1
|
1 /*
|
|
2 * Ristipolku
|
|
3 * (C) Copyright 2011 Matti 'ccr' Hämäläinen <ccr@tnsp.org>
|
|
4 */
|
|
5 package game;
|
|
6
|
|
7 import java.awt.*;
|
7
|
8 import java.awt.geom.*;
|
1
|
9 import java.util.*;
|
6
|
10 import java.math.*;
|
1
|
11
|
|
12
|
|
13 public class Piece
|
|
14 {
|
3
|
15 static final int numConnections = 8;
|
9
|
16 static final float maxTime = 50.0f;
|
|
17
|
3
|
18 int currRotation;
|
|
19 int[] connections;
|
9
|
20 boolean[] active;
|
3
|
21 PieceType type, oldType;
|
1
|
22
|
3
|
23 boolean rotationChanged, rotationActive,
|
9
|
24 typeChanged, typeActive,
|
|
25 activeChanged, activeActive;
|
7
|
26 float currAngle, newAngle, rotationTime, typeTime;
|
|
27 float throb;
|
6
|
28
|
7
|
29 Interpolate lerpRotation;
|
1
|
30
|
3
|
31 public Piece(PieceType ptype)
|
|
32 {
|
|
33 // Initialize
|
|
34 connections = new int[numConnections];
|
9
|
35 active = new boolean[numConnections];
|
3
|
36 type = ptype;
|
1
|
37
|
3
|
38 rotationChanged = false;
|
6
|
39 rotationActive = false;
|
|
40 currRotation = 0;
|
|
41 currAngle = 0;
|
|
42
|
3
|
43 typeChanged = false;
|
|
44 typeActive = false;
|
1
|
45
|
6
|
46 throb = 0;
|
1
|
47
|
|
48
|
3
|
49 // Initialize connections between endpoints of the paths inside the piece
|
|
50 for (int i = 0; i < numConnections; i++)
|
|
51 connections[i] = -1;
|
1
|
52
|
6
|
53 // Randomize connections in the piece
|
3
|
54 Random rnd = new Random();
|
|
55 for (int i = 0; i < numConnections; i++)
|
|
56 {
|
|
57 while (connections[i] < 0)
|
|
58 {
|
|
59 int tmp = rnd.nextInt(numConnections);
|
|
60 if (connections[tmp] < 0)
|
|
61 {
|
|
62 connections[i] = tmp;
|
|
63 connections[tmp] = i;
|
|
64 }
|
|
65 }
|
|
66 }
|
|
67 }
|
|
68
|
|
69 public Piece()
|
|
70 {
|
|
71 this(PieceType.NONE);
|
|
72 }
|
1
|
73
|
3
|
74 public void setType(PieceType ptype)
|
|
75 {
|
|
76 typeChanged = (oldType != ptype);
|
|
77 oldType = type;
|
|
78 type = ptype;
|
|
79 }
|
1
|
80
|
3
|
81 public int getConnection(int in)
|
|
82 {
|
|
83 return connections[in];
|
|
84 }
|
5
|
85
|
3
|
86 public void rotate(boolean dir)
|
|
87 {
|
6
|
88 // Only normal
|
|
89 if (type != PieceType.LOCKED && type != PieceType.ACTIVE)
|
3
|
90 return;
|
1
|
91
|
9
|
92 currRotation = currRotation + (dir ? -1 : 1);
|
|
93 newAngle = (float) (currRotation * Math.PI) / 2.0f;
|
1
|
94
|
10
|
95 lerpRotation = new Interpolate(currAngle, newAngle, maxTime);
|
3
|
96 rotationChanged = true;
|
5
|
97 }
|
1
|
98
|
7
|
99 public Point2D getPointCoords(float x, float y, float dim, int index)
|
5
|
100 {
|
7
|
101 float ox = 0, oy = 0;
|
|
102 float step = dim / 10;
|
1
|
103
|
5
|
104 switch (index) {
|
|
105 case 0: ox = 3.0f; oy = 0.5f; break;
|
|
106 case 1: ox = 7.0f; oy = 0.5f; break;
|
|
107 case 2: ox = 9.5f; oy = 3.0f; break;
|
|
108 case 3: ox = 9.5f; oy = 7.0f; break;
|
|
109 case 4: ox = 7.0f; oy = 9.5f; break;
|
|
110 case 5: ox = 3.0f; oy = 9.5f; break;
|
|
111 case 6: ox = 0.5f; oy = 7.0f; break;
|
|
112 case 7: ox = 0.5f; oy = 3.0f; break;
|
1
|
113
|
5
|
114 case -1: ox = 5.0f; oy = 5.0f; break;
|
|
115 }
|
1
|
116
|
7
|
117 return new Point2D.Float(x + ox * step, y + oy * step);
|
5
|
118 }
|
1
|
119
|
9
|
120 public void setActiveConnection(int index)
|
|
121 {
|
|
122 active[index] = true;
|
|
123 activeChanged = true;
|
|
124 }
|
|
125
|
7
|
126 public void animate(float time)
|
5
|
127 {
|
|
128 if (rotationChanged)
|
|
129 {
|
|
130 rotationTime = time;
|
|
131 rotationActive = true;
|
7
|
132 rotationChanged = false;
|
5
|
133 }
|
1
|
134
|
5
|
135 if (rotationActive)
|
|
136 {
|
9
|
137 float t = (time - rotationTime);
|
6
|
138
|
9
|
139 if (t < maxTime)
|
7
|
140 currAngle = lerpRotation.getValue(t);
|
|
141 else
|
|
142 {
|
|
143 currAngle = newAngle;
|
|
144 rotationActive = false;
|
|
145 }
|
5
|
146 }
|
6
|
147
|
|
148 if (typeChanged)
|
|
149 {
|
|
150 typeTime = time;
|
|
151 typeActive = true;
|
7
|
152 typeChanged = false;
|
6
|
153 }
|
|
154
|
|
155 if (typeActive)
|
|
156 {
|
|
157 }
|
|
158
|
9
|
159 if (activeChanged)
|
|
160 {
|
|
161 }
|
|
162
|
|
163 throb = (time % 100) / 100.0f;
|
5
|
164 }
|
1
|
165
|
7
|
166 public void paint(Graphics2D g, float x, float y, float dim)
|
5
|
167 {
|
|
168 AffineTransform tf = new AffineTransform();
|
6
|
169 tf.rotate(currAngle, x + dim / 2.0f, y + dim / 2.0f);
|
5
|
170 g.transform(tf);
|
1
|
171
|
5
|
172 switch (type) {
|
6
|
173 case LOCKED: g.setPaint(Color.green); break;
|
5
|
174 case ACTIVE: g.setPaint(Color.red); break;
|
|
175 case START: g.setPaint(Color.orange); break;
|
|
176 }
|
6
|
177
|
7
|
178 g.fill(new RoundRectangle2D.Float(x, y, dim, dim, dim / 10, dim / 10));
|
1
|
179
|
5
|
180 g.setPaint(Color.black);
|
|
181 g.setStroke(new BasicStroke(4.0f));
|
7
|
182 g.draw(new RoundRectangle2D.Float(x, y, dim, dim, dim / 10, dim / 10));
|
5
|
183
|
|
184 if (type == PieceType.START)
|
|
185 return;
|
|
186
|
6
|
187 if (type == PieceType.ACTIVE)
|
|
188 {
|
7
|
189 g.setPaint(new Color(0.0f, 0.0f, 0.0f, (float) (1.0f - throb) ));
|
6
|
190 g.setStroke(new BasicStroke(2.0f + throb * 2.0f));
|
7
|
191 g.draw(new RoundRectangle2D.Float(x - throb * 10.0f, y - throb * 10.0f, dim + throb * 20.0f, dim + throb * 20.0f, dim / 10, dim / 10));
|
6
|
192 }
|
|
193
|
9
|
194 g.setPaint(Color.black);
|
5
|
195 g.setStroke(new BasicStroke(6.0f));
|
7
|
196 // CubicCurve2D c = new CubicCurve2D.Float();
|
|
197 QuadCurve2D c = new QuadCurve2D.Float();
|
9
|
198 boolean[] drawn = new boolean[numConnections];
|
|
199 for (int i = 0; i < numConnections; i++)
|
|
200 if (!drawn[i])
|
5
|
201 {
|
|
202 Point2D start, cp1, cp2, end;
|
9
|
203
|
6
|
204 start = getPointCoords(x, y, dim, i);
|
|
205 end = getPointCoords(x, y, dim, connections[i]);
|
|
206 cp1 = getPointCoords(x, y, dim, -1);
|
1
|
207
|
9
|
208 c.setCurve(start, cp1, end);
|
|
209 g.draw(c);
|
|
210
|
|
211 drawn[i] = true;
|
|
212 drawn[connections[i]] = true;
|
5
|
213 }
|
|
214 }
|
1
|
215 }
|