Created basic movement.
This commit is contained in:
@ -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;
|
||||
}
|
@ -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();
|
||||
};
|
||||
}
|
@ -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() {
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -10,6 +10,7 @@ namespace Dawn {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right
|
||||
Right,
|
||||
Run
|
||||
};
|
||||
}
|
@ -7,4 +7,5 @@ target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
PlayerPrefab.cpp
|
||||
WorldPrefab.cpp
|
||||
TestEntityPrefab.cpp
|
||||
)
|
@ -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
|
||||
);
|
||||
|
||||
|
37
src/dawnrpg/prefab/TestEntityPrefab.cpp
Normal file
37
src/dawnrpg/prefab/TestEntityPrefab.cpp
Normal 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;
|
||||
}
|
24
src/dawnrpg/prefab/TestEntityPrefab.hpp
Normal file
24
src/dawnrpg/prefab/TestEntityPrefab.hpp
Normal 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
|
||||
);
|
||||
}
|
@ -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 });
|
||||
}
|
Reference in New Issue
Block a user