ADD: Basic AnimationSystem

This commit is contained in:
sebastian 2026-02-14 15:37:05 +01:00
parent 40a6c2b048
commit e62f3ffacc
12 changed files with 199 additions and 4 deletions

View File

@ -192,6 +192,14 @@ add_executable(Dicewars_Siedler src/main.cpp
src/engine/renderer/components/WorldSpriteRenderingData.h
src/engine/renderer/shaders/WorldSpriteShader.cpp
src/engine/renderer/shaders/WorldSpriteShader.h
src/engine/core/animations/AnimationCurve.h
src/engine/core/animations/AnimationTrack.h
src/engine/core/animations/AnimationComponent.cpp
src/engine/core/animations/AnimationComponent.h
src/engine/core/animations/AnimationSystem.cpp
src/engine/core/animations/AnimationSystem.h
src/engine/core/EngineTime.cpp
src/engine/core/EngineTime.h
)
target_compile_options(Dicewars_Siedler PRIVATE

View File

@ -4,11 +4,19 @@
#include "Application.h"
#include "EngineTime.h"
#include "../layer/Layer.h"
#include "../platform/glfw/InputManager.h"
Application* Application::instance = nullptr;
void Application::updateTime() {
const auto now = static_cast<float>(glfwGetTime());
EngineTime::deltaTime = now - lastFrame;
EngineTime::totalTime += EngineTime::deltaTime;
lastFrame = now;
}
void Application::pushLayer(Layer* layer) {
layers.push_back(layer);
layer->onAttach();
@ -34,6 +42,7 @@ Application::~Application()
void Application::run() {
while (!window->shouldClose())
{
updateTime();
for (Layer* layer : layers)
{
layer->onUpdate();

View File

@ -34,6 +34,10 @@ private:
std::vector<Layer*> layers;
EventBus eventBus;
void updateTime();
float lastFrame;
protected:
void pushLayer(Layer* layer);
};

View File

@ -0,0 +1,8 @@
//
// Created by sebastian on 14.02.26.
//
#include "EngineTime.h"
float EngineTime::deltaTime = 0.0f;
float EngineTime::totalTime = 0.0f;

View File

@ -0,0 +1,16 @@
//
// Created by sebastian on 14.02.26.
//
#ifndef DICEWARS_SIEDLER_ENGINETIME_H
#define DICEWARS_SIEDLER_ENGINETIME_H
class EngineTime {
public:
static float deltaTime;
static float totalTime;
};
#endif //DICEWARS_SIEDLER_ENGINETIME_H

View File

@ -0,0 +1,5 @@
//
// Created by sebastian on 14.02.26.
//
#include "AnimationComponent.h"

View File

@ -0,0 +1,17 @@
//
// Created by sebastian on 14.02.26.
//
#ifndef DICEWARS_SIEDLER_ANIMATIONCOMPONENT_H
#define DICEWARS_SIEDLER_ANIMATIONCOMPONENT_H
#include "AnimationTrack.h"
#include "../ECS/Component.h"
class AnimationComponent : public Component {
public:
std::vector<AnimationTrack> tracks;
};
#endif //DICEWARS_SIEDLER_ANIMATIONCOMPONENT_H

View File

@ -0,0 +1,52 @@
//
// Created by sebastian on 14.02.26.
//
#ifndef DICEWARS_SIEDLER_ANIMATIONCURVE_H
#define DICEWARS_SIEDLER_ANIMATIONCURVE_H
#include <cmath>
enum class CurveType {
Sine,
Triangle,
SmoothStep,
EaseInOut,
Constant
};
struct AnimationCurve {
CurveType type = CurveType::Sine;
float amplitude = 1.0f;
float frequency = 1.0f;
float phase = 0.0f;
float offset = 0.0f;
float evaluate(float time) const {
float t = time * frequency + phase;
switch (type) {
case CurveType::Sine:
return offset + std::sin(t) * amplitude;
case CurveType::Triangle:
return offset + (2.0f * amplitude / M_PI) * std::asin(std::sin(t));
case CurveType::SmoothStep: {
float x = 0.5f + 0.5f * std::sin(t);
return offset + amplitude * (x * x * (3.0f - 2.0f * x));
}
case CurveType::EaseInOut: {
float x = 0.5f + 0.5f * std::sin(t);
return offset + amplitude * (1.0f - std::cos(x * M_PI));
}
case CurveType::Constant:
return offset;
}
return offset;
}
};
#endif //DICEWARS_SIEDLER_ANIMATIONCURVE_H

View File

@ -0,0 +1,17 @@
//
// Created by sebastian on 14.02.26.
//
#include "AnimationSystem.h"
#include "AnimationComponent.h"
void AnimationSystem::update(EntityManager &em, const float time) {
for (EntityID e : em.getAllEntities()) {
auto anim = em.getComponent<AnimationComponent>(e);
if (!anim) continue;
for (const auto& track : anim->tracks) {
track.update(time);
}
}
}

View File

@ -0,0 +1,16 @@
//
// Created by sebastian on 14.02.26.
//
#ifndef DICEWARS_SIEDLER_ANIMATIONSYSTEM_H
#define DICEWARS_SIEDLER_ANIMATIONSYSTEM_H
#include "../ECS/EntityManager.h"
class AnimationSystem {
public:
static void update(EntityManager& em, float time);
};
#endif //DICEWARS_SIEDLER_ANIMATIONSYSTEM_H

View File

@ -0,0 +1,26 @@
//
// Created by sebastian on 14.02.26.
//
#ifndef DICEWARS_SIEDLER_ANIMATIONTRACK_H
#define DICEWARS_SIEDLER_ANIMATIONTRACK_H
#include <cstdio>
#include <functional>
#include "AnimationCurve.h"
using AnimationTarget = std::function<void(float)>;
struct AnimationTrack {
AnimationCurve curve;
AnimationTarget target;
bool enabled = true;
void update(float time) const {
if (!enabled) return;
const float value = curve.evaluate(time);
target(value);
}
};
#endif //DICEWARS_SIEDLER_ANIMATIONTRACK_H

View File

@ -4,6 +4,9 @@
#include "GameLayer.h"
#include "../engine/core/EngineTime.h"
#include "../engine/core/animations/AnimationComponent.h"
#include "../engine/core/animations/AnimationSystem.h"
#include "../engine/core/ECS/ModelStateComponent.h"
#include "../engine/core/ECS/WorldSpriteComponent.h"
#include "../engine/platform/glfw/InputManager.h"
@ -59,9 +62,23 @@ void GameLayer::onAttach()
TransformComponent transformComponent(glm::vec3(0,0,0), glm::vec3(0), 1.0f);
testEntity = BuildingFactory::create(*entityManager, TemporaryBuildingDefinitionFactory::createForestHutDefinition(), transformComponent, 0, 0);
auto worldspriteComponent = WorldSpriteComponent();
worldspriteComponent.texture = std::make_shared<ModelTexture>(modelTexture);
entityManager->addComponent(testEntity, std::make_shared<WorldSpriteComponent>(worldspriteComponent));
auto worldSpritePtr = std::make_shared<WorldSpriteComponent>();
worldSpritePtr->texture = std::make_shared<ModelTexture>(modelTexture);
entityManager->addComponent(testEntity, worldSpritePtr);
auto anim = std::make_shared<AnimationComponent>();
float baseY = worldSpritePtr->offset.y;
anim->tracks.push_back({
AnimationCurve{CurveType::Sine, 0.3f, 5.f},
[worldSpritePtr, baseY](float v) {
worldSpritePtr->offset.y = baseY + v;
}
});
entityManager->addComponent(testEntity, anim);
events.subscribe<TurnChangedEvent>([this](const TurnChangedEvent& event) {
ProducingSystem::onTurnEnded(*entityManager);
@ -98,7 +115,7 @@ void GameLayer::onUpdate()
modelStateComponent->params["fillRatio"] += 0.1f;
}
AnimationSystem::update(*entityManager, EngineTime::totalTime);
camera->move(moveDir, 0.5f);
tileHighlightSystem->update(*entityManager, *mousePicker, *camera);
buildingPlacementSystem->update(*entityManager, *gameMode, 0, *turnState);