-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSnake.java
More file actions
249 lines (216 loc) · 7.03 KB
/
Snake.java
File metadata and controls
249 lines (216 loc) · 7.03 KB
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
import java.util.ArrayList;
import java.util.Random;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JPanel;
public class Snake {
//private ArrayList<GraphicsItem> allItems;
private ArrayList<SnakePart> snakeBody;
private SnakePart snakeHead;
private Direction direction;
private SnakeAction action;
// int partHeight, partWidth;
private Rat rat;
// DEBUG
// private int collisions;
// borders
private Rectangle2D.Double borders;
public Snake() {
// default length with 6 parts
// head + 5 parts
this(Config.defaultLength);
}
// with specific parts
public Snake(int length) {
// FIXME: lower/higher bounds for parts number
// list of parts
snakeBody = new ArrayList<SnakePart>();
//allItems = new ArrayList<GraphicsItem>();
// set defult direction
direction = Direction.UP;
// add head
snakeHead = new SnakePart("art/snake_head.png");
addPart(snakeHead);
for(int i=0; i < length; i++)
addNormalPart();
// DEBUG
// collisions = 0;
// System.out.println(snakeHead.getWidth());
// System.out.println(snakeHead.getHeight());
}
public void setRat(Rat r)
{
rat = r;
}
public void setSnakeActionListener(SnakeAction act)
{
action = act;
}
//public void setBorders(HashMap<Direction, Rectangle2D.Double> b)
public void setBorders(Rectangle2D.Double rect)
{
borders = rect;
}
// add a given part at any direction (condition)
// FIXME: add part when stepping have error
public void addPart(SnakePart part) {
// add part after the last one
if(part == null) return;
if(direction == null) direction = Direction.UP;
int size = snakeBody.size();
double lastX = 0, lastY = 0;
SnakePart lastPart = null;
if (size > 0) {
lastPart = snakeBody.get(snakeBody.size() - 1);
lastX = lastPart.getX();
lastY = lastPart.getY();
}
// move to the last coordinates
part.moveTo(lastX , lastY);
// place the part at the right location
// no last part so step with step value of 0
// for both vertical or horizontal step
// then reset last direction
if(lastPart == null) {
// set default direction reverse
part.setDirection(reverseDirection(direction));
part.step(0, 0);
part.setDirection(direction);
}
else {
// set direction to reverse to add to last
part.setDirection(reverseDirection(lastPart.getDirection()));
part.step();
part.setDirection(lastPart.getDirection());
}
// add to his borthers :D
snakeBody.add(part);
// debug
//System.out.println("Part Added at: " + part.getX() + ", " + part.getY());
//System.out.println("Direction: " + part.getDirection());
}
// add a normal snake part
public void addNormalPart() {
addPart(new SnakePart());
}
public ArrayList<SnakePart> parts() {
return snakeBody;
}
public void setDirection(Direction dir) {
direction = dir;
}
public Direction getDirection() {
return direction;
}
// the whole snake step
// FIXME:
// don't move a parts in the reverse direction
// (means in the direction of it's previous one)
public void step() {
// move the head
// then every part will replace the next part's place
double nextX = snakeHead.getX(), nextY = snakeHead.getY();
// get the curren direction of head
// and it will be the next direction to others
Direction nextDirection = snakeHead.getDirection(), currentDirection;
// set the new head direction
// which is the whole snake direction
//System.out.println(nextDirection);
snakeHead.setDirection(direction);
// move the head
snakeHead.step();
// follow the head
for(int i = 1; i < snakeBody.size(); i++) {
// FIXME:
// test for collision by the way?
SnakePart nextPart = snakeBody.get(i);
// store the current direction
currentDirection = nextPart.getDirection();
// set the next direction
nextPart.setDirection(nextDirection);
// move to that direction
nextPart.step();
// and reset the next to current
// so the next direction will directed to teh current
nextDirection = currentDirection;
}
checkCollisions();
}
public void checkCollisions() {
// check collision and call a something
// or make an Event derived class to do so
// TODO: how to define own events?
// collisionCallback();
if(action == null)
return;
//test
if(snakeHead.collidesWith(rat))
action.snakeHitsRat();
//TODO: callback for slef and rat collision
// test collision with itself and borders
// FIXME: test collide with again
// head collides with others already
// its previous part has the same coordinates
for(int i = 1; i < snakeBody.size(); i++)
if(snakeHead.collidesWith(snakeBody.get(i)))
action.snakeHitsItself();
if(!borders.contains(snakeHead.getBounds()))
action.snakeHitsBorders();
for(SnakePart part: snakeBody) {
if(part == snakeHead)
continue;
if(borders.contains(part.getBounds()))
action.partOutOfBorders(part);
}
/*
Iterator<Direction> borderIterator = borders.keySet().iterator();
while(borderIterator.hasNext())
{
Direction d = borderIterator.next();
if(snakeHead.intersects(borders.get(d)))
{
//System.out.println(d);
action.snakeHitsBorderAt(d);
}
}
*/
}
public Direction reverseDirection(Direction dir) {
Direction d = Direction.DOWN;
switch(dir) {
case UP:
d = Direction.DOWN;
break;
case DOWN:
d = Direction.UP;
break;
case LEFT:
d = Direction.RIGHT;
break;
case RIGHT:
d = Direction.LEFT;
break;
}
return d;
}
// move the whole snake
public void moveTo(double x, double y) {
for(SnakePart part: snakeBody) {
part.moveTo(x + part.getX(), y + part.getY());
}
}
public void draw(Graphics2D g2d)
{
for(SnakePart part: snakeBody) {
part.draw(g2d);
}
}
public void redraw()
{
for(SnakePart part: snakeBody) {
part.redraw();
}
}
}