nsnake
Classic snake game for the terminal
Player.cpp
1 #include <Entities/Player.hpp>
2 #include <Entities/Board.hpp>
3 #include <Config/Globals.hpp>
4 
5 Player::Player(int x, int y):
6  alive(true),
7  currentDirection(Player::RIGHT),
8  nextDirection(Player::RIGHT)
9 {
10  // The Snake's head
11  this->body.push_back(Body(x, y));
12 
13  // Initializing the snake with 2 body pieces
14  // (plus the head)
15  this->body.push_back(Body(x - 1, y));
16  this->body.push_back(Body(x - 1, y));
17 }
18 bool Player::isAlive()
19 {
20  return (this->alive);
21 }
22 int Player::getSize()
23 {
24  return (int)(this->body.size());
25 }
27 {
28  return (this->body.front().x);
29 }
31 {
32  return (this->body.front().y);
33 }
34 void Player::moveTo(int x, int y)
35 {
36  this->body.front().x = x;
37  this->body.front().y = y;
38 }
39 void Player::move(Direction dir)
40 {
41  this->nextDirection = dir;
42 }
43 void Player::kill()
44 {
45  this->alive = false;
46 }
47 void Player::update(Board* board)
48 {
49  // We have to make sure the snake doesn't do strange
50  // things, like turning around on itself.
51  switch(this->nextDirection)
52  {
53  case Player::RIGHT:
54  if (this->currentDirection != Player::LEFT)
55  this->currentDirection = this->nextDirection;
56  break;
57 
58  case Player::LEFT:
59  if (this->currentDirection != Player::RIGHT)
60  this->currentDirection = this->nextDirection;
61  break;
62 
63  case Player::UP:
64  if (this->currentDirection != Player::DOWN)
65  this->currentDirection = this->nextDirection;
66  break;
67 
68  case Player::DOWN:
69  if (this->currentDirection != Player::UP)
70  this->currentDirection = this->nextDirection;
71  break;
72  };
73 
74  // Making the rest of the body catch up
75  for (unsigned int i = (this->body.size() - 1); i > 0; i--)
76  {
77  this->body[i].x = this->body[i - 1].x;
78  this->body[i].y = this->body[i - 1].y;
79  }
80 
81  // Moving the head
82  switch(this->currentDirection)
83  {
84  case Player::RIGHT:
85  this->body.front().x++;
86  break;
87 
88  case Player::LEFT:
89  this->body.front().x--;
90  break;
91  case Player::UP:
92  this->body.front().y--;
93  break;
94 
95  case Player::DOWN:
96  this->body.front().y++;
97  break;
98  }
99 
100  // Checking if the player hit the board's extremes.
101  //
102  // @warning `teleport` may change player's X and Y!
103  if (board->isBorder(this->body.front().x,
104  this->body.front().y))
105  {
106  if (board->style == Board::TELEPORT)
107  board->teleport(this);
108  else
109  this->kill();
110  }
111 
112  int headx = this->body.front().x;
113  int heady = this->body.front().y;
114 
115  // Checking if the head hits the body
116  if (this->bodyHit(headx, heady, true))
117  this->kill();
118 
119  // Checking for collisions on the board
120  if (board->isWall(headx, heady))
121  this->kill();
122 }
123 void Player::draw(Window* win)
124 {
125  // The body
126  for (unsigned int i = 1; i < (this->body.size()); i++)
127  win->printChar('o',
128  this->body[i].x,
129  this->body[i].y,
130  Globals::Theme::player_body);
131 
132  // The head
133  win->printChar(((this->alive) ?
134  '@' :
135  'X'),
136  this->body.front().x,
137  this->body.front().y,
138  ((this->alive) ?
139  Globals::Theme::player_head :
140  Globals::Theme::player_head_dead));
141 }
142 bool Player::headHit(int x, int y)
143 {
144  return ((this->body.front().x == x) &&
145  (this->body.front().y == y));
146 }
147 bool Player::bodyHit(int x, int y, bool isCheckingHead)
148 {
149  int initial = 0;
150  if (isCheckingHead) initial = 3;
151 
152  for (unsigned int i = initial; i < (this->body.size()); i++)
153  if ((this->body[i].x == x) &&
154  (this->body[i].y == y))
155  return true;
156 
157  return false;
158 }
159 void Player::increase()
160 {
161  int lastx = this->body.back().x;
162  int lasty = this->body.back().y;
163 
164  this->body.push_back(Body(lastx, lasty));
165 }
166 
Definition: Player.hpp:8
Style style
Tells if the player will teleport when reaching the Board's limits or not.
Definition: Board.hpp:90
A level where the snake runs and eats fruits.
Definition: Board.hpp:32
bool isWall(int x, int y)
Tells if there's a wall at #x #y.
Definition: Board.cpp:36
void teleport(Player *player)
Makes the Player teleport if it's on a border.
Definition: Board.cpp:95
int getX()
Returns the head's x position.
Definition: Player.cpp:26
bool bodyHit(int x, int y, bool isCheckingHead=false)
Tells if something at #x and #y collides with any part of the snake.
Definition: Player.cpp:147
int getY()
Returns the head's y position.
Definition: Player.cpp:30