Zappy GUI
C++ graphic client: renderer, camera, network
Loading...
Searching...
No Matches
MoveBehavior.cpp
Go to the documentation of this file.
1#include "MoveBehavior.hpp"
2
3#include <cmath>
4
6
7MoveBehavior::MoveBehavior(VisualState& visual, int fromX, int fromY, int toX, int toY, int mapW,
8 int mapH, float tileSize, float duration)
9 : _visual(visual), _duration(duration)
10{
11 _from = RenderingHelper::tileToWorld(fromX, fromY, mapW, mapH, tileSize);
12 _to = RenderingHelper::tileToWorld(toX, toY, mapW, mapH, tileSize);
13
14 // Wrap detected when tile distance exceeds 1 (only possible on a toroidal map)
15 int dx = abs(toX - fromX);
16 int dy = abs(toY - fromY);
17 _wraps = (dx > 1 || dy > 1);
18
19 if (_wraps) {
20 float halfW = mapW * tileSize / 2.0f;
21 float halfH = mapH * tileSize / 2.0f;
22
25
26 // Exit = world boundary in direction of travel, entry = opposite boundary
27 // dir > 0 means moving toward +boundary, dir < 0 toward -boundary
28 if (dx > 1) {
29 float dir = (toX < fromX) ? 1.0f : -1.0f;
30 _wrapExit.x = dir * halfW;
31 _wrapEntry.x = -dir * halfW;
32 }
33 if (dy > 1) {
34 float dir = (toY < fromY) ? 1.0f : -1.0f;
35 _wrapExit.z = dir * halfH;
36 _wrapEntry.z = -dir * halfH;
37 }
38
39 // Split duration proportionally: dist(from→exit) / total_dist
40 float d1 =
41 std::sqrt(std::pow(_wrapExit.x - _from.x, 2) + std::pow(_wrapExit.z - _from.z, 2));
42 float d2 = std::sqrt(std::pow(_to.x - _wrapEntry.x, 2) + std::pow(_to.z - _wrapEntry.z, 2));
43 float total = d1 + d2;
44 _splitT = (total > 0.0f) ? (d1 / total) : 0.5f;
45 }
46
48}
49
51{
52 _elapsed += dt;
53 float t = _elapsed / _duration;
54 if (t > 1.0f) t = 1.0f;
55
56 if (_wraps) {
57 if (t < _splitT) {
58 float s = _smoothstep(t / _splitT);
59 _visual.pos.x = _from.x + s * (_wrapExit.x - _from.x);
60 _visual.pos.y = 0.0f;
61 _visual.pos.z = _from.z + s * (_wrapExit.z - _from.z);
62 } else {
63 float s = _smoothstep((t - _splitT) / (1.0f - _splitT));
64 _visual.pos.x = _wrapEntry.x + s * (_to.x - _wrapEntry.x);
65 _visual.pos.y = 0.0f;
66 _visual.pos.z = _wrapEntry.z + s * (_to.z - _wrapEntry.z);
67 }
68 } else {
69 float s = _smoothstep(t);
70 _visual.pos.x = _from.x + s * (_to.x - _from.x);
71 _visual.pos.y = _from.y + s * (_to.y - _from.y);
72 _visual.pos.z = _from.z + s * (_to.z - _from.z);
73 }
74}
75
76bool MoveBehavior::isDone() const { return _elapsed >= _duration; }
77
79float MoveBehavior::_smoothstep(float t) { return t * t * (3.0f - 2.0f * t); }
MoveBehavior(VisualState &visual, int fromX, int fromY, int toX, int toY, int mapW, int mapH, float tileSize, float duration)
bool isDone() const override
Returns true when the behavior has completed and can be removed.
Vector3 _wrapExit
VisualState & _visual
static float _smoothstep(float t)
void update(float dt) override
Vector3 _wrapEntry
static Vector3 tileToWorld(int tileX, int tileY, int worldWidth, int worldHeight, float tileSize)
Converts tile coordinates to world coordinates (centered on tile).
Visual-only state for an entity, driven by behaviors each frame. Logical state (x,...