-
Notifications
You must be signed in to change notification settings - Fork 1
/
Snake.pde
101 lines (92 loc) · 2.82 KB
/
Snake.pde
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
class Snake {
ArrayList<Line> segments;
float lastLineTime;
int segmentColour;
float segmentWidth;
int maxSegments;
int curSegments;
static final int SEGMENT_LENGTH = 12;
float speed;
PVector lastPlacedTail;
Snake() {
segments = new ArrayList<Line>();
lastPlacedTail = new PVector();
lastLineTime = 0;
segmentColour = color(255);
segmentWidth = 3f;
maxSegments = 5;
curSegments = 0;
speed = 10;
}
/**
* Considers adding a new segment by looking at the game state.
* Returns whether or not a new segment was added.
*/
public boolean addSegment() {
// Don't add new segment if we're at the max length
if (curSegments >= maxSegments) {
return false;
}
// Find the tail of the snake
Line curTail;
try {
curTail = segments.get(0);
}
catch (IndexOutOfBoundsException e) {
curTail = null;
}
Line newTail = null;
if (curTail != null) {
// If the snake hasn't travelled far enough since the last tail was placed, no new tail
if (!(dist(curTail.x0, curTail.y0, lastPlacedTail.x, lastPlacedTail.y) > SEGMENT_LENGTH)) {
return false;
}
// Create new tail segment, which will be in the same direction as the current tail
newTail = new Line(2 * curTail.x0 - curTail.x1,
2 * curTail.y0 - curTail.y1,
curTail.x0,
curTail.y0);
} else {
// If there is yet to be any snake, make the first segment where the pointer started
newTail = new Line(mouseX, mouseY, mouseX, mouseY);
}
lastPlacedTail.x = newTail.x0;
lastPlacedTail.y = newTail.y0;
segments.add(0, newTail);
curSegments++;
return true;
}
/**
* Renders the snake!
*/
public void render() {
for (Line l : snake.segments) {
l.render(segmentColour, segmentWidth);
}
}
/**
* Pulls every segment so the head is now at (x, y)
*/
public void updatePosition(PVector mousePosition) {
PVector curPosition = getHead();
PVector newPosition = new PVector(mousePosition.x - curPosition.x, mousePosition.y - curPosition.y).normalize().mult(speed).add(curPosition);
for (int i = segments.size() - 1; i >= 0; --i) {
Line segment = segments.get(i);
segment.x1 = newPosition.x;
segment.y1 = newPosition.y;
// Calculates the amount the "tail-end" of the segment has to move towards
// the new location of it's "head-end"
PVector u = new PVector(segment.x0 - newPosition.x, segment.y0 - newPosition.y);
u.normalize();
u.mult(SEGMENT_LENGTH);
segment.x0 = newPosition.x + u.x;
segment.y0 = newPosition.y + u.y;
newPosition.x = segment.x0;
newPosition.y = segment.y0;
}
}
public PVector getHead() {
Line head = segments.get(segments.size() - 1);
return new PVector(head.x1, head.y1);
}
}