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
|
11
|
92 currRotation = (currRotation + (dir ? -1 : 1)) % 4;
|
|
93 newAngle = (float) ((currRotation * Math.PI) / 2.0f);
|
10
|
94 lerpRotation = new Interpolate(currAngle, newAngle, maxTime);
|
3
|
95 rotationChanged = true;
|
5
|
96 }
|
1
|
97
|
7
|
98 public Point2D getPointCoords(float x, float y, float dim, int index)
|
5
|
99 {
|
7
|
100 float ox = 0, oy = 0;
|
|
101 float step = dim / 10;
|
1
|
102
|
5
|
103 switch (index) {
|
|
104 case 0: ox = 3.0f; oy = 0.5f; break;
|
|
105 case 1: ox = 7.0f; oy = 0.5f; break;
|
|
106 case 2: ox = 9.5f; oy = 3.0f; break;
|
|
107 case 3: ox = 9.5f; oy = 7.0f; break;
|
|
108 case 4: ox = 7.0f; oy = 9.5f; break;
|
|
109 case 5: ox = 3.0f; oy = 9.5f; break;
|
|
110 case 6: ox = 0.5f; oy = 7.0f; break;
|
|
111 case 7: ox = 0.5f; oy = 3.0f; break;
|
1
|
112
|
5
|
113 case -1: ox = 5.0f; oy = 5.0f; break;
|
|
114 }
|
1
|
115
|
7
|
116 return new Point2D.Float(x + ox * step, y + oy * step);
|
5
|
117 }
|
1
|
118
|
9
|
119 public void setActiveConnection(int index)
|
|
120 {
|
|
121 active[index] = true;
|
|
122 activeChanged = true;
|
|
123 }
|
|
124
|
7
|
125 public void animate(float time)
|
5
|
126 {
|
|
127 if (rotationChanged)
|
|
128 {
|
|
129 rotationTime = time;
|
|
130 rotationActive = true;
|
7
|
131 rotationChanged = false;
|
5
|
132 }
|
1
|
133
|
5
|
134 if (rotationActive)
|
|
135 {
|
11
|
136 float t = (time - rotationTime) / 2;
|
|
137
|
9
|
138 if (t < maxTime)
|
7
|
139 currAngle = lerpRotation.getValue(t);
|
|
140 else
|
|
141 {
|
|
142 currAngle = newAngle;
|
|
143 rotationActive = false;
|
|
144 }
|
5
|
145 }
|
6
|
146
|
|
147 if (typeChanged)
|
|
148 {
|
|
149 typeTime = time;
|
|
150 typeActive = true;
|
7
|
151 typeChanged = false;
|
6
|
152 }
|
|
153
|
|
154 if (typeActive)
|
|
155 {
|
|
156 }
|
|
157
|
9
|
158 if (activeChanged)
|
|
159 {
|
|
160 }
|
|
161
|
|
162 throb = (time % 100) / 100.0f;
|
5
|
163 }
|
1
|
164
|
7
|
165 public void paint(Graphics2D g, float x, float y, float dim)
|
5
|
166 {
|
11
|
167 // AffineTransform tf = new AffineTransform();
|
|
168 g.rotate(currAngle, x + dim / 2.0f, y + dim / 2.0f);
|
|
169 // g.transform(tf);
|
|
170
|
|
171 if (type == PieceType.ACTIVE)
|
|
172 System.out.print("angle = " + currAngle + "\n");
|
1
|
173
|
5
|
174 switch (type) {
|
6
|
175 case LOCKED: g.setPaint(Color.green); break;
|
5
|
176 case ACTIVE: g.setPaint(Color.red); break;
|
|
177 case START: g.setPaint(Color.orange); break;
|
|
178 }
|
6
|
179
|
7
|
180 g.fill(new RoundRectangle2D.Float(x, y, dim, dim, dim / 10, dim / 10));
|
1
|
181
|
5
|
182 g.setPaint(Color.black);
|
|
183 g.setStroke(new BasicStroke(4.0f));
|
7
|
184 g.draw(new RoundRectangle2D.Float(x, y, dim, dim, dim / 10, dim / 10));
|
5
|
185
|
|
186 if (type == PieceType.START)
|
|
187 return;
|
|
188
|
6
|
189 if (type == PieceType.ACTIVE)
|
|
190 {
|
11
|
191 float offs1 = throb * 10.0f,
|
|
192 offs2 = throb * 20.0f;
|
|
193
|
7
|
194 g.setPaint(new Color(0.0f, 0.0f, 0.0f, (float) (1.0f - throb) ));
|
6
|
195 g.setStroke(new BasicStroke(2.0f + throb * 2.0f));
|
11
|
196 g.draw(new RoundRectangle2D.Float(x - offs1, y - offs1, dim + offs2, dim + offs2, dim / 10, dim / 10));
|
6
|
197 }
|
|
198
|
9
|
199 g.setPaint(Color.black);
|
5
|
200 g.setStroke(new BasicStroke(6.0f));
|
7
|
201 // CubicCurve2D c = new CubicCurve2D.Float();
|
|
202 QuadCurve2D c = new QuadCurve2D.Float();
|
9
|
203 boolean[] drawn = new boolean[numConnections];
|
|
204 for (int i = 0; i < numConnections; i++)
|
|
205 if (!drawn[i])
|
5
|
206 {
|
|
207 Point2D start, cp1, cp2, end;
|
9
|
208
|
6
|
209 start = getPointCoords(x, y, dim, i);
|
|
210 end = getPointCoords(x, y, dim, connections[i]);
|
|
211 cp1 = getPointCoords(x, y, dim, -1);
|
1
|
212
|
9
|
213 c.setCurve(start, cp1, end);
|
|
214 g.draw(c);
|
|
215
|
|
216 drawn[i] = true;
|
|
217 drawn[connections[i]] = true;
|
5
|
218 }
|
|
219 }
|
1
|
220 }
|