Created basic movement.

This commit is contained in:
2024-09-11 09:21:56 -05:00
parent 01c56477aa
commit e5349cc093
13 changed files with 364 additions and 48 deletions

View File

@ -6,17 +6,41 @@
#include "Entity.hpp"
#include "scene/Scene.hpp"
#include "assert/assert.hpp"
#include "util/Easing.hpp"
using namespace Dawn;
const glm::vec3 EntityTilePosition::toWorldSpace() {
return glm::vec3(
this->x,
this->y,
this->z
);
}
void Entity::onInit() {
auto world = this->world.lock();
assertNotNull(world, "World is no longer active?");
listeners.push_back(getScene()->onUnpausedUpdate.listen([this](float delta) {
if(this->stepTime <= 0.0f) return;
this->stepTime = 0;
this->getItem()->setLocalPosition(glm::vec3(this->tileX, this->tileY, this->tileZ));
this->stepTime -= delta * this->stepSpeed;
glm::vec3 nextPosition = this->tilePosition.toWorldSpace();
if(this->stepTime <= 0) {
this->getItem()->setLocalPosition(nextPosition);
this->stepTime = 0.0f;
this->eventMove.emit();
this->eventStepEnd.emit();
return;
}
float_t t = Easing::easeInOutSine(1.0f - this->stepTime);
glm::vec3 lastPosition = this->lastTilePosition.toWorldSpace();
glm::vec3 newLocal = glm::mix(lastPosition, nextPosition, t);
this->getItem()->setLocalPosition(newLocal);
this->eventMove.emit();
}));
}
@ -24,24 +48,24 @@ void Entity::onDispose() {
}
void Entity::move(const enum EntityDirection direction) {
entitytileposition_t newTileX, newTileY, newTileZ;
newTileX = tileX;
newTileY = tileY;
newTileZ = tileZ;
void Entity::move(
const enum EntityDirection direction,
const float_t stepSpeed
) {
struct EntityTilePosition newPosition = this->tilePosition;
switch(direction) {
case EntityDirection::Up:
newTileZ--;
newPosition.z--;
break;
case EntityDirection::Down:
newTileZ++;
newPosition.z++;
break;
case EntityDirection::Left:
newTileX--;
newPosition.x--;
break;
case EntityDirection::Right:
newTileX++;
newPosition.x++;
break;
default:
assertUnreachable("Invalid direction: %d", direction);
@ -51,9 +75,22 @@ void Entity::move(const enum EntityDirection direction) {
// If the tile is not walkable, return early.
// Move the entity to the new tile.
this->tileX = newTileX;
this->tileY = newTileY;
this->tileZ = newTileZ;
this->lastTilePosition = this->tilePosition;
this->tilePosition = newPosition;
this->direction = direction;
this->stepTime = 1.0f;
this->stepSpeed = stepSpeed;
this->eventStepStart.emit();
}
void Entity::setPosition(struct EntityTilePosition pos) {
this->stepTime = 0.0f;
this->tilePosition = pos;
this->lastTilePosition = pos;
this->getItem()->setLocalPosition(pos.toWorldSpace());
}
bool_t Entity::isMoving() {
return this->stepTime > 0.0f;
}

View File

@ -5,10 +5,14 @@
#pragma once
#include "scene/SceneComponent.hpp"
#include "event/Event.hpp"
typedef uint32_t entityid_t;
typedef int64_t entitytileposition_t;
#define ENTITY_STEP_SPEED_DEFAULT 3.0f
#define ENTITY_STEP_SPEED_RUNNING 6.0f
namespace Dawn {
class World;
@ -18,20 +22,42 @@ namespace Dawn {
Left,
Right
};
struct EntityTilePosition {
entitytileposition_t x, y, z;
/**
* Converts the tile position to a world space position.
*
* @return This tile position in world space.
*/
const glm::vec3 toWorldSpace();
};
class Entity : public SceneComponent {
private:
entitytileposition_t tileX = 0, tileY = 0, tileZ = 0;
struct EntityTilePosition lastTilePosition;
enum EntityDirection direction = EntityDirection::Down;
float_t stepTime = 0.0f;
float_t stepSpeed = ENTITY_STEP_SPEED_DEFAULT;
protected:
struct EntityTilePosition tilePosition;
public:
std::weak_ptr<World> world;
Event<> eventStepStart;
Event<> eventStepEnd;
Event<> eventMove;
void onInit() override;
void onDispose() override;
void move(const enum EntityDirection direction);
void move(
const enum EntityDirection direction,
const float_t stepSpeed = ENTITY_STEP_SPEED_DEFAULT
);
void setPosition(struct EntityTilePosition position);
bool_t isMoving();
};
}

View File

@ -13,17 +13,39 @@ void Player::onInit() {
Entity::onInit();
listeners.push_back(getScene()->onUnpausedUpdate.listen([this](float delta) {
if(this->isMoving()) return;
InputManager &im = getGame()->inputManager;
if(im.isPressed(InputBind::Up)) {
this->move(EntityDirection::Up);
} else if(im.isPressed(InputBind::Down)) {
this->move(EntityDirection::Down);
} else if(im.isPressed(InputBind::Left)) {
this->move(EntityDirection::Left);
} else if(im.isPressed(InputBind::Right)) {
this->move(EntityDirection::Right);
bool_t run = im.isDown(InputBind::Run);
float_t stepSpeed = run ? ENTITY_STEP_SPEED_RUNNING : ENTITY_STEP_SPEED_DEFAULT;
if(im.isDown(InputBind::Up)) {
this->move(EntityDirection::Up, stepSpeed);
} else if(im.isDown(InputBind::Down)) {
this->move(EntityDirection::Down, stepSpeed);
} else if(im.isDown(InputBind::Left)) {
this->move(EntityDirection::Left, stepSpeed);
} else if(im.isDown(InputBind::Right)) {
this->move(EntityDirection::Right, stepSpeed);
}
}));
listeners.push_back(eventMove.listen([this]() {
this->updateCameraPosition();
}));
this->updateCameraPosition();
}
void Player::updateCameraPosition() {
auto c = camera.lock();
if(!c) return;
glm::vec3 pos = this->getItem()->getLocalPosition();
c->getItem()->lookAt(
pos + glm::vec3(0, 8, 1),
pos,
glm::vec3(0, 1, 0)
);
}
void Player::onDispose() {

View File

@ -5,12 +5,16 @@
#pragma once
#include "component/entity/Entity.hpp"
#include "component/display/Camera.hpp"
namespace Dawn {
class Player : public Entity {
protected:
void updateCameraPosition();
public:
std::weak_ptr<Camera> camera;
void onInit() override;
void onDispose() override;
};