added ui, enemy, sounds, fixed anims
This commit is contained in:
@@ -6,8 +6,10 @@ EE_OBJS = \
|
|||||||
managers/light_manager.o \
|
managers/light_manager.o \
|
||||||
managers/floor_manager.o \
|
managers/floor_manager.o \
|
||||||
camera.o \
|
camera.o \
|
||||||
|
objects/enemy.o \
|
||||||
objects/floor.o \
|
objects/floor.o \
|
||||||
objects/player.o \
|
objects/player.o \
|
||||||
|
ui.o \
|
||||||
utils.o \
|
utils.o \
|
||||||
floors.o \
|
floors.o \
|
||||||
main.o
|
main.o
|
||||||
|
|||||||
@@ -14,15 +14,21 @@
|
|||||||
// Constructors/Destructors
|
// Constructors/Destructors
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
const u8 FLOORS_COUNT = 144; // Temp change it also in floor_manager.hpp
|
const u16 FLOORS_COUNT = 144; // Temp change it also in floor_manager.hpp
|
||||||
|
|
||||||
Floors::Floors(Engine *t_engine)
|
Floors::Floors(Engine *t_engine)
|
||||||
: engine(t_engine), floorManager(FLOORS_COUNT), camera(&t_engine->screen)
|
: engine(t_engine), floorManager(FLOORS_COUNT),
|
||||||
|
player(&t_engine->audio), camera(&t_engine->screen)
|
||||||
{
|
{
|
||||||
audioTicks = 0;
|
audioTicks = 0;
|
||||||
|
skip1Beat = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Floors::~Floors() {}
|
Floors::~Floors()
|
||||||
|
{
|
||||||
|
delete enemy;
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
// ----
|
// ----
|
||||||
// Methods
|
// Methods
|
||||||
@@ -32,10 +38,13 @@ void Floors::onInit()
|
|||||||
{
|
{
|
||||||
engine->renderer->setCameraDefinitions(&camera.worldView, &camera.unitCirclePosition, camera.planes);
|
engine->renderer->setCameraDefinitions(&camera.worldView, &camera.unitCirclePosition, camera.planes);
|
||||||
engine->audio.addSongListener(this);
|
engine->audio.addSongListener(this);
|
||||||
engine->audio.loadSong("NF-CHILL.WAV");
|
engine->audio.loadSong("nob-else.wav");
|
||||||
engine->audio.setSongVolume(100);
|
|
||||||
engine->audio.playSong();
|
engine->audio.playSong();
|
||||||
texRepo = engine->renderer->getTextureRepository();
|
texRepo = engine->renderer->getTextureRepository();
|
||||||
|
enemy = new Enemy(texRepo);
|
||||||
|
ui = new Ui(texRepo);
|
||||||
|
engine->audio.setSongVolume(80);
|
||||||
|
|
||||||
texRepo->addByMesh("warrior/", player.mesh, BMP);
|
texRepo->addByMesh("warrior/", player.mesh, BMP);
|
||||||
texRepo->addByMesh("floor/", floorManager.floors[0].mesh, BMP);
|
texRepo->addByMesh("floor/", floorManager.floors[0].mesh, BMP);
|
||||||
for (u32 i = 1; i < floorManager.floorAmount; i++)
|
for (u32 i = 1; i < floorManager.floorAmount; i++)
|
||||||
@@ -45,23 +54,26 @@ void Floors::onInit()
|
|||||||
|
|
||||||
void Floors::onUpdate()
|
void Floors::onUpdate()
|
||||||
{
|
{
|
||||||
if (engine->pad.isCrossClicked)
|
ui->update(player);
|
||||||
printf("FPS:%f\n", engine->fps);
|
|
||||||
lightManager.update();
|
lightManager.update();
|
||||||
camera.update(engine->pad, player.mesh);
|
camera.update(engine->pad, player.mesh);
|
||||||
floorManager.update(player);
|
floorManager.update(player);
|
||||||
player.update(engine->pad, camera, floorManager);
|
player.update(engine->pad, camera, floorManager, *enemy);
|
||||||
engine->renderer->draw(player.mesh);
|
engine->renderer->draw(player.mesh);
|
||||||
for (u8 i = 0; i < FLOORS_COUNT; i++)
|
engine->renderer->draw(enemy->getMeshes(), enemy->getMeshesCount());
|
||||||
|
for (u16 i = 0; i < FLOORS_COUNT; i++)
|
||||||
engine->renderer->drawByPath3(floorManager.floors[i].mesh, lightManager.bulbs, lightManager.bulbsCount);
|
engine->renderer->drawByPath3(floorManager.floors[i].mesh, lightManager.bulbs, lightManager.bulbsCount);
|
||||||
|
ui->render(engine->renderer); // 2D rendering ist LAST step, because layers gonna play there.
|
||||||
}
|
}
|
||||||
|
|
||||||
void Floors::onAudioTick()
|
void Floors::onAudioTick()
|
||||||
{
|
{
|
||||||
if ((++audioTicks + 20) % 41 == 0)
|
if ((++audioTicks + 20) % 28 == 0)
|
||||||
{
|
{
|
||||||
|
if (skip1Beat)
|
||||||
floorManager.onAudioTick();
|
floorManager.onAudioTick();
|
||||||
lightManager.onAudioTick();
|
lightManager.onAudioTick();
|
||||||
|
skip1Beat = !skip1Beat;
|
||||||
}
|
}
|
||||||
if (audioTicks > 10000)
|
if (audioTicks > 10000)
|
||||||
audioTicks = 0;
|
audioTicks = 0;
|
||||||
|
|||||||
@@ -18,7 +18,9 @@
|
|||||||
#include "managers/light_manager.hpp"
|
#include "managers/light_manager.hpp"
|
||||||
#include "modules/texture_repository.hpp"
|
#include "modules/texture_repository.hpp"
|
||||||
#include "objects/player.hpp"
|
#include "objects/player.hpp"
|
||||||
|
#include "objects/enemy.hpp"
|
||||||
#include "./camera.hpp"
|
#include "./camera.hpp"
|
||||||
|
#include "./ui.hpp"
|
||||||
|
|
||||||
class Floors : public Game, AudioListener
|
class Floors : public Game, AudioListener
|
||||||
{
|
{
|
||||||
@@ -36,11 +38,14 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
u32 audioTicks;
|
u32 audioTicks;
|
||||||
|
u8 skip1Beat;
|
||||||
TextureRepository *texRepo;
|
TextureRepository *texRepo;
|
||||||
LightManager lightManager;
|
LightManager lightManager;
|
||||||
FloorManager floorManager;
|
FloorManager floorManager;
|
||||||
Player player;
|
Player player;
|
||||||
Camera camera;
|
Camera camera;
|
||||||
|
Ui *ui;
|
||||||
|
Enemy *enemy;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ void FloorManager::initFloors()
|
|||||||
floors[0].mesh.loadObj("floor/", "floor", 3.0F, false);
|
floors[0].mesh.loadObj("floor/", "floor", 3.0F, false);
|
||||||
floors[0].mesh.shouldBeFrustumCulled = true;
|
floors[0].mesh.shouldBeFrustumCulled = true;
|
||||||
floors[0].mesh.shouldBeLighted = true;
|
floors[0].mesh.shouldBeLighted = true;
|
||||||
for (u8 i = 1; i < floorAmount; i++)
|
for (u16 i = 1; i < floorAmount; i++)
|
||||||
floors[i].init(floors[0].mesh, spirals[i], i);
|
floors[i].init(floors[0].mesh, spirals[i], i);
|
||||||
PRINT_LOG("Floors initialized!");
|
PRINT_LOG("Floors initialized!");
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ void FloorManager::initFloors()
|
|||||||
*/
|
*/
|
||||||
void FloorManager::update(Player &t_player)
|
void FloorManager::update(Player &t_player)
|
||||||
{
|
{
|
||||||
for (u8 i = 0; i < floorAmount; i++)
|
for (u16 i = 0; i < floorAmount; i++)
|
||||||
{
|
{
|
||||||
floors[i].animate(t_player);
|
floors[i].animate(t_player);
|
||||||
|
|
||||||
@@ -106,11 +106,11 @@ void FloorManager::update(Player &t_player)
|
|||||||
/** Called by audio thread */
|
/** Called by audio thread */
|
||||||
void FloorManager::onAudioTick()
|
void FloorManager::onAudioTick()
|
||||||
{
|
{
|
||||||
if (audioTick++ > 16)
|
if (audioTick++ > 13)
|
||||||
{
|
{
|
||||||
if (audioMode == 0)
|
if (audioMode == 0)
|
||||||
{
|
{
|
||||||
for (u8 i = 0; i < floorAmount; i++)
|
for (u16 i = 0; i < floorAmount; i++)
|
||||||
{
|
{
|
||||||
if ((i + audioOffset) % 2 == 0)
|
if ((i + audioOffset) % 2 == 0)
|
||||||
floors[i].isByAudioTriggered = true;
|
floors[i].isByAudioTriggered = true;
|
||||||
@@ -125,7 +125,7 @@ void FloorManager::onAudioTick()
|
|||||||
}
|
}
|
||||||
else if (audioMode == 1)
|
else if (audioMode == 1)
|
||||||
{
|
{
|
||||||
for (u8 i = 0; i < floorAmount; i++)
|
for (u16 i = 0; i < floorAmount; i++)
|
||||||
{
|
{
|
||||||
if (i < floorAmount / (audioOffset + 1))
|
if (i < floorAmount / (audioOffset + 1))
|
||||||
floors[i].isByAudioTriggered = true;
|
floors[i].isByAudioTriggered = true;
|
||||||
@@ -140,7 +140,7 @@ void FloorManager::onAudioTick()
|
|||||||
}
|
}
|
||||||
else if (audioMode == 2)
|
else if (audioMode == 2)
|
||||||
{
|
{
|
||||||
for (u8 i = 0; i < floorAmount; i++)
|
for (u16 i = 0; i < floorAmount; i++)
|
||||||
{
|
{
|
||||||
if ((i + audioOffset) % 4 == 0)
|
if ((i + audioOffset) % 4 == 0)
|
||||||
floors[i].isByAudioTriggered = true;
|
floors[i].isByAudioTriggered = true;
|
||||||
@@ -155,9 +155,9 @@ void FloorManager::onAudioTick()
|
|||||||
}
|
}
|
||||||
else if (audioMode == 3)
|
else if (audioMode == 3)
|
||||||
{
|
{
|
||||||
for (u8 i = 0; i < floorAmount; i++)
|
for (u16 i = 0; i < floorAmount; i++)
|
||||||
{
|
{
|
||||||
if (u8(i + 1) > floorAmount / (audioOffset + 1))
|
if (u16(i + 1) > floorAmount / (audioOffset + 1))
|
||||||
floors[i].isByAudioTriggered = true;
|
floors[i].isByAudioTriggered = true;
|
||||||
else
|
else
|
||||||
floors[i].isByAudioTriggered = false;
|
floors[i].isByAudioTriggered = false;
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public:
|
|||||||
FloorManager(int t_floorAmount);
|
FloorManager(int t_floorAmount);
|
||||||
~FloorManager();
|
~FloorManager();
|
||||||
Floor floors[144]; // Temp change it also in floors.cpp
|
Floor floors[144]; // Temp change it also in floors.cpp
|
||||||
u32 floorAmount;
|
u16 floorAmount;
|
||||||
void update(Player &t_player);
|
void update(Player &t_player);
|
||||||
void onAudioTick();
|
void onAudioTick();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
# ______ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licenced under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "enemy.hpp"
|
||||||
|
|
||||||
|
#include <loaders/md2_loader.hpp>
|
||||||
|
#include <loaders/bmp_loader.hpp>
|
||||||
|
#include <modules/gif_sender.hpp>
|
||||||
|
#include <utils/debug.hpp>
|
||||||
|
#include <utils/math.hpp>
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// Constructors/Destructors
|
||||||
|
// ----
|
||||||
|
|
||||||
|
Enemy::Enemy(TextureRepository *t_texRepo)
|
||||||
|
{
|
||||||
|
PRINT_LOG("Creating enemy object");
|
||||||
|
|
||||||
|
meshes = new Mesh[getMeshesCount()];
|
||||||
|
|
||||||
|
meshes[0].loadMD2("poss/", "poss_head", 0.3F, false);
|
||||||
|
meshes[0].position.set(0.00F, 40.00F, 0.00F);
|
||||||
|
meshes[0].rotation.x = -1.566F;
|
||||||
|
meshes[0].rotation.z = 1.566F;
|
||||||
|
|
||||||
|
meshes[1].loadMD2("poss/", "poss_body", 0.3F, false);
|
||||||
|
meshes[1].position.set(0.00F, 40.00F, 0.00F);
|
||||||
|
meshes[1].rotation.x = -1.566F;
|
||||||
|
meshes[1].rotation.z = 1.566F;
|
||||||
|
|
||||||
|
meshes[2].loadMD2("poss/", "poss_weapon", 0.3F, false);
|
||||||
|
meshes[2].position.set(0.00F, 40.00F, 0.00F);
|
||||||
|
meshes[2].rotation.x = -1.566F;
|
||||||
|
meshes[2].rotation.z = 1.566F;
|
||||||
|
|
||||||
|
t_texRepo->addByMesh("poss/", meshes[0], PNG);
|
||||||
|
t_texRepo->addByMesh("poss/", meshes[1], PNG);
|
||||||
|
t_texRepo->addByMesh("poss/", meshes[2], PNG);
|
||||||
|
|
||||||
|
meshes[0].playAnimation(1, 6);
|
||||||
|
meshes[1].playAnimation(1, 6);
|
||||||
|
meshes[2].playAnimation(1, 6);
|
||||||
|
|
||||||
|
PRINT_LOG("Enemy object created!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Enemy::~Enemy()
|
||||||
|
{
|
||||||
|
delete[] meshes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// Methods
|
||||||
|
// ----
|
||||||
|
|
||||||
|
/** Called by player class. */
|
||||||
|
void Enemy::kill(const Player &player) const
|
||||||
|
{
|
||||||
|
printf("killed!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Enemy::update(const FloorManager &floorManager)
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
# ______ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licenced under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ENEMY_
|
||||||
|
#define _ENEMY_
|
||||||
|
|
||||||
|
#include <tamtypes.h>
|
||||||
|
#include "../managers/floor_manager.hpp"
|
||||||
|
#include <modules/texture_repository.hpp>
|
||||||
|
|
||||||
|
/** Player 3D object class */
|
||||||
|
class Enemy
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
s16 indexOfCurrentFloor;
|
||||||
|
Enemy(TextureRepository *t_texRepo);
|
||||||
|
~Enemy();
|
||||||
|
|
||||||
|
inline Mesh *getMeshes() const { return meshes; }
|
||||||
|
inline u8 getMeshesCount() const { return 3; }
|
||||||
|
inline Vector3 &getPosition() const { return meshes[1].position; }
|
||||||
|
void kill(const Player &player) const;
|
||||||
|
void update(const FloorManager &t_floorManager);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** 0 - head, 1 - body, 2 - weapon */
|
||||||
|
Mesh *meshes;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -23,7 +23,7 @@ class Floor
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
u16 animTimer;
|
u16 animTimer;
|
||||||
u8 animDirection, initOffset, isByAudioTriggered;
|
s16 animDirection, initOffset, isByAudioTriggered;
|
||||||
Mesh mesh;
|
Mesh mesh;
|
||||||
|
|
||||||
Floor();
|
Floor();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
|
|
||||||
#include <loaders/obj_loader.hpp>
|
#include <loaders/md2_loader.hpp>
|
||||||
#include <loaders/bmp_loader.hpp>
|
#include <loaders/bmp_loader.hpp>
|
||||||
#include <modules/gif_sender.hpp>
|
#include <modules/gif_sender.hpp>
|
||||||
#include <utils/debug.hpp>
|
#include <utils/debug.hpp>
|
||||||
@@ -20,20 +20,33 @@
|
|||||||
// Constructors/Destructors
|
// Constructors/Destructors
|
||||||
// ----
|
// ----
|
||||||
|
|
||||||
Player::Player()
|
Player::Player(Audio *t_audio)
|
||||||
{
|
{
|
||||||
PRINT_LOG("Creating player object");
|
PRINT_LOG("Creating player object");
|
||||||
this->gravity = 0.1F;
|
audio = t_audio;
|
||||||
this->lift = -1.0F;
|
gravity = 0.1F;
|
||||||
|
lift = -1.0F;
|
||||||
|
jumpCounter = 0;
|
||||||
|
killedEnemies = 0;
|
||||||
|
isWalking = false;
|
||||||
|
isFighting = false;
|
||||||
|
isWalkingAnimationSet = false;
|
||||||
|
isJumpingAnimationSet = false;
|
||||||
|
isFightingAnimationSet = false;
|
||||||
|
|
||||||
this->mesh.loadMD2("warrior/", "warrior", 0.2F, true);
|
mesh.loadMD2("warrior/", "warrior", 0.2F, true);
|
||||||
this->mesh.position.set(0.00F, 20.00F, 0.00F);
|
mesh.position.set(0.00F, 40.00F, 0.00F);
|
||||||
this->mesh.rotation.x = -1.6F;
|
mesh.rotation.x = -1.566F;
|
||||||
this->mesh.shouldBeBackfaceCulled = false;
|
mesh.rotation.z = 1.566F;
|
||||||
this->mesh.shouldBeFrustumCulled = false;
|
mesh.shouldBeBackfaceCulled = false;
|
||||||
|
mesh.shouldBeFrustumCulled = false;
|
||||||
|
mesh.setAnimSpeed(0.17F);
|
||||||
|
mesh.playAnimation(0, 0);
|
||||||
|
|
||||||
|
walkAdpcm = audio->loadADPCM("walk.adpcm");
|
||||||
|
jumpAdpcm = audio->loadADPCM("jump.adpcm");
|
||||||
|
audio->setADPCMVolume(60, 0);
|
||||||
|
|
||||||
this->mesh.setAnimSpeed(0.2F);
|
|
||||||
this->mesh.playAnimation(0, 24);
|
|
||||||
PRINT_LOG("Player object created!");
|
PRINT_LOG("Player object created!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,138 +59,205 @@ Player::~Player()
|
|||||||
// ----
|
// ----
|
||||||
|
|
||||||
/** Update player position and control gravity */
|
/** Update player position and control gravity */
|
||||||
void Player::update(Pad &pad, Camera &camera, FloorManager &floorManager)
|
void Player::update(const Pad &t_pad, const Camera &t_camera, const FloorManager &floorManager, const Enemy &enemy)
|
||||||
{
|
{
|
||||||
this->updatePosition(pad, camera, floorManager);
|
Vector3 *nextPos = getNextPosition(t_pad, t_camera);
|
||||||
this->updateGravity(pad, floorManager);
|
FloorsCheck *floorsCheck = checkFloors(floorManager, *nextPos);
|
||||||
if (mesh.position.y < -60.0F)
|
if (floorsCheck->currentFloor != NULL)
|
||||||
|
indexOfCurrentFloor = floorsCheck->currentFloor->initOffset;
|
||||||
|
updatePosition(t_pad, t_camera, floorManager, *floorsCheck, *nextPos, enemy);
|
||||||
|
updateGravity(floorsCheck);
|
||||||
|
delete floorsCheck;
|
||||||
|
delete nextPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 *Player::getNextPosition(const Pad &t_pad, const Camera &t_camera)
|
||||||
|
{
|
||||||
|
Vector3 *result = new Vector3(mesh.position);
|
||||||
|
Vector3 normalizedCamera = Vector3(t_camera.unitCirclePosition);
|
||||||
|
normalizedCamera.normalize();
|
||||||
|
if (t_pad.lJoyV <= 100)
|
||||||
{
|
{
|
||||||
mesh.position.y = 60.0F;
|
result->x += -normalizedCamera.x;
|
||||||
velocity = 0;
|
result->z += -normalizedCamera.z;
|
||||||
}
|
}
|
||||||
|
else if (t_pad.lJoyV >= 200)
|
||||||
|
{
|
||||||
|
result->x += normalizedCamera.x;
|
||||||
|
result->z += normalizedCamera.z;
|
||||||
|
}
|
||||||
|
if (t_pad.lJoyH <= 100)
|
||||||
|
{
|
||||||
|
result->x += -normalizedCamera.z;
|
||||||
|
result->z += normalizedCamera.x;
|
||||||
|
}
|
||||||
|
else if (t_pad.lJoyH >= 200)
|
||||||
|
{
|
||||||
|
result->x += normalizedCamera.z;
|
||||||
|
result->z += -normalizedCamera.x;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Move player when pad move buttons are pressed and is not blocked by any floor side */
|
/** Move player when pad move buttons are pressed and is not blocked by any floor side */
|
||||||
void Player::updatePosition(Pad &pad, Camera &camera, FloorManager &floorManager)
|
void Player::updatePosition(const Pad &t_pad, const Camera &t_camera, const FloorManager &t_floorManager, const FloorsCheck &t_floorsCheck, const Vector3 &t_nextPos, const Enemy &enemy)
|
||||||
{
|
{
|
||||||
|
if (t_pad.rJoyH >= 200)
|
||||||
|
mesh.rotation.z += 0.08;
|
||||||
|
else if (t_pad.rJoyH <= 100)
|
||||||
|
mesh.rotation.z -= 0.08;
|
||||||
|
|
||||||
if (pad.isDpadUpPressed == 1)
|
isWalking = mesh.position.x != t_nextPos.x || mesh.position.z != t_nextPos.z;
|
||||||
|
isFighting = isFighting || t_pad.isCircleClicked;
|
||||||
|
|
||||||
|
if (isFighting)
|
||||||
{
|
{
|
||||||
this->playerNextPosition.x = this->mesh.position.x + 0.01F * -camera.unitCirclePosition.x;
|
if (!isFightingAnimationSet)
|
||||||
this->playerNextPosition.z = this->mesh.position.z + 0.01F * -camera.unitCirclePosition.z;
|
{
|
||||||
|
isFightingAnimationSet = true;
|
||||||
|
mesh.playAnimation(8, 19, 0);
|
||||||
|
fightTimer.prime();
|
||||||
}
|
}
|
||||||
if (pad.isDpadDownPressed == 1)
|
if (fightTimer.getTimeDelta() > 25000)
|
||||||
|
{ // end of fighting
|
||||||
|
float distance = getPosition().distanceTo(enemy.getPosition());
|
||||||
|
if (12.0F > distance)
|
||||||
{
|
{
|
||||||
this->playerNextPosition.x = this->mesh.position.x + 0.01F * camera.unitCirclePosition.x;
|
enemy.kill(*this);
|
||||||
this->playerNextPosition.z = this->mesh.position.z + 0.01F * camera.unitCirclePosition.z;
|
killedEnemies++;
|
||||||
}
|
}
|
||||||
if (pad.isDpadLeftPressed == 1)
|
isFightingAnimationSet = false;
|
||||||
{
|
isFighting = false;
|
||||||
this->playerNextPosition.x = this->mesh.position.x + 0.01F * -camera.unitCirclePosition.z;
|
|
||||||
this->playerNextPosition.z = this->mesh.position.z + 0.01F * camera.unitCirclePosition.x;
|
|
||||||
}
|
}
|
||||||
if (pad.isDpadRightPressed == 1)
|
|
||||||
{
|
|
||||||
this->playerNextPosition.x = this->mesh.position.x + 0.01F * camera.unitCirclePosition.z;
|
|
||||||
this->playerNextPosition.z = this->mesh.position.z + 0.01F * -camera.unitCirclePosition.x;
|
|
||||||
}
|
}
|
||||||
this->playerNextPosition.y = this->mesh.position.y;
|
else if (isWalking)
|
||||||
this->isCollideFloor = 0;
|
|
||||||
Vector3 min = Vector3();
|
|
||||||
Vector3 max = Vector3();
|
|
||||||
for (u32 i = 0; i < floorManager.floorAmount; i++)
|
|
||||||
{
|
{
|
||||||
getMinMax(&floorManager.floors[i].mesh, &min, &max);
|
if (!isWalkingAnimationSet)
|
||||||
this->isCollideFloor = this->playerNextPosition.collidesSquare(min, max);
|
{
|
||||||
if (this->isCollideFloor == 1)
|
isWalkingAnimationSet = true;
|
||||||
break;
|
this->mesh.playAnimation(1, 8);
|
||||||
}
|
}
|
||||||
if (this->isCollideFloor == 0)
|
if (walkTimer.getTimeDelta() > 8000)
|
||||||
{
|
{
|
||||||
this->mesh.position.x = this->playerNextPosition.x;
|
walkTimer.prime();
|
||||||
this->mesh.position.z = this->playerNextPosition.z;
|
audio->playADPCM(walkAdpcm, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isWalkingAnimationSet = false;
|
||||||
|
mesh.playAnimation(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t_floorsCheck.willCollideFloor == NULL && !isFighting)
|
||||||
|
{
|
||||||
|
mesh.position.x = t_nextPos.x;
|
||||||
|
mesh.position.z = t_nextPos.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t_pad.isCrossClicked == 1)
|
||||||
|
{
|
||||||
|
velocity = lift;
|
||||||
|
audio->playADPCM(jumpAdpcm);
|
||||||
|
jumpCounter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Do not call this.
|
/**
|
||||||
|
* Do not call this.
|
||||||
* This is called by Floor::animate() on player's floor move in Y direction
|
* This is called by Floor::animate() on player's floor move in Y direction
|
||||||
*/
|
*/
|
||||||
void Player::onBeforePlayerFloorMove(Floor *floor, float &newY)
|
void Player::onBeforePlayerFloorMove(Floor *t_floor, float &t_newY)
|
||||||
{
|
{
|
||||||
if (floor->animDirection == 0 && newY > 0.0F)
|
if (t_floor->animDirection == 0 && t_newY > 0.0F)
|
||||||
this->mesh.position.y += newY * 1.05F;
|
this->mesh.position.y += t_newY * 1.05F;
|
||||||
else if ((floor->animDirection == 1 && -newY < 0.0F))
|
else if ((t_floor->animDirection == 1 && -t_newY < 0.0F))
|
||||||
this->mesh.position.y -= -newY * 1.05F;
|
this->mesh.position.y -= -t_newY * 1.05F;
|
||||||
}
|
|
||||||
|
|
||||||
/** Calculates minimum and maximum X, Y, Z of mesh vertices + current position */
|
|
||||||
void Player::getMinMax(Mesh *t_mesh, Vector3 *t_min, Vector3 *t_max)
|
|
||||||
{
|
|
||||||
Vector3 calc = Vector3();
|
|
||||||
u8 isInitialized = 0;
|
|
||||||
Vector3 *boundingBox = t_mesh->getCurrentBoundingBox();
|
|
||||||
for (u32 i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
calc.set(
|
|
||||||
boundingBox[i].x + t_mesh->position.x,
|
|
||||||
boundingBox[i].y + t_mesh->position.y,
|
|
||||||
boundingBox[i].z + t_mesh->position.z);
|
|
||||||
if (isInitialized == 0)
|
|
||||||
{
|
|
||||||
isInitialized = 1;
|
|
||||||
t_min->set(calc);
|
|
||||||
t_max->set(calc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t_min->x > calc.x)
|
|
||||||
t_min->x = calc.x;
|
|
||||||
if (calc.x > t_max->x)
|
|
||||||
t_max->x = calc.x;
|
|
||||||
|
|
||||||
if (t_min->y > calc.y)
|
|
||||||
t_min->y = calc.y;
|
|
||||||
if (calc.y > t_max->y)
|
|
||||||
t_max->y = calc.y;
|
|
||||||
|
|
||||||
if (t_min->z > calc.z)
|
|
||||||
t_min->z = calc.z;
|
|
||||||
if (calc.z > t_max->z)
|
|
||||||
t_max->z = calc.z;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Update player position by gravity and update index of current floor */
|
/** Update player position by gravity and update index of current floor */
|
||||||
void Player::updateGravity(Pad &pad, FloorManager &floorManager)
|
void Player::updateGravity(FloorsCheck *t_floorsCheck)
|
||||||
{
|
{
|
||||||
Vector3 min = Vector3();
|
|
||||||
Vector3 max = Vector3();
|
|
||||||
|
|
||||||
if (pad.isCrossClicked == 1)
|
|
||||||
this->velocity = this->lift;
|
|
||||||
|
|
||||||
this->isOnFloor = 0;
|
|
||||||
for (u32 i = 0; i < floorManager.floorAmount; i++)
|
|
||||||
{
|
|
||||||
getMinMax(&floorManager.floors[i].mesh, &min, &max);
|
|
||||||
this->isOnFloor = this->mesh.position.isOnSquare(min, max);
|
|
||||||
if (this->isOnFloor == 1)
|
|
||||||
{
|
|
||||||
this->indexOfCurrentFloor = floorManager.floors[i].initOffset;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->velocity += this->gravity;
|
this->velocity += this->gravity;
|
||||||
this->mesh.position.y -= this->velocity;
|
this->mesh.position.y -= this->velocity;
|
||||||
|
u8 isOnFloor = t_floorsCheck->currentFloor != NULL && mesh.position.y < t_floorsCheck->currFloorMax.y;
|
||||||
|
|
||||||
if (this->mesh.position.y >= 60.0F)
|
if (this->mesh.position.y >= 60.0F || mesh.position.y < -60.0F)
|
||||||
{
|
{
|
||||||
this->mesh.position.y = 60.0F;
|
this->mesh.position.y = 60.0F;
|
||||||
this->velocity = 0;
|
this->velocity = 0;
|
||||||
}
|
}
|
||||||
else if ((this->mesh.position.y) < max.y && this->isOnFloor)
|
else if (isOnFloor)
|
||||||
{
|
{
|
||||||
this->mesh.position.y = max.y;
|
this->mesh.position.y = t_floorsCheck->currFloorMax.y;
|
||||||
this->velocity = 0;
|
this->velocity = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
// Private
|
||||||
|
// ---
|
||||||
|
|
||||||
|
FloorsCheck *Player::checkFloors(const FloorManager &t_floorManager, const Vector3 &t_nextPos)
|
||||||
|
{
|
||||||
|
FloorsCheck *result = new FloorsCheck;
|
||||||
|
result->currentFloor = NULL;
|
||||||
|
result->willCollideFloor = NULL;
|
||||||
|
Vector3 min = Vector3();
|
||||||
|
Vector3 max = Vector3();
|
||||||
|
for (u32 i = 0; i < t_floorManager.floorAmount; i++)
|
||||||
|
{
|
||||||
|
getMinMax(t_floorManager.floors[i].mesh, min, max);
|
||||||
|
if (result->currentFloor == NULL && this->mesh.position.isOnSquare(min, max))
|
||||||
|
{
|
||||||
|
result->currentFloor = &t_floorManager.floors[i];
|
||||||
|
result->currFloorMin.set(min);
|
||||||
|
result->currFloorMax.set(max);
|
||||||
|
}
|
||||||
|
if (result->willCollideFloor == NULL && t_nextPos.collidesSquare(min, max))
|
||||||
|
{
|
||||||
|
result->willCollideFloor = &t_floorManager.floors[i];
|
||||||
|
result->willCollideFloorMin.set(min);
|
||||||
|
result->willCollideFloorMax.set(max);
|
||||||
|
}
|
||||||
|
if (result->currentFloor != NULL && result->willCollideFloor != NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Calculates minimum and maximum X, Y, Z of mesh vertices + current position */
|
||||||
|
void Player::getMinMax(const Mesh &t_mesh, Vector3 &t_min, Vector3 &t_max)
|
||||||
|
{
|
||||||
|
Vector3 calc = Vector3();
|
||||||
|
u8 isInitialized = 0;
|
||||||
|
Vector3 *boundingBox = t_mesh.getCurrentBoundingBox();
|
||||||
|
for (u32 i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
calc.set(
|
||||||
|
boundingBox[i].x + t_mesh.position.x,
|
||||||
|
boundingBox[i].y + t_mesh.position.y,
|
||||||
|
boundingBox[i].z + t_mesh.position.z);
|
||||||
|
if (isInitialized == 0)
|
||||||
|
{
|
||||||
|
isInitialized = 1;
|
||||||
|
t_min.set(calc);
|
||||||
|
t_max.set(calc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t_min.x > calc.x)
|
||||||
|
t_min.x = calc.x;
|
||||||
|
if (calc.x > t_max.x)
|
||||||
|
t_max.x = calc.x;
|
||||||
|
|
||||||
|
if (t_min.y > calc.y)
|
||||||
|
t_min.y = calc.y;
|
||||||
|
if (calc.y > t_max.y)
|
||||||
|
t_max.y = calc.y;
|
||||||
|
|
||||||
|
if (t_min.z > calc.z)
|
||||||
|
t_min.z = calc.z;
|
||||||
|
if (calc.z > t_max.z)
|
||||||
|
t_max.z = calc.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,8 +13,17 @@
|
|||||||
|
|
||||||
#include "../managers/floor_manager.hpp"
|
#include "../managers/floor_manager.hpp"
|
||||||
#include "../camera.hpp"
|
#include "../camera.hpp"
|
||||||
|
#include "./enemy.hpp"
|
||||||
#include <modules/pad.hpp>
|
#include <modules/pad.hpp>
|
||||||
|
#include <modules/timer.hpp>
|
||||||
#include <tamtypes.h>
|
#include <tamtypes.h>
|
||||||
|
#include <modules/audio.hpp>
|
||||||
|
|
||||||
|
struct FloorsCheck
|
||||||
|
{
|
||||||
|
const Floor *currentFloor, *willCollideFloor;
|
||||||
|
Vector3 currFloorMin, willCollideFloorMin, currFloorMax, willCollideFloorMax;
|
||||||
|
};
|
||||||
|
|
||||||
/** Player 3D object class */
|
/** Player 3D object class */
|
||||||
class Player
|
class Player
|
||||||
@@ -22,19 +31,28 @@ class Player
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
float gravity, velocity, lift;
|
float gravity, velocity, lift;
|
||||||
u8 isOnFloor, isCollideFloor, indexOfCurrentFloor;
|
|
||||||
Mesh mesh;
|
Mesh mesh;
|
||||||
Player();
|
s16 indexOfCurrentFloor;
|
||||||
|
Player(Audio *t_audio);
|
||||||
~Player();
|
~Player();
|
||||||
|
|
||||||
void update(Pad &pad, Camera &camera, FloorManager &floorManager);
|
void update(const Pad &t_pad, const Camera &t_camera, const FloorManager &t_floorManager, const Enemy &enemy);
|
||||||
void onBeforePlayerFloorMove(Floor *floor, float &newY);
|
void onBeforePlayerFloorMove(Floor *t_floor, float &t_newY);
|
||||||
|
const inline u32 &getJumpCount() const { return jumpCounter; }
|
||||||
|
inline const Vector3 &getPosition() const { return mesh.position; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector3 playerNextPosition;
|
u32 jumpCounter, killedEnemies;
|
||||||
void getMinMax(Mesh *t_mesh, Vector3 *t_min, Vector3 *t_max);
|
Vector3 *getNextPosition(const Pad &t_pad, const Camera &t_camera);
|
||||||
void updatePosition(Pad &pad, Camera &camera, FloorManager &floorManager);
|
FloorsCheck *checkFloors(const FloorManager &t_floorManager, const Vector3 &t_nextPos);
|
||||||
void updateGravity(Pad &pad, FloorManager &floorManager);
|
u8 isWalkingAnimationSet, isJumpingAnimationSet, isFightingAnimationSet;
|
||||||
|
u8 isFighting, isWalking;
|
||||||
|
Audio *audio;
|
||||||
|
Timer walkTimer, fightTimer;
|
||||||
|
audsrv_adpcm_t *walkAdpcm, *jumpAdpcm;
|
||||||
|
void getMinMax(const Mesh &t_mesh, Vector3 &t_min, Vector3 &t_max);
|
||||||
|
void updatePosition(const Pad &t_pad, const Camera &t_camera, const FloorManager &t_floorManager, const FloorsCheck &t_floorsCheck, const Vector3 &nextPos, const Enemy &enemy);
|
||||||
|
void updateGravity(FloorsCheck *t_floorsCheck);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
# ______ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licenced under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ui.hpp"
|
||||||
|
|
||||||
|
#include <utils/debug.hpp>
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// Constructors/Destructors
|
||||||
|
// ----
|
||||||
|
|
||||||
|
Ui::Ui(TextureRepository *t_texRepo)
|
||||||
|
{
|
||||||
|
PRINT_LOG("Initializing ui");
|
||||||
|
|
||||||
|
isTask1Done = false;
|
||||||
|
isTask2Done = false;
|
||||||
|
|
||||||
|
task1.size.set(128.0F, 32.0F);
|
||||||
|
task1.position.set(500.0F, 10.0F);
|
||||||
|
|
||||||
|
task2.size.set(128.0F, 32.0F);
|
||||||
|
task2.position.set(500.0F, 50.0F);
|
||||||
|
|
||||||
|
task1Checkbox.size.set(32.0F, 32.0F);
|
||||||
|
task1Checkbox.position.set(460.0F, 10.0F);
|
||||||
|
|
||||||
|
task2Checkbox.size.set(32.0F, 32.0F);
|
||||||
|
task2Checkbox.position.set(460.0F, 50.0F);
|
||||||
|
|
||||||
|
t_texRepo->add("2d/", "check1_text", PNG)->addLink(task1.getId());
|
||||||
|
t_texRepo->add("2d/", "check2_text", PNG)->addLink(task2.getId());
|
||||||
|
grayCheckboxTex = t_texRepo->add("2d/", "gray_checkmark", PNG);
|
||||||
|
blueCheckboxTex = t_texRepo->add("2d/", "blue_checkmark", PNG);
|
||||||
|
|
||||||
|
grayCheckboxTex->addLink(task1Checkbox.getId());
|
||||||
|
grayCheckboxTex->addLink(task2Checkbox.getId());
|
||||||
|
|
||||||
|
PRINT_LOG("Ui initialized!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ui::~Ui() {}
|
||||||
|
|
||||||
|
// ----
|
||||||
|
// Methods
|
||||||
|
// ----
|
||||||
|
|
||||||
|
void Ui::update(const Player &player)
|
||||||
|
{
|
||||||
|
if (!isTask1Done && player.getJumpCount() >= 10)
|
||||||
|
{
|
||||||
|
isTask1Done = true;
|
||||||
|
grayCheckboxTex->removeLinkBySprite(task1Checkbox.getId());
|
||||||
|
blueCheckboxTex->addLink(task1Checkbox.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ui::render(Renderer *t_renderer)
|
||||||
|
{
|
||||||
|
t_renderer->draw(task1);
|
||||||
|
t_renderer->draw(task2);
|
||||||
|
t_renderer->draw(task1Checkbox);
|
||||||
|
t_renderer->draw(task2Checkbox);
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
# ______ ____ ___
|
||||||
|
# | \/ ____| |___|
|
||||||
|
# | | | \ | |
|
||||||
|
#-----------------------------------------------------------------------
|
||||||
|
# Copyright 2020, tyra - https://github.com/h4570/tyra
|
||||||
|
# Licenced under Apache License 2.0
|
||||||
|
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _UI_
|
||||||
|
#define _UI_
|
||||||
|
|
||||||
|
#include <modules/texture_repository.hpp>
|
||||||
|
#include <modules/renderer.hpp>
|
||||||
|
#include "objects/player.hpp"
|
||||||
|
#include <tamtypes.h>
|
||||||
|
|
||||||
|
class Ui
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
Ui(TextureRepository *t_texRepo);
|
||||||
|
~Ui();
|
||||||
|
|
||||||
|
void update(const Player &player);
|
||||||
|
void render(Renderer *t_renderer);
|
||||||
|
|
||||||
|
private:
|
||||||
|
u8 isTask1Done, isTask2Done;
|
||||||
|
Sprite task1, task2, task1Checkbox, task2Checkbox;
|
||||||
|
Texture *grayCheckboxTex, *blueCheckboxTex;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user