demo update
This commit is contained in:
@@ -1,11 +1,5 @@
|
|||||||
------------ Tyra's v2.0 roadmap to publish on GitHub ------------
|
------------ Tyra's v2.0 roadmap to publish on GitHub ------------
|
||||||
|
|
||||||
- [Demo] Red screen on hit
|
|
||||||
- [HUD] Count of killed zombies
|
|
||||||
- [HUD] Crosshair
|
|
||||||
- [HUD] 2D Health bar
|
|
||||||
- [Demo] Game over screen
|
|
||||||
- [Demo] Game fadein with audio information about island
|
|
||||||
- [General] USB test
|
- [General] USB test
|
||||||
- [General] CI in Github via docker image
|
- [General] CI in Github via docker image
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,6 @@
|
|||||||
|
|
||||||
namespace Demo {
|
namespace Demo {
|
||||||
|
|
||||||
enum GlobalStateType { STATE_INTRO, STATE_GAME, STATE_EXIT };
|
enum GlobalStateType { STATE_INTRO, STATE_LOADING, STATE_GAME, STATE_EXIT };
|
||||||
|
|
||||||
} // namespace Demo
|
} // namespace Demo
|
||||||
|
|||||||
@@ -49,10 +49,12 @@ class Enemy {
|
|||||||
void animationCallback(const AnimationSequenceCallback& callback);
|
void animationCallback(const AnimationSequenceCallback& callback);
|
||||||
void fight();
|
void fight();
|
||||||
void handlePlayerShoot(const PlayerShootAction& shootAction);
|
void handlePlayerShoot(const PlayerShootAction& shootAction);
|
||||||
|
void setMeshToSpawn();
|
||||||
|
|
||||||
bool isWalking = true;
|
bool isWalking = true;
|
||||||
bool isFighting = false;
|
bool isFighting = false;
|
||||||
Vec4 spawnPoint;
|
Vec4 terrainLeftUp;
|
||||||
|
Vec4 terrainRightDown;
|
||||||
|
|
||||||
Audio* audio;
|
Audio* audio;
|
||||||
EnemyInfo info;
|
EnemyInfo info;
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ struct EnemyInfo {
|
|||||||
DynamicMesh* motherMesh;
|
DynamicMesh* motherMesh;
|
||||||
Texture* bodyTexture;
|
Texture* bodyTexture;
|
||||||
Texture* clothTexture;
|
Texture* clothTexture;
|
||||||
Vec4 spawnPoint;
|
Vec4 terrainLeftUp;
|
||||||
|
Vec4 terrainRightDown;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Demo
|
} // namespace Demo
|
||||||
|
|||||||
@@ -17,8 +17,11 @@
|
|||||||
#include "./terrain/terrain.hpp"
|
#include "./terrain/terrain.hpp"
|
||||||
#include "./skybox/skybox.hpp"
|
#include "./skybox/skybox.hpp"
|
||||||
#include "./ship/ship.hpp"
|
#include "./ship/ship.hpp"
|
||||||
|
#include "./hud/hud.hpp"
|
||||||
#include "./enemy/enemy_manager.hpp"
|
#include "./enemy/enemy_manager.hpp"
|
||||||
|
|
||||||
|
using std::unique_ptr;
|
||||||
|
|
||||||
namespace Demo {
|
namespace Demo {
|
||||||
|
|
||||||
class GameState : public State<GlobalStateType> {
|
class GameState : public State<GlobalStateType> {
|
||||||
@@ -44,11 +47,12 @@ class GameState : public State<GlobalStateType> {
|
|||||||
u8 fpsChecker;
|
u8 fpsChecker;
|
||||||
|
|
||||||
GameRenderer renderer;
|
GameRenderer renderer;
|
||||||
Player* player;
|
unique_ptr<Player> player;
|
||||||
EnemyManager* enemyManager;
|
unique_ptr<EnemyManager> enemyManager;
|
||||||
Terrain* terrain;
|
unique_ptr<Terrain> terrain;
|
||||||
Skybox* skybox;
|
unique_ptr<Skybox> skybox;
|
||||||
Ship* ship;
|
unique_ptr<Ship> ship;
|
||||||
|
unique_ptr<Hud> hud;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Demo
|
} // namespace Demo
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <tyra>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
using std::unique_ptr;
|
||||||
|
using Tyra::Sprite;
|
||||||
|
using Tyra::Texture;
|
||||||
|
using Tyra::TextureRepository;
|
||||||
|
|
||||||
|
namespace Demo {
|
||||||
|
|
||||||
|
class Hud {
|
||||||
|
public:
|
||||||
|
Hud(TextureRepository* repo);
|
||||||
|
~Hud();
|
||||||
|
|
||||||
|
TextureRepository* repo;
|
||||||
|
Texture* hpTexture;
|
||||||
|
unique_ptr<Sprite> hpSprite;
|
||||||
|
Texture* crosshairTexture;
|
||||||
|
unique_ptr<Sprite> crosshairSprite;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Demo
|
||||||
@@ -14,8 +14,10 @@
|
|||||||
#include "./renderer_static_pair.hpp"
|
#include "./renderer_static_pair.hpp"
|
||||||
#include "./renderer_dynamic_pair.hpp"
|
#include "./renderer_dynamic_pair.hpp"
|
||||||
|
|
||||||
|
using Tyra::CoreBBox;
|
||||||
using Tyra::DynamicPipeline;
|
using Tyra::DynamicPipeline;
|
||||||
using Tyra::Renderer;
|
using Tyra::Renderer;
|
||||||
|
using Tyra::Sprite;
|
||||||
using Tyra::StaticPipeline;
|
using Tyra::StaticPipeline;
|
||||||
|
|
||||||
namespace Demo {
|
namespace Demo {
|
||||||
@@ -29,10 +31,10 @@ class GameRenderer {
|
|||||||
void add(std::vector<RendererDynamicPair*> dynamicPairs);
|
void add(std::vector<RendererDynamicPair*> dynamicPairs);
|
||||||
void add(RendererStaticPair* staticPair);
|
void add(RendererStaticPair* staticPair);
|
||||||
void add(RendererDynamicPair* dynamicPair);
|
void add(RendererDynamicPair* dynamicPair);
|
||||||
|
void add(Sprite* sprite);
|
||||||
|
void add(const CoreBBox& bbox);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void renderSkybox(const RendererStaticPair& pair);
|
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -43,6 +45,8 @@ class GameRenderer {
|
|||||||
|
|
||||||
std::vector<RendererStaticPair*> staticPairs;
|
std::vector<RendererStaticPair*> staticPairs;
|
||||||
std::vector<RendererDynamicPair*> dynamicPairs;
|
std::vector<RendererDynamicPair*> dynamicPairs;
|
||||||
|
std::vector<Sprite*> sprites;
|
||||||
|
std::vector<CoreBBox> bboxes;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Demo
|
} // namespace Demo
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "state/state.hpp"
|
||||||
|
#include "state/global_state_type.hpp"
|
||||||
|
#include "state/state_manager.hpp"
|
||||||
|
|
||||||
|
namespace Demo {
|
||||||
|
|
||||||
|
class LoadingState : public State<GlobalStateType> {
|
||||||
|
public:
|
||||||
|
LoadingState(Engine* t_engine);
|
||||||
|
~LoadingState();
|
||||||
|
|
||||||
|
const GlobalStateType& getState() const { return state; }
|
||||||
|
|
||||||
|
const bool& wantFinish() const { return _wantFinish; };
|
||||||
|
|
||||||
|
void onStart();
|
||||||
|
|
||||||
|
void update();
|
||||||
|
|
||||||
|
/** @return Next game state */
|
||||||
|
GlobalStateType onFinish();
|
||||||
|
|
||||||
|
private:
|
||||||
|
GlobalStateType state;
|
||||||
|
bool _wantFinish;
|
||||||
|
bool initialized;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Demo
|
||||||
@@ -10,16 +10,18 @@
|
|||||||
|
|
||||||
#include "demo_game.hpp"
|
#include "demo_game.hpp"
|
||||||
#include "states/intro/intro_state.hpp"
|
#include "states/intro/intro_state.hpp"
|
||||||
|
#include "states/loading/loading_state.hpp"
|
||||||
#include "states/game/game_state.hpp"
|
#include "states/game/game_state.hpp"
|
||||||
|
|
||||||
namespace Demo {
|
namespace Demo {
|
||||||
|
|
||||||
DemoGame::DemoGame(Engine* t_engine)
|
DemoGame::DemoGame(Engine* t_engine)
|
||||||
: engine(t_engine), stateManager(STATE_GAME, STATE_EXIT) {}
|
: engine(t_engine), stateManager(STATE_INTRO, STATE_EXIT) {}
|
||||||
DemoGame::~DemoGame() {}
|
DemoGame::~DemoGame() {}
|
||||||
|
|
||||||
void DemoGame::init() {
|
void DemoGame::init() {
|
||||||
stateManager.add(new IntroState(engine));
|
stateManager.add(new IntroState(engine));
|
||||||
|
stateManager.add(new LoadingState(engine));
|
||||||
stateManager.add(new GameState(engine));
|
stateManager.add(new GameState(engine));
|
||||||
}
|
}
|
||||||
void DemoGame::loop() {
|
void DemoGame::loop() {
|
||||||
|
|||||||
@@ -40,8 +40,10 @@ Enemy::Enemy(Engine* engine, const EnemyInfo& t_info) {
|
|||||||
walkSequence = {0, 1, 2};
|
walkSequence = {0, 1, 2};
|
||||||
fightSequence = {3, 4, 5};
|
fightSequence = {3, 4, 5};
|
||||||
|
|
||||||
spawnPoint = info.spawnPoint;
|
terrainLeftUp = info.terrainLeftUp;
|
||||||
mesh->setPosition(info.spawnPoint);
|
terrainRightDown = info.terrainRightDown;
|
||||||
|
|
||||||
|
setMeshToSpawn();
|
||||||
|
|
||||||
mesh->animation.setSequence(walkSequence);
|
mesh->animation.setSequence(walkSequence);
|
||||||
mesh->animation.loop = true;
|
mesh->animation.loop = true;
|
||||||
@@ -50,8 +52,7 @@ Enemy::Enemy(Engine* engine, const EnemyInfo& t_info) {
|
|||||||
mesh->translation.translateY(-5.0F);
|
mesh->translation.translateY(-5.0F);
|
||||||
|
|
||||||
audio = &engine->audio;
|
audio = &engine->audio;
|
||||||
audio->adpcm.setVolume(5, info.adpcmChannel);
|
audio->adpcm.setVolume(30, info.adpcmChannel);
|
||||||
// audio->adpcm.setVolume(30, info.adpcmChannel); // TEMP
|
|
||||||
|
|
||||||
allocateOptions();
|
allocateOptions();
|
||||||
|
|
||||||
@@ -64,6 +65,14 @@ Enemy::~Enemy() {
|
|||||||
delete pair;
|
delete pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Enemy::setMeshToSpawn() {
|
||||||
|
auto spawnPoint =
|
||||||
|
Vec4(Math::randomf(terrainLeftUp.x, terrainRightDown.x), 0.0F,
|
||||||
|
Math::randomf(terrainLeftUp.z, terrainRightDown.z), 1.0F);
|
||||||
|
|
||||||
|
mesh->setPosition(spawnPoint);
|
||||||
|
}
|
||||||
|
|
||||||
void Enemy::update(const Heightmap& heightmap, const Vec4& playerPosition,
|
void Enemy::update(const Heightmap& heightmap, const Vec4& playerPosition,
|
||||||
const PlayerShootAction& shootAction) {
|
const PlayerShootAction& shootAction) {
|
||||||
auto* enemyPosition = mesh->getPosition();
|
auto* enemyPosition = mesh->getPosition();
|
||||||
@@ -73,7 +82,7 @@ void Enemy::update(const Heightmap& heightmap, const Vec4& playerPosition,
|
|||||||
auto diff = *enemyPosition - playerPosition;
|
auto diff = *enemyPosition - playerPosition;
|
||||||
auto ang = Math::atan2(diff.x, diff.z);
|
auto ang = Math::atan2(diff.x, diff.z);
|
||||||
|
|
||||||
if (diff.length() > 110.0F) {
|
if (diff.length() > 150.0F) {
|
||||||
walk(heightmap, diff);
|
walk(heightmap, diff);
|
||||||
} else {
|
} else {
|
||||||
fight();
|
fight();
|
||||||
@@ -97,14 +106,10 @@ void Enemy::handlePlayerShoot(const PlayerShootAction& shootAction) {
|
|||||||
auto bbox =
|
auto bbox =
|
||||||
mesh->getCurrentBoundingBox().getTransformed(mesh->getModelMatrix());
|
mesh->getCurrentBoundingBox().getTransformed(mesh->getModelMatrix());
|
||||||
|
|
||||||
float length = -1.0F;
|
auto isOnEnemy = ray.intersectBox(bbox.min(), bbox.max());
|
||||||
auto isOnEnemy = ray.intersectBox(bbox.min(), bbox.max(), &length);
|
|
||||||
|
|
||||||
if (isOnEnemy) {
|
if (isOnEnemy) {
|
||||||
mesh->setPosition(spawnPoint);
|
setMeshToSpawn();
|
||||||
TYRA_LOG("Enemy hit!");
|
|
||||||
} else {
|
|
||||||
if (length != -1.0F) TYRA_LOG("Distance: ", length);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +149,10 @@ void Enemy::animationCallback(const AnimationSequenceCallback& callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Enemy::allocateOptions() { options = new DynPipOptions(); }
|
void Enemy::allocateOptions() {
|
||||||
|
options = new DynPipOptions();
|
||||||
|
options->frustumCulling =
|
||||||
|
Tyra::PipelineFrustumCulling::PipelineFrustumCulling_None;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Demo
|
} // namespace Demo
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ EnemyManager::EnemyManager(Engine* engine, const Heightmap& heightmap) {
|
|||||||
auto* sample = engine->audio.adpcm.load(
|
auto* sample = engine->audio.adpcm.load(
|
||||||
FileUtils::fromCwd("game/models/zombie/punch.adpcm"));
|
FileUtils::fromCwd("game/models/zombie/punch.adpcm"));
|
||||||
|
|
||||||
const int enemyCount = 5;
|
const int enemyCount = 10;
|
||||||
for (int i = 0; i < enemyCount; i++) {
|
for (int i = 0; i < enemyCount; i++) {
|
||||||
EnemyInfo info;
|
EnemyInfo info;
|
||||||
info.adpcmChannel = 9 + i;
|
info.adpcmChannel = 9 + i;
|
||||||
@@ -51,9 +51,8 @@ EnemyManager::EnemyManager(Engine* engine, const Heightmap& heightmap) {
|
|||||||
info.motherMesh = motherMesh;
|
info.motherMesh = motherMesh;
|
||||||
info.clothTexture = clothTexture;
|
info.clothTexture = clothTexture;
|
||||||
info.bodyTexture = bodyTexture;
|
info.bodyTexture = bodyTexture;
|
||||||
info.spawnPoint =
|
info.terrainLeftUp = heightmap.leftUp;
|
||||||
Vec4(Math::randomf(heightmap.leftUp.x, heightmap.rightDown.x), 0.0F,
|
info.terrainRightDown = heightmap.rightDown;
|
||||||
Math::randomf(heightmap.leftUp.z, heightmap.rightDown.z), 1.0F);
|
|
||||||
enemies.push_back(new Enemy(engine, info));
|
enemies.push_back(new Enemy(engine, info));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "states/game/game_state.hpp"
|
#include "states/game/game_state.hpp"
|
||||||
|
|
||||||
|
using std::make_unique;
|
||||||
using Tyra::FileUtils;
|
using Tyra::FileUtils;
|
||||||
|
|
||||||
namespace Demo {
|
namespace Demo {
|
||||||
@@ -28,17 +29,20 @@ void GameState::onStart() {
|
|||||||
TYRA_LOG("Game. RAM: ", engine->info.getAvailableRAM(), "MB");
|
TYRA_LOG("Game. RAM: ", engine->info.getAvailableRAM(), "MB");
|
||||||
|
|
||||||
engine->audio.song.stop();
|
engine->audio.song.stop();
|
||||||
engine->audio.song.load(FileUtils::fromCwd("game/ambiance.wav"));
|
|
||||||
engine->audio.song.inLoop = true;
|
engine->audio.song.inLoop = true;
|
||||||
engine->audio.song.setVolume(100);
|
engine->audio.song.load(FileUtils::fromCwd("game/game-audio.wav"));
|
||||||
|
engine->audio.song.setVolume(0);
|
||||||
engine->audio.song.play();
|
engine->audio.song.play();
|
||||||
|
|
||||||
auto* repository = &engine->renderer.core.texture.repository;
|
auto* repository = &engine->renderer.core.texture.repository;
|
||||||
player = new Player(engine);
|
player = make_unique<Player>(engine);
|
||||||
terrain = new Terrain(repository);
|
terrain = make_unique<Terrain>(repository);
|
||||||
enemyManager = new EnemyManager(engine, terrain->heightmap);
|
enemyManager = make_unique<EnemyManager>(engine, terrain->heightmap);
|
||||||
ship = new Ship(repository);
|
ship = make_unique<Ship>(repository);
|
||||||
skybox = new Skybox(repository);
|
skybox = make_unique<Skybox>(repository);
|
||||||
|
hud = make_unique<Hud>(repository);
|
||||||
|
|
||||||
|
engine->audio.song.setVolume(85);
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
@@ -46,27 +50,12 @@ void GameState::onStart() {
|
|||||||
GlobalStateType GameState::onFinish() {
|
GlobalStateType GameState::onFinish() {
|
||||||
if (!initialized) return STATE_EXIT;
|
if (!initialized) return STATE_EXIT;
|
||||||
|
|
||||||
delete player;
|
|
||||||
delete enemyManager;
|
|
||||||
delete terrain;
|
|
||||||
delete ship;
|
|
||||||
delete skybox;
|
|
||||||
initialized = false;
|
initialized = false;
|
||||||
|
|
||||||
return STATE_EXIT;
|
return STATE_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameState::update() {
|
void GameState::update() {
|
||||||
// Begin frame
|
|
||||||
player->update(terrain->heightmap);
|
|
||||||
auto cameraInfo = player->getCameraInfo();
|
|
||||||
engine->renderer.beginFrame(cameraInfo);
|
|
||||||
|
|
||||||
// Clear screen and render skybox
|
|
||||||
renderer.clear();
|
|
||||||
skybox->update(player->getPosition());
|
|
||||||
renderer.renderSkybox(*skybox->pair); // First, because of ALLPASS
|
|
||||||
|
|
||||||
// Check fps
|
// Check fps
|
||||||
if (fpsChecker++ > 50) {
|
if (fpsChecker++ > 50) {
|
||||||
TYRA_LOG("FPS: ", engine->info.getFps(),
|
TYRA_LOG("FPS: ", engine->info.getFps(),
|
||||||
@@ -75,25 +64,29 @@ void GameState::update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Game logic
|
// Game logic
|
||||||
|
player->update(terrain->heightmap);
|
||||||
|
skybox->update(player->getPosition());
|
||||||
auto shootAction = player->getShootAction();
|
auto shootAction = player->getShootAction();
|
||||||
enemyManager->update(terrain->heightmap, player->getPosition(), shootAction);
|
enemyManager->update(terrain->heightmap, player->getPosition(), shootAction);
|
||||||
|
auto* firstEnemyMesh = enemyManager->getPairs().front()->mesh;
|
||||||
|
|
||||||
// Render other stuff
|
// Render
|
||||||
|
engine->renderer.beginFrame(player->getCameraInfo());
|
||||||
|
{
|
||||||
|
renderer.clear();
|
||||||
|
{
|
||||||
|
renderer.add(skybox->pair); // First, because of ALLPASS
|
||||||
renderer.add(ship->pair);
|
renderer.add(ship->pair);
|
||||||
renderer.add(player->pair);
|
renderer.add(player->pair);
|
||||||
renderer.add(enemyManager->getPairs());
|
renderer.add(enemyManager->getPairs());
|
||||||
renderer.add(terrain->pair);
|
renderer.add(terrain->pair);
|
||||||
|
renderer.add(firstEnemyMesh->getCurrentBoundingBox().getTransformed(
|
||||||
|
firstEnemyMesh->getModelMatrix()));
|
||||||
|
renderer.add(hud->crosshairSprite.get());
|
||||||
|
renderer.add(hud->hpSprite.get());
|
||||||
|
}
|
||||||
renderer.render();
|
renderer.render();
|
||||||
|
}
|
||||||
// Debug
|
|
||||||
// auto& utility = engine->renderer.renderer3D.utility;
|
|
||||||
// utility.drawBox(*player->getCameraInfo().looksAt, 0.3F);
|
|
||||||
|
|
||||||
// auto* firstEnemy = enemyManager->getPairs().front()->mesh;
|
|
||||||
// utility.drawBBox(firstEnemy->getCurrentBoundingBox().getTransformed(
|
|
||||||
// firstEnemy->getModelMatrix()));
|
|
||||||
|
|
||||||
// End frame
|
|
||||||
engine->renderer.endFrame();
|
engine->renderer.endFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "states/game/hud/hud.hpp"
|
||||||
|
|
||||||
|
using Tyra::FileUtils;
|
||||||
|
|
||||||
|
namespace Demo {
|
||||||
|
|
||||||
|
Hud::Hud(TextureRepository* t_repo) {
|
||||||
|
repo = t_repo;
|
||||||
|
|
||||||
|
hpSprite = std::make_unique<Sprite>();
|
||||||
|
hpSprite->mode = Tyra::MODE_STRETCH;
|
||||||
|
hpSprite->size.set(128.0F, 64.0F);
|
||||||
|
hpSprite->position.set(0, 448.0F - 64.0F - 5.0F);
|
||||||
|
|
||||||
|
hpTexture = repo->add(FileUtils::fromCwd("game/health_bar.png"));
|
||||||
|
hpTexture->addLink(hpSprite->id);
|
||||||
|
|
||||||
|
crosshairSprite = std::make_unique<Sprite>();
|
||||||
|
crosshairSprite->mode = Tyra::MODE_STRETCH;
|
||||||
|
crosshairSprite->size.set(16.0F, 16.0F);
|
||||||
|
crosshairSprite->position.set(512.0F / 2.0F - 16.0F / 2,
|
||||||
|
448.0F / 2.0F - 16.0F / 2);
|
||||||
|
|
||||||
|
crosshairTexture = repo->add(FileUtils::fromCwd("game/crosshair.png"));
|
||||||
|
crosshairTexture->addLink(crosshairSprite->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Hud::~Hud() {
|
||||||
|
repo->free(crosshairTexture->id);
|
||||||
|
repo->free(hpTexture->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Demo
|
||||||
@@ -18,7 +18,7 @@ Player::Player(Engine* engine)
|
|||||||
pad = &engine->pad;
|
pad = &engine->pad;
|
||||||
position = Vec4(3.0F, 50.0F, 0.0F);
|
position = Vec4(3.0F, 50.0F, 0.0F);
|
||||||
camera.lookAt = Vec4(0.0F, 0.0F, -30.0F);
|
camera.lookAt = Vec4(0.0F, 0.0F, -30.0F);
|
||||||
speed = 5.0F;
|
speed = 6.0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player::~Player() { delete pair; }
|
Player::~Player() { delete pair; }
|
||||||
@@ -36,7 +36,8 @@ PlayerShootAction Player::getShootAction() const {
|
|||||||
action.isShooting = weapon.isShooting;
|
action.isShooting = weapon.isShooting;
|
||||||
|
|
||||||
if (action.isShooting) {
|
if (action.isShooting) {
|
||||||
action.ray = Ray(camera.position, camera.lookAt.getNormalized());
|
action.ray =
|
||||||
|
Ray(camera.position, (camera.lookAt - camera.position).getNormalized());
|
||||||
}
|
}
|
||||||
|
|
||||||
return action;
|
return action;
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ void GameRenderer::add(std::vector<RendererDynamicPair*> t_dynamicPairs) {
|
|||||||
t_dynamicPairs.end());
|
t_dynamicPairs.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameRenderer::add(Sprite* sprite) { sprites.push_back(sprite); }
|
||||||
|
|
||||||
|
void GameRenderer::add(const CoreBBox& bbox) { bboxes.push_back(bbox); }
|
||||||
|
|
||||||
void GameRenderer::add(RendererStaticPair* staticPair) {
|
void GameRenderer::add(RendererStaticPair* staticPair) {
|
||||||
staticPairs.push_back(staticPair);
|
staticPairs.push_back(staticPair);
|
||||||
}
|
}
|
||||||
@@ -44,14 +48,12 @@ void GameRenderer::add(RendererDynamicPair* dynamicPair) {
|
|||||||
void GameRenderer::clear() {
|
void GameRenderer::clear() {
|
||||||
staticPairs.clear();
|
staticPairs.clear();
|
||||||
dynamicPairs.clear();
|
dynamicPairs.clear();
|
||||||
}
|
sprites.clear();
|
||||||
|
bboxes.clear();
|
||||||
void GameRenderer::renderSkybox(const RendererStaticPair& pair) {
|
|
||||||
renderer->renderer3D.usePipeline(&stpip);
|
|
||||||
stpip.render(pair.mesh, pair.options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameRenderer::render() {
|
void GameRenderer::render() {
|
||||||
|
// Render static stuff
|
||||||
if (staticPairs.size()) {
|
if (staticPairs.size()) {
|
||||||
renderer->renderer3D.usePipeline(&stpip);
|
renderer->renderer3D.usePipeline(&stpip);
|
||||||
|
|
||||||
@@ -60,8 +62,9 @@ void GameRenderer::render() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Threading::switchThread();
|
Threading::switchThread(); // give some time for audio thread
|
||||||
|
|
||||||
|
// Render animated stuff
|
||||||
if (dynamicPairs.size()) {
|
if (dynamicPairs.size()) {
|
||||||
renderer->renderer3D.usePipeline(&dypip);
|
renderer->renderer3D.usePipeline(&dypip);
|
||||||
|
|
||||||
@@ -69,6 +72,18 @@ void GameRenderer::render() {
|
|||||||
dypip.render(pair->mesh, pair->options);
|
dypip.render(pair->mesh, pair->options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Threading::switchThread();
|
||||||
|
|
||||||
|
// Render debug stuff after stapip/dynpip, otherwise it will not be visible
|
||||||
|
for (auto& bbox : bboxes) {
|
||||||
|
renderer->renderer3D.utility.drawBBox(bbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render 2D
|
||||||
|
for (auto& sprite : sprites) {
|
||||||
|
renderer->renderer2D.render(sprite);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Demo
|
} // namespace Demo
|
||||||
|
|||||||
@@ -43,12 +43,12 @@ void IntroState::onStart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GlobalStateType IntroState::onFinish() {
|
GlobalStateType IntroState::onFinish() {
|
||||||
if (!initialized) return STATE_GAME;
|
if (!initialized) return STATE_LOADING;
|
||||||
|
|
||||||
stateManager.freeAll();
|
stateManager.freeAll();
|
||||||
|
|
||||||
initialized = false;
|
initialized = false;
|
||||||
return STATE_GAME;
|
return STATE_LOADING;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntroState::update() {
|
void IntroState::update() {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ void IntroPressKeyState::onStart() {
|
|||||||
for (u8 j = 0; j < mapCols; j++) {
|
for (u8 j = 0; j < mapCols; j++) {
|
||||||
mapSprites[i][j] = new Sprite;
|
mapSprites[i][j] = new Sprite;
|
||||||
mapSprites[i][j]->color.a = 0.0F;
|
mapSprites[i][j]->color.a = 0.0F;
|
||||||
mapSprites[i][j]->setMode(SpriteMode::MODE_STRETCH);
|
mapSprites[i][j]->mode = SpriteMode::MODE_STRETCH;
|
||||||
mapSprites[i][j]->size.set(textureWidthHeight, textureWidthHeight);
|
mapSprites[i][j]->size.set(textureWidthHeight, textureWidthHeight);
|
||||||
mapSprites[i][j]->position.set(i * textureWidthHeight,
|
mapSprites[i][j]->position.set(i * textureWidthHeight,
|
||||||
j * textureWidthHeight);
|
j * textureWidthHeight);
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
# _____ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2022, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licensed under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <tyra>
|
||||||
|
#include "states/loading/loading_state.hpp"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
using std::make_unique;
|
||||||
|
using std::unique_ptr;
|
||||||
|
using Tyra::FileUtils;
|
||||||
|
using Tyra::Sprite;
|
||||||
|
|
||||||
|
namespace Demo {
|
||||||
|
|
||||||
|
LoadingState::LoadingState(Engine* t_engine) : State(t_engine) {
|
||||||
|
state = STATE_LOADING;
|
||||||
|
_wantFinish = false;
|
||||||
|
initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadingState::~LoadingState() {}
|
||||||
|
|
||||||
|
void LoadingState::onStart() {
|
||||||
|
TYRA_LOG("Loading. RAM: ", engine->info.getAvailableRAM(), "MB");
|
||||||
|
|
||||||
|
auto* repo = &engine->renderer.core.texture.repository;
|
||||||
|
|
||||||
|
auto fillerTexture = repo->add(FileUtils::fromCwd("loading/filler.png"));
|
||||||
|
auto loadingTexture = repo->add(FileUtils::fromCwd("loading/loading.png"));
|
||||||
|
|
||||||
|
auto fillerSprite = make_unique<Sprite>();
|
||||||
|
auto loadingSprite = make_unique<Sprite>();
|
||||||
|
|
||||||
|
fillerSprite->position.set(0.0F, 0.0F);
|
||||||
|
fillerSprite->size.set(600.0F, 600.0F);
|
||||||
|
fillerSprite->mode = Tyra::MODE_STRETCH;
|
||||||
|
|
||||||
|
loadingSprite->size.set(128.0F, 64.0F);
|
||||||
|
loadingSprite->mode = Tyra::MODE_STRETCH;
|
||||||
|
loadingSprite->position.set(5.0F, 448.0F - 64.0F - 5.0F);
|
||||||
|
|
||||||
|
fillerTexture->addLink(fillerSprite->id);
|
||||||
|
loadingTexture->addLink(loadingSprite->id);
|
||||||
|
|
||||||
|
engine->renderer.beginFrame();
|
||||||
|
engine->renderer.renderer2D.render(fillerSprite.get());
|
||||||
|
engine->renderer.renderer2D.render(loadingSprite.get());
|
||||||
|
engine->renderer.endFrame();
|
||||||
|
|
||||||
|
repo->free(fillerTexture->id);
|
||||||
|
repo->free(loadingTexture->id);
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalStateType LoadingState::onFinish() {
|
||||||
|
if (!initialized) return STATE_GAME;
|
||||||
|
|
||||||
|
initialized = false;
|
||||||
|
return STATE_GAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadingState::update() { _wantFinish = true; }
|
||||||
|
|
||||||
|
} // namespace Demo
|
||||||
@@ -27,42 +27,11 @@ class Sprite {
|
|||||||
Vec2 position, size;
|
Vec2 position, size;
|
||||||
float scale;
|
float scale;
|
||||||
Color color;
|
Color color;
|
||||||
|
SpriteMode mode;
|
||||||
// ----
|
bool flipHorizontal, flipVertical;
|
||||||
// Getters
|
|
||||||
// ----
|
|
||||||
|
|
||||||
/** Get sprite drawing mode. */
|
|
||||||
inline const SpriteMode& getMode() const { return mode; };
|
|
||||||
|
|
||||||
// ----
|
|
||||||
// Setters
|
|
||||||
// ----
|
|
||||||
|
|
||||||
/** Set sprite drawing mode. */
|
|
||||||
void setMode(const SpriteMode& t_val) { mode = t_val; }
|
|
||||||
|
|
||||||
// ----
|
|
||||||
// Other
|
|
||||||
// ----
|
|
||||||
|
|
||||||
/** Flip texture horizontally. */
|
|
||||||
inline void flipHorizontally(const u8& t_set) { _flipH = t_set; };
|
|
||||||
|
|
||||||
/** Flip texture vertically. */
|
|
||||||
inline void flipVertically(const u8& t_set) { _flipV = t_set; };
|
|
||||||
|
|
||||||
/** Check if texture is vertically flipped. */
|
|
||||||
inline const u8& isFlippedVertically() const { return _flipV; };
|
|
||||||
|
|
||||||
/** Check if texture is horizontally flipped. */
|
|
||||||
inline const u8& isFlippedHorizontally() const { return _flipH; };
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SpriteMode mode;
|
|
||||||
u8 _isSizeSet, _flipH, _flipV;
|
|
||||||
void setDefaultColor();
|
void setDefaultColor();
|
||||||
void setDefaultLODAndClut();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Tyra
|
} // namespace Tyra
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ void RendererCore2D::render(Sprite* sprite,
|
|||||||
auto* rect = rects[context];
|
auto* rect = rects[context];
|
||||||
float sizeX, sizeY;
|
float sizeX, sizeY;
|
||||||
|
|
||||||
if (sprite->getMode() == MODE_REPEAT) {
|
if (sprite->mode == MODE_REPEAT) {
|
||||||
sizeX = sprite->size.x;
|
sizeX = sprite->size.x;
|
||||||
sizeY = sprite->size.y;
|
sizeY = sprite->size.y;
|
||||||
} else {
|
} else {
|
||||||
@@ -84,10 +84,10 @@ void RendererCore2D::render(Sprite* sprite,
|
|||||||
else if (sizeY > sizeX)
|
else if (sizeY > sizeX)
|
||||||
texS = texMax / (sizeY / sizeX);
|
texS = texMax / (sizeY / sizeX);
|
||||||
|
|
||||||
rect->t0.s = sprite->isFlippedHorizontally() ? texS : 0.0F;
|
rect->t0.s = sprite->flipHorizontal ? texS : 0.0F;
|
||||||
rect->t0.t = sprite->isFlippedVertically() ? texT : 0.0F;
|
rect->t0.t = sprite->flipVertical ? texT : 0.0F;
|
||||||
rect->t1.s = sprite->isFlippedHorizontally() ? 0.0F : texS;
|
rect->t1.s = sprite->flipHorizontal ? 0.0F : texS;
|
||||||
rect->t1.t = sprite->isFlippedVertically() ? 0.0F : texT;
|
rect->t1.t = sprite->flipVertical ? 0.0F : texT;
|
||||||
|
|
||||||
rect->color.r = sprite->color.r;
|
rect->color.r = sprite->color.r;
|
||||||
rect->color.g = sprite->color.g;
|
rect->color.g = sprite->color.g;
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ namespace Tyra {
|
|||||||
|
|
||||||
Sprite::Sprite() {
|
Sprite::Sprite() {
|
||||||
id = rand() % 1000000;
|
id = rand() % 1000000;
|
||||||
_flipH = false;
|
flipHorizontal = false;
|
||||||
_flipV = false;
|
flipVertical = false;
|
||||||
size.set(32.0F, 32.0F);
|
size.set(32.0F, 32.0F);
|
||||||
position.set(100.0F, 100.0F);
|
position.set(100.0F, 100.0F);
|
||||||
scale = 1.0F;
|
scale = 1.0F;
|
||||||
|
|||||||
Reference in New Issue
Block a user