1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
package ch.asynk.gdx.boardgame.animations;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.utils.Pool;
import com.badlogic.gdx.math.Vector3;
import ch.asynk.gdx.boardgame.Piece;
import ch.asynk.gdx.boardgame.Path;
public class MoveAnimation implements Animation, Pool.Poolable
{
@FunctionalInterface
public interface MoveAnimationCb
{
void onTileChange(Piece piece, Path path);
}
private static final Pool<MoveAnimation> moveAnimationPool = new Pool<MoveAnimation>()
{
@Override protected MoveAnimation newObject()
{
return new MoveAnimation();
}
};
public static MoveAnimation obtain(Piece piece, Path path, float speed, Sound snd, MoveAnimationCb cb)
{
MoveAnimation a = moveAnimationPool.obtain();
a.piece = piece;
a.path = path;
a.speed = speed;
a.snd = snd;
a.cb = cb;
a.init();
return a;
}
private Piece piece;
private Path path;
private MoveAnimationCb cb;
private float speed;
private float dp;
private float percent;
private boolean notify;
private Vector3 dst = new Vector3();
private Vector3 dt = new Vector3();
private Sound snd;
private MoveAnimation()
{
}
private void init()
{
path.iterator();
setNextMove();
percent = 0f;
dp = 1f * speed;
}
private boolean setNextMove()
{
boolean done = path.nextPosition(piece, dst);
float dr = (dst.z - piece.getRotation());
if (dr > 180) {
dr -= 360;
} else if (dr < -180) {
dr += 360;
}
dt.set(
(dst.x - piece.getX()) * speed,
(dst.y - piece.getY()) * speed,
(dr) * speed
);
notify = (dr == 0 ? (cb != null) : false);
return done;
}
@Override public void reset()
{
this.path = null;
this.piece = null;
this.dst.set(0, 0, 0);
}
@Override public void dispose()
{
moveAnimationPool.free(this);
}
@Override public boolean completed()
{
return (percent >= 1f);
}
@Override public boolean animate(float delta)
{
if (percent == 0f) {
if (snd != null) {
snd.loop();
}
if (notify) {
cb.onTileChange(piece, path);
notify = false;
}
}
piece.translate(dt.x * delta, dt.y * delta);
piece.rotate(dt.z * delta);
percent += (dp * delta);
if (notify && percent >= 0.5f) {
cb.onTileChange(piece, path);
notify = false;
}
if (percent >= 1f) {
piece.setPosition(dst.x, dst.y, dst.z);
if (!setNextMove()) {
percent = 0.0001f;
} else if (notify) {
cb.onTileChange(piece, path);
notify = false;
}
}
if (percent >= 1f) {
if (snd != null) {
snd.stop();
}
return true;
}
return false;
}
}
|