-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathSnake.cpp
More file actions
106 lines (85 loc) · 2.51 KB
/
Snake.cpp
File metadata and controls
106 lines (85 loc) · 2.51 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
#include <cstdlib>
#include "Snake.h"
#include "Food.h"
#include "SnakeScreen.h"
Snake::Snake(Screen *screen) : Object(screen) {
character = 'S';
}
Snake::~Snake() = default;
void Snake::initialize() {
isAlive = true;
position = getScreen()->getSize() / 2;
velocity = Pixel(1, 0);
trailSize = 1;
prevPositions.clear();
}
void Snake::update() {
prevPositions.insert(prevPositions.begin(), position);
while (prevPositions.size() > trailSize) {
prevPositions.pop_back();
}
if (isAlive) {
if (key(0x26)) { // UP
velocity = {0, -1};
} else if (key(0x28)) { // DOWN
velocity = {0, 1};
} else if (key(0x25)) { // LEFT
velocity = {-1, 0};
} else if (key(0x27)) { // RIGHT
velocity = {1, 0};
}
position += velocity;
// check for collisions with food - look at all objects at the snake's head
for (Object *object : getScreen()->objectsAtPixel(position)) {
// check if object is food
if (Food *food = dynamic_cast<Food *>(object)) {
grow();
food->goToRandomPosition();
}
// if object is the HUD, then we have a collision
if (dynamic_cast<HUD *>(object)) {
die();
}
}
// snake's head can't collide with body
for (const Pixel &prevPosition : prevPositions) {
if (position == prevPosition) {
die();
}
}
// neither coordinate (x or y) of snake's head can be below 0 or above screen width/height
if (!(position >= Pixel::zero && position < getScreen()->getSize())) {
die();
}
} else {
if (key('R')) {
restart();
}
}
}
Shape Snake::shape() {
Shape shape = Object::shape();
for (const Pixel &prevPosition : prevPositions) {
shape.push_back({prevPosition - position, '*'});
}
return shape;
}
// snake functions with callbacks to the screen
void Snake::grow() {
trailSize++;
if (auto snakeScreen = dynamic_cast<SnakeScreen *>(getScreen())) {
snakeScreen->setScore(snakeScreen->getScore() + 1);
}
}
void Snake::die() {
isAlive = false;
if (auto snakeScreen = dynamic_cast<SnakeScreen *>(getScreen())) {
snakeScreen->gameOver();
}
}
void Snake::restart() {
initialize();
if (auto snakeScreen = dynamic_cast<SnakeScreen *>(getScreen())) {
snakeScreen->restart();
}
}