ADD: Enable AnimationSystem
This commit is contained in:
parent
12c617587f
commit
97f8e71e18
@ -279,6 +279,7 @@ target_link_libraries(GameLib PUBLIC Engine)
|
|||||||
# --- Executable ---
|
# --- Executable ---
|
||||||
add_executable(ColorRace
|
add_executable(ColorRace
|
||||||
game/src/main.cpp
|
game/src/main.cpp
|
||||||
|
engine/src/core/animation/components/BlockingAnimationComponent.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(ColorRace PRIVATE
|
target_link_libraries(ColorRace PRIVATE
|
||||||
|
|||||||
@ -4,19 +4,28 @@
|
|||||||
|
|
||||||
#include "AnimationSystem.h"
|
#include "AnimationSystem.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "components/TransformAnimationComponent.h"
|
#include "components/TransformAnimationComponent.h"
|
||||||
#include "ecs/standardComponents/TransformComponent.h"
|
#include "ecs/standardComponents/TransformComponent.h"
|
||||||
|
|
||||||
namespace engine::animation {
|
namespace engine::animation {
|
||||||
void animation::AnimationSystem::update(float deltaTime) {
|
void animation::AnimationSystem::update(float deltaTime) {
|
||||||
|
std::vector<engine::Entity> toRemove;
|
||||||
for (auto& [entity, animation] : m_registry.getPool<TransformAnimationComponent>()) {
|
for (auto& [entity, animation] : m_registry.getPool<TransformAnimationComponent>()) {
|
||||||
animation.time += deltaTime;
|
animation.time += deltaTime;
|
||||||
|
|
||||||
auto& transform = m_registry.getComponent<TransformComponent>(entity);
|
auto& transform = m_registry.getComponent<TransformComponent>(entity);
|
||||||
|
|
||||||
transform.m_position = evaluate(animation.position, animation.time);
|
if (!animation.position.keys.empty()) {
|
||||||
transform.m_rotation = evaluate(animation.rotation, animation.time);
|
transform.m_position = evaluate(animation.position, animation.time);
|
||||||
transform.m_scale = evaluate(animation.scale, animation.time);
|
}
|
||||||
|
if (!animation.rotation.keys.empty()) {
|
||||||
|
transform.m_rotation = evaluate(animation.rotation, animation.time);
|
||||||
|
}
|
||||||
|
if (!animation.scale.keys.empty()) {
|
||||||
|
transform.m_scale = evaluate(animation.scale, animation.time);
|
||||||
|
}
|
||||||
|
|
||||||
if (animation.time >= animation.duration) {
|
if (animation.time >= animation.duration) {
|
||||||
if (animation.loop) {
|
if (animation.loop) {
|
||||||
@ -26,8 +35,13 @@ namespace engine::animation {
|
|||||||
animation.onFinished();
|
animation.onFinished();
|
||||||
}
|
}
|
||||||
animation.finished = true;
|
animation.finished = true;
|
||||||
|
toRemove.push_back(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto entity : toRemove) {
|
||||||
|
m_registry.removeComponent<TransformAnimationComponent>(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // engine
|
} // engine
|
||||||
@ -16,11 +16,13 @@ namespace engine::animation {
|
|||||||
EntityRegistry& m_registry;
|
EntityRegistry& m_registry;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
glm::vec3 evaluate(const AnimationTrack<T>& track, float time) {
|
T evaluate(const AnimationTrack<T>& track, float time) {
|
||||||
Keyframe<T> a;
|
Keyframe<T> a;
|
||||||
Keyframe<T> b;
|
Keyframe<T> b;
|
||||||
findSurroundingKeys(track, time, a, b);
|
findSurroundingKeys(track, time, a, b);
|
||||||
|
|
||||||
|
if (a.time == b.time) return a.value;
|
||||||
|
|
||||||
float localT = (time - a.time) / (b.time - a.time);
|
float localT = (time - a.time) / (b.time - a.time);
|
||||||
float easedT = a.easingFunction(localT);
|
float easedT = a.easingFunction(localT);
|
||||||
return glm::mix(a.value, b.value, easedT);
|
return glm::mix(a.value, b.value, easedT);
|
||||||
|
|||||||
@ -0,0 +1,11 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 05.08.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef COLORRACE_BLOCKINGANIMATIONCOMPONENT_H
|
||||||
|
#define COLORRACE_BLOCKINGANIMATIONCOMPONENT_H
|
||||||
|
namespace engine::animation {
|
||||||
|
struct BlockingAnimationComponent {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif //COLORRACE_BLOCKINGANIMATIONCOMPONENT_H
|
||||||
@ -12,6 +12,7 @@ namespace engine {
|
|||||||
public:
|
public:
|
||||||
virtual ~IComponentPool() = default;
|
virtual ~IComponentPool() = default;
|
||||||
virtual void remove(Entity entity) = 0;
|
virtual void remove(Entity entity) = 0;
|
||||||
|
virtual size_t size() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -33,6 +34,10 @@ namespace engine {
|
|||||||
return m_components.at(entity);
|
return m_components.at(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t size() override {
|
||||||
|
return m_components.size();
|
||||||
|
}
|
||||||
|
|
||||||
// Für Iteration in Systemen
|
// Für Iteration in Systemen
|
||||||
auto begin() { return m_components.begin(); }
|
auto begin() { return m_components.begin(); }
|
||||||
auto end() { return m_components.end(); }
|
auto end() { return m_components.end(); }
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include "ecs/standardComponents/HighlightComponent.h"
|
#include "ecs/standardComponents/HighlightComponent.h"
|
||||||
#include "ecs/standardComponents/MeshComponent.h"
|
#include "ecs/standardComponents/MeshComponent.h"
|
||||||
#include "ecs/standardComponents/TransformComponent.h"
|
#include "ecs/standardComponents/TransformComponent.h"
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
|
|
||||||
void engine::MeshRenderSystem::update(engine::EntityRegistry ®istry, engine::RenderQueue &renderQueue) {
|
void engine::MeshRenderSystem::update(engine::EntityRegistry ®istry, engine::RenderQueue &renderQueue) {
|
||||||
@ -20,6 +21,8 @@ void engine::MeshRenderSystem::update(engine::EntityRegistry ®istry, engine::
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto& transform = transforms.get(entity);
|
auto& transform = transforms.get(entity);
|
||||||
|
// spdlog::info("Entity {}: pos=({}, {}, {})", entity.value(),
|
||||||
|
// transform.m_position.x, transform.m_position.y, transform.m_position.z);
|
||||||
|
|
||||||
RenderCommand renderCommand(mesh.model, transform.computeModelMatrix());
|
RenderCommand renderCommand(mesh.model, transform.computeModelMatrix());
|
||||||
if (registry.hasComponent<HighlightComponent>(entity)) {
|
if (registry.hasComponent<HighlightComponent>(entity)) {
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
#include <glm/gtx/string_cast.hpp>
|
#include <glm/gtx/string_cast.hpp>
|
||||||
|
|
||||||
|
#include "core/animation/components/BlockingAnimationComponent.h"
|
||||||
#include "core/audio/SoundSource.h"
|
#include "core/audio/SoundSource.h"
|
||||||
#include "GLFW/glfw3.h"
|
#include "GLFW/glfw3.h"
|
||||||
using namespace engine;
|
using namespace engine;
|
||||||
@ -55,9 +56,16 @@ void GameLayer::renderHud() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GameLayer::isAnimationBlocking() {
|
||||||
|
return m_entityRegistry.getPool<animation::BlockingAnimationComponent>().size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
void GameLayer::onUpdate(float deltaTime) {
|
void GameLayer::onUpdate(float deltaTime) {
|
||||||
Layer::onUpdate(deltaTime);
|
Layer::onUpdate(deltaTime);
|
||||||
m_cameraController->update(getKeyboard(), *m_camera, deltaTime);
|
m_cameraController->update(getKeyboard(), *m_camera, deltaTime);
|
||||||
|
m_animationSystem.update(deltaTime);
|
||||||
|
if (isAnimationBlocking()) return;
|
||||||
|
|
||||||
for (auto& ai : aiControllers) {
|
for (auto& ai : aiControllers) {
|
||||||
ai.update(deltaTime);
|
ai.update(deltaTime);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#define COLORRACE_GAMELAYER_H
|
#define COLORRACE_GAMELAYER_H
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "core/animation/AnimationSystem.h"
|
||||||
#include "core/audio/AudioDevice.h"
|
#include "core/audio/AudioDevice.h"
|
||||||
#include "core/audio/SoundBuffer.h"
|
#include "core/audio/SoundBuffer.h"
|
||||||
#include "core/inputsOutputs/controller/CameraController.h"
|
#include "core/inputsOutputs/controller/CameraController.h"
|
||||||
@ -27,7 +28,7 @@ public:
|
|||||||
engine::Keyboard& keyboard, engine::Mouse& mouse, std::shared_ptr<engine::Model> boardModel, std::unordered_map<std::string, std::shared_ptr<engine::Model>> pieceModdels)
|
engine::Keyboard& keyboard, engine::Mouse& mouse, std::shared_ptr<engine::Model> boardModel, std::unordered_map<std::string, std::shared_ptr<engine::Model>> pieceModdels)
|
||||||
: Layer(keyboard, mouse), m_gameMode(std::move(gameMode)), m_entityRegistry(entityRegistry), m_camera(std::move(cam)), m_renderer(std::make_unique<engine::MeshRenderer>()),
|
: Layer(keyboard, mouse), m_gameMode(std::move(gameMode)), m_entityRegistry(entityRegistry), m_camera(std::move(cam)), m_renderer(std::make_unique<engine::MeshRenderer>()),
|
||||||
m_pointLight(std::move(light)), m_boardLayout(std::move(boardModel)), m_piecePresenter(m_entityRegistry, std::move(pieceModdels), m_boardLayout),
|
m_pointLight(std::move(light)), m_boardLayout(std::move(boardModel)), m_piecePresenter(m_entityRegistry, std::move(pieceModdels), m_boardLayout),
|
||||||
m_pickingSystem(*m_camera), m_highlightSystem(*m_camera) {
|
m_pickingSystem(*m_camera), m_highlightSystem(*m_camera), m_animationSystem(m_entityRegistry) {
|
||||||
for (auto playerID : m_gameMode->getPlayerOrder()) {
|
for (auto playerID : m_gameMode->getPlayerOrder()) {
|
||||||
if (playerID != m_localPlayer) {
|
if (playerID != m_localPlayer) {
|
||||||
aiControllers.emplace_back(m_gameMode, playerID);
|
aiControllers.emplace_back(m_gameMode, playerID);
|
||||||
@ -58,12 +59,14 @@ private:
|
|||||||
std::string m_lastEventMessage;
|
std::string m_lastEventMessage;
|
||||||
|
|
||||||
std::vector<ludo::LudoAiController> aiControllers;
|
std::vector<ludo::LudoAiController> aiControllers;
|
||||||
|
engine::animation::AnimationSystem m_animationSystem;
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<engine::audio::SoundBuffer> m_soundBuffer;
|
std::unique_ptr<engine::audio::SoundBuffer> m_soundBuffer;
|
||||||
|
|
||||||
|
|
||||||
void renderHud();
|
void renderHud();
|
||||||
|
bool isAnimationBlocking();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -89,9 +89,10 @@ ludo::LudoGameMode::MoveResult ludo::LudoGameMode::movePieceInternal(int pieceIn
|
|||||||
|
|
||||||
void ludo::LudoGameMode::autoReleasePiece(int pieceIndex) {
|
void ludo::LudoGameMode::autoReleasePiece(int pieceIndex) {
|
||||||
auto result = movePieceInternal(pieceIndex, m_gameState.getDiceValue());
|
auto result = movePieceInternal(pieceIndex, m_gameState.getDiceValue());
|
||||||
m_pendingEvents.emplace_back(PieceMovedEvent{pieceIndex, result.fromPosition, result.toPosition, result.captured});
|
m_pendingEvents.emplace_back(PieceMovedEvent::create(pieceIndex, result.fromPosition, result.toPosition, result.captured, result.startState, result.targetState));
|
||||||
if (result.captured) {
|
if (result.captured) {
|
||||||
m_pendingEvents.emplace_back(PieceMovedEvent{result.capturedPieceIndex, result.toPosition, -1, false});
|
//Todo: Determine real toPosition Index dependent on home belegung
|
||||||
|
m_pendingEvents.emplace_back(PieceMovedEvent::create(result.capturedPieceIndex, result.fromPosition, -1, result.captured, result.startState, result.targetState));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +145,7 @@ void ludo::LudoGameMode::handle(const MovePieceCommand &command) {
|
|||||||
spdlog::info("MovePieceCommand akzeptiert: pieceIndex={}", command.pieceIndex);
|
spdlog::info("MovePieceCommand akzeptiert: pieceIndex={}", command.pieceIndex);
|
||||||
|
|
||||||
auto result = movePieceInternal(command.pieceIndex, m_gameState.m_diceValue);
|
auto result = movePieceInternal(command.pieceIndex, m_gameState.m_diceValue);
|
||||||
m_pendingEvents.emplace_back(PieceMovedEvent{command.pieceIndex, result.fromPosition, result.toPosition, result.captured});
|
m_pendingEvents.emplace_back(PieceMovedEvent{command.pieceIndex, result.fromPosition, result.toPosition, result.captured, result.targetState, result.startState});
|
||||||
if (result.captured) {
|
if (result.captured) {
|
||||||
spdlog::info("MovePieceCommand: gegnerische Figur auf {} geworfen", result.toPosition);
|
spdlog::info("MovePieceCommand: gegnerische Figur auf {} geworfen", result.toPosition);
|
||||||
m_pendingEvents.emplace_back(PieceMovedEvent{result.capturedPieceIndex, result.toPosition, -1, false});
|
m_pendingEvents.emplace_back(PieceMovedEvent{result.capturedPieceIndex, result.toPosition, -1, false});
|
||||||
@ -220,7 +221,69 @@ bool ludo::LudoGameMode::isBlockedByOwnPiece(PlayerColor owner, PieceState state
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int stateOrder(ludo::PieceState state) {
|
||||||
|
switch (state) {
|
||||||
|
case ludo::PieceState::AtHome: return 0;
|
||||||
|
case ludo::PieceState::OnTrack: return 1;
|
||||||
|
case ludo::PieceState::InHomeStretch: return 2;
|
||||||
|
case ludo::PieceState::Finished: return 3;
|
||||||
|
}
|
||||||
|
throw std::invalid_argument("computePath: unbekannter PieceState");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<ludo::PathNode> ludo::LudoGameMode::computePath(PlayerColor color, PieceState startingState, int startPosition, PieceState targetState, int targetPosition) {
|
std::vector<ludo::PathNode> ludo::LudoGameMode::computePath(PlayerColor color, PieceState startingState, int startPosition, PieceState targetState, int targetPosition) {
|
||||||
|
if (startingState == targetState && startPosition == targetPosition) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Nur Vorwärtsbewegungen sind erlaubt ---
|
||||||
|
if (stateOrder(targetState) < stateOrder(startingState)) {
|
||||||
|
throw std::invalid_argument(
|
||||||
|
"computePath: targetState liegt vor startingState (Rueckwaerts nicht unterstuetzt)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetState == PieceState::AtHome) {
|
||||||
|
throw std::invalid_argument(
|
||||||
|
"computePath: AtHome kann kein Zielzustand sein (ausser Start==Ziel)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startingState == PieceState::Finished) {
|
||||||
|
// hier nur erreichbar, wenn targetState/targetPosition abweicht (early return greift sonst)
|
||||||
|
throw std::invalid_argument(
|
||||||
|
"computePath: startingState ist bereits Finished, aber Ziel weicht ab");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startingState == PieceState::InHomeStretch && targetState == PieceState::InHomeStretch
|
||||||
|
&& targetPosition < startPosition) {
|
||||||
|
throw std::invalid_argument(
|
||||||
|
"computePath: targetPosition liegt in InHomeStretch vor startPosition");
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Positionsbereiche ---
|
||||||
|
if (targetState == PieceState::OnTrack
|
||||||
|
&& (targetPosition < 0 || targetPosition >= kTrackLength)) {
|
||||||
|
throw std::invalid_argument("computePath: targetPosition ausserhalb OnTrack-Bereich");
|
||||||
|
}
|
||||||
|
if (targetState == PieceState::InHomeStretch
|
||||||
|
&& (targetPosition < 0 || targetPosition >= kHomeStretchLength)) {
|
||||||
|
throw std::invalid_argument("computePath: targetPosition ausserhalb InHomeStretch-Bereich");
|
||||||
|
}
|
||||||
|
if (targetState == PieceState::Finished && targetPosition != kHomeStretchLength - 1) {
|
||||||
|
// <-- vermutlich dein aktueller Bug
|
||||||
|
throw std::invalid_argument(
|
||||||
|
"computePath: targetPosition fuer Finished muss kHomeStretchLength - 1 sein");
|
||||||
|
}
|
||||||
|
if (startingState == PieceState::OnTrack
|
||||||
|
&& (startPosition < 0 || startPosition >= kTrackLength)) {
|
||||||
|
throw std::invalid_argument("computePath: startPosition ausserhalb OnTrack-Bereich");
|
||||||
|
}
|
||||||
|
if (startingState == PieceState::InHomeStretch
|
||||||
|
&& (startPosition < 0 || startPosition >= kHomeStretchLength)) {
|
||||||
|
throw std::invalid_argument("computePath: startPosition ausserhalb InHomeStretch-Bereich");
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<PathNode> path;
|
std::vector<PathNode> path;
|
||||||
|
|
||||||
if (startPosition == targetPosition && startingState == targetState) return path;
|
if (startPosition == targetPosition && startingState == targetState) return path;
|
||||||
@ -230,7 +293,17 @@ std::vector<ludo::PathNode> ludo::LudoGameMode::computePath(PlayerColor color, P
|
|||||||
|
|
||||||
path.push_back({state, position});
|
path.push_back({state, position});
|
||||||
|
|
||||||
|
// Defense in depth: falls die Validierung oben eine Kombination übersieht
|
||||||
|
// (z.B. nach zukünftigen Erweiterungen), lieber laut abstürzen als RAM fressen.
|
||||||
|
const int maxSteps = kTrackLength + kHomeStretchLength + 4;
|
||||||
|
int steps = 0;
|
||||||
|
|
||||||
while (state != targetState || position != targetPosition) {
|
while (state != targetState || position != targetPosition) {
|
||||||
|
if (++steps > maxSteps) {
|
||||||
|
throw std::logic_error(
|
||||||
|
"computePath: Iterationslimit ueberschritten - unreachable Ziel trotz Validierung");
|
||||||
|
}
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PieceState::AtHome:
|
case PieceState::AtHome:
|
||||||
state = PieceState::OnTrack;
|
state = PieceState::OnTrack;
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <stdexcept>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
#include "game/TurnBasedGameMode.h"
|
#include "game/TurnBasedGameMode.h"
|
||||||
@ -66,7 +67,34 @@ namespace ludo {
|
|||||||
struct RollDiceCommand { engine::PlayerID player; };
|
struct RollDiceCommand { engine::PlayerID player; };
|
||||||
using LudoCommand = std::variant<MovePieceCommand, RollDiceCommand>;
|
using LudoCommand = std::variant<MovePieceCommand, RollDiceCommand>;
|
||||||
|
|
||||||
struct PieceMovedEvent { int pieceIndex; int fromPosition; int toPosition; bool captured; PieceState targetState; PieceState startState; };
|
struct PieceMovedEvent {
|
||||||
|
int pieceIndex;
|
||||||
|
int fromPosition;
|
||||||
|
int toPosition;
|
||||||
|
bool captured;
|
||||||
|
PieceState targetState;
|
||||||
|
PieceState startState;
|
||||||
|
|
||||||
|
static PieceMovedEvent create(int pieceIndex, int fromPosition, int toPosition,
|
||||||
|
bool captured, PieceState startState, PieceState targetState) {
|
||||||
|
validate(startState, fromPosition, targetState, toPosition, captured);
|
||||||
|
return PieceMovedEvent{pieceIndex, fromPosition, toPosition, captured, targetState, startState};
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void validate(PieceState startState, int fromPosition,
|
||||||
|
PieceState targetState, int toPosition, bool captured) {
|
||||||
|
if (captured && targetState != PieceState::AtHome) {
|
||||||
|
throw std::invalid_argument(
|
||||||
|
"PieceMovedEvent: captured==true erwartet targetState==AtHome");
|
||||||
|
}
|
||||||
|
if (!captured && targetState == PieceState::AtHome && startState != PieceState::AtHome) {
|
||||||
|
throw std::invalid_argument(
|
||||||
|
"PieceMovedEvent: targetState==AtHome ohne captured-Flag ist nicht vorgesehen");
|
||||||
|
}
|
||||||
|
// weitere Regeln nach Bedarf, z.B. Bereichschecks für fromPosition/toPosition
|
||||||
|
}
|
||||||
|
};
|
||||||
struct DiceRolledEvent { engine::PlayerID player; int diceValue; };
|
struct DiceRolledEvent { engine::PlayerID player; int diceValue; };
|
||||||
struct TurnChangedEvent {engine::PlayerID newPlayer; };
|
struct TurnChangedEvent {engine::PlayerID newPlayer; };
|
||||||
using LudoEvent = std::variant<PieceMovedEvent, DiceRolledEvent, TurnChangedEvent>;
|
using LudoEvent = std::variant<PieceMovedEvent, DiceRolledEvent, TurnChangedEvent>;
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "LudoGameMode.h"
|
#include "LudoGameMode.h"
|
||||||
|
#include "core/animation/components/BlockingAnimationComponent.h"
|
||||||
#include "core/animation/components/TransformAnimationComponent.h"
|
#include "core/animation/components/TransformAnimationComponent.h"
|
||||||
#include "ecs/standardComponents/MeshComponent.h"
|
#include "ecs/standardComponents/MeshComponent.h"
|
||||||
#include "ecs/standardComponents/PickableComponent.h"
|
#include "ecs/standardComponents/PickableComponent.h"
|
||||||
@ -30,8 +31,39 @@ void ludo::PiecePresenter::onPieceMoved(const ludo::PieceMovedEvent &event, cons
|
|||||||
const auto& piece = state.getPieces()[event.pieceIndex];
|
const auto& piece = state.getPieces()[event.pieceIndex];
|
||||||
auto target = m_layout.getWorldPosition(piece.color, piece.state, piece.position);
|
auto target = m_layout.getWorldPosition(piece.color, piece.state, piece.position);
|
||||||
auto entity = m_pieceEntities[event.pieceIndex];
|
auto entity = m_pieceEntities[event.pieceIndex];
|
||||||
auto& transform = m_registry.getComponent<engine::TransformComponent>(entity);
|
|
||||||
transform.m_position = target;
|
engine::animation::TransformAnimationComponent animationComponent;
|
||||||
|
std::vector<PathNode> path = LudoGameMode::computePath(piece.color, event.startState, event.fromPosition, event.targetState, event.toPosition);
|
||||||
|
std::vector<glm::vec3> pathPositions;
|
||||||
|
for (const auto& node : path) {
|
||||||
|
pathPositions.push_back(m_layout.getWorldPosition(piece.color, node.state, node.position));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<engine::animation::Keyframe<glm::vec3>> keyframes;
|
||||||
|
float time = 0;
|
||||||
|
for (const auto& position : pathPositions) {
|
||||||
|
keyframes.emplace_back(time, position);
|
||||||
|
time += 0.5f; // Todo: Check if this is in ms or s
|
||||||
|
}
|
||||||
|
|
||||||
|
engine::animation::AnimationTrack<glm::vec3> positionTrack;
|
||||||
|
engine::animation::AnimationTrack<glm::vec3> rotationTrack;
|
||||||
|
engine::animation::AnimationTrack<glm::vec3> scaleTrack;
|
||||||
|
|
||||||
|
positionTrack.keys = keyframes;
|
||||||
|
animationComponent.position = positionTrack;
|
||||||
|
animationComponent.rotation = rotationTrack;
|
||||||
|
animationComponent.scale = scaleTrack;
|
||||||
|
animationComponent.loop = false;
|
||||||
|
animationComponent.duration = time;
|
||||||
|
animationComponent.onFinished = [this, entity]() {
|
||||||
|
m_registry.removeComponent<engine::animation::BlockingAnimationComponent>(entity);
|
||||||
|
};
|
||||||
|
|
||||||
|
m_registry.addComponent<engine::animation::TransformAnimationComponent>(entity, animationComponent);
|
||||||
|
m_registry.addComponent<engine::animation::BlockingAnimationComponent>(entity, engine::animation::BlockingAnimationComponent());
|
||||||
|
// auto& transform = m_registry.getComponent<engine::TransformComponent>(entity);
|
||||||
|
// transform.m_position = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<int> ludo::PiecePresenter::getPieceIndex(std::optional<engine::Entity>::value_type entity) {
|
std::optional<int> ludo::PiecePresenter::getPieceIndex(std::optional<engine::Entity>::value_type entity) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user