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;
};

View File

@ -10,6 +10,7 @@ namespace Dawn {
Up,
Down,
Left,
Right
Right,
Run
};
}

View File

@ -7,4 +7,5 @@ target_sources(${DAWN_TARGET_NAME}
PRIVATE
PlayerPrefab.cpp
WorldPrefab.cpp
TestEntityPrefab.cpp
)

View File

@ -4,7 +4,7 @@
// https://opensource.org/licenses/MIT
#include "PlayerPrefab.hpp"
#include "display/mesh/QuadMesh.hpp"
#include "display/mesh/CubeMesh.hpp"
using namespace Dawn;
@ -19,11 +19,11 @@ struct PlayerPrefab Dawn::createPlayerPrefab(
player.player->world = world;
player.mesh = std::make_shared<Mesh>();
player.mesh->createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT);
QuadMesh::buffer(
player.mesh->createBuffers(CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT);
CubeMesh::buffer(
player.mesh,
glm::vec4(0, 0, 1, 1),
glm::vec4(0, 0, 1, 1),
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(1, 1, 1),
0, 0
);

View File

@ -0,0 +1,37 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "TestEntityPrefab.hpp"
#include "display/mesh/CubeMesh.hpp"
using namespace Dawn;
struct TestEntityPrefab Dawn::createTestEntityPrefab(
const std::shared_ptr<World> world
) {
struct TestEntityPrefab entity;
entity.item = world->getScene()->createSceneItem();
entity.item->setParent(world->getItem());
entity.entity = entity.item->addComponent<Entity>();
entity.entity->world = world;
entity.mesh = std::make_shared<Mesh>();
entity.mesh->createBuffers(CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT);
CubeMesh::buffer(
entity.mesh,
glm::vec3(-0.5f, -0.5f, -0.5f),
glm::vec3(1, 1, 1),
0, 0
);
entity.meshRenderer = entity.item->addComponent<MeshRenderer>();
entity.meshRenderer->mesh = entity.mesh;
entity.material = entity.item->addComponent<SimpleTexturedMaterial>();
entity.material->setColor(COLOR_GREEN);
return entity;
}

View File

@ -0,0 +1,24 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "prefab/Prefab.hpp"
#include "component/world/World.hpp"
#include "component/display/MeshRenderer.hpp"
#include "component/display/material/SimpleTexturedMaterial.hpp"
namespace Dawn {
struct TestEntityPrefab : public Prefab {
public:
std::shared_ptr<Entity> entity;
std::shared_ptr<Mesh> mesh;
std::shared_ptr<MeshRenderer> meshRenderer;
std::shared_ptr<SimpleTexturedMaterial> material;
};
struct TestEntityPrefab createTestEntityPrefab(
const std::shared_ptr<World> world
);
}

View File

@ -6,6 +6,7 @@
#include "scenes/SceneList.hpp"
#include "prefab/PlayerPrefab.hpp"
#include "prefab/TestEntityPrefab.hpp"
#include "prefab/WorldPrefab.hpp"
#include "component/display/Camera.hpp"
// #include "prefab/SimpleSpinningCube.hpp"
@ -43,4 +44,8 @@ void Dawn::worldScene(Scene &s) {
auto world = createWorldPrefab(s);
auto player = createPlayerPrefab(world.world);
player.player->camera = camera;
auto test = createTestEntityPrefab(world.world);
test.entity->setPosition({ 5, 0, 0 });
}