I'm trying to make a snake game using the u8g lib. But for now, only the second body part of the snake follows the head, where I want the whole body to follow the snake's head and I don't understand why it doesn't work. Here is the code:
#include "U8glib.h"
U8GLIB_PCD8544 u8g(13, 11, 10, 9, 8); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8
const int SNAKEMAXSIZE = 10;
bool title = true;
bool gameRunning = false;
enum direction {HAUT, BAS, GAUCHE, DROITE};
int snakeDirection = GAUCHE;
class snakeCell
{
private:
int x;
int y;
public:
snakeCell(int x, int y)
{
this->x = x;
this->y = y;
}
snakeCell()
{
x = 42;
y = 24;
}
void setX(int x)
{
this->x = x;
}
void setY(int y)
{
this->y = y;
}
int getX()
{
return x;
}
int getY()
{
return y;
}
void draw()
{
u8g.drawBox(x, y, 5,5);
}
};
class Pomme
{
public:
int x;
int y;
Pomme(int x, int y)
{
this->x = x;
this->y = y;
}
Pomme()
{
x = 42;
y = 24;
}
void randomSpawn()
{
x = random(48);
y = random(84);
}
void draw()
{
u8g.drawCircle(x, y, 5);
}
};
snakeCell snake[10] = {snakeCell(), snakeCell(47,24), snakeCell(52,24), snakeCell(57,24), snakeCell(62,24), snakeCell(62,29), snakeCell(62,34), snakeCell(57,34), snakeCell(52,34), snakeCell(52,39)};
Pomme pomme = Pomme();
void draw(void) {
// graphic commands to redraw the complete screen should be placed here
u8g.setFont(u8g_font_6x13);
//u8g.setFont(u8g_font_osb21);
u8g.drawRFrame(0, 0, 84, 48, 0); //Screen frame
printTitle();
game();
}
void setup(void) {
// flip screen, if required
//u8g.setRot180();
// set SPI backup if required
//u8g.setHardwareBackup(u8g_backup_avr_spi);
// assign default color value
randomSeed(analogRead(0));
if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
u8g.setColorIndex(255); // white
}
else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
u8g.setColorIndex(3); // max intensity
}
else if ( u8g.getMode() == U8G_MODE_BW ) {
u8g.setColorIndex(1); // pixel on
}
else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
u8g.setHiColorByRGB(255,255,255);
}
}
void loop(void) {
// picture loop
u8g.firstPage();
do {
draw();
} while( u8g.nextPage() );
// rebuild the picture after some delay
delay(50);
}
void printTitle()
{
if(title == true)
{
u8g.setFont(u8g_font_6x13);
//u8g.drawStr( 26, 30, "SNAKE");
delay(2000);
title = false;
gameRunning = true;
}
}
void moveSnake()
{
//move head accordingly to movement
if(snakeDirection == GAUCHE)
{
snake[0].setX(snake[0].getX() - 1);
}
else if(snakeDirection == DROITE)
{
snake[0].setX(snake[0].getX() + 1);
}
else if(snakeDirection == BAS)
{
snake[0].setY(snake[0].getY() + 1);
}
else if(snakeDirection == HAUT)
{
snake[0].setY(snake[0].getY() - 1);
}
//tail follow head
for(int i = 9; i > 0; i--)
{
snake[i] = snakeCell(snake[i-1].getX(),snake[i-1].getY());
}
delay(100);
}
void restart()
{
//snakeCell snake[10] = {snakeCell(), snakeCell(47,24), snakeCell(52,24), snakeCell(57,24), snakeCell(62,24), snakeCell(62,29), snakeCell(62,34), snakeCell(57,34), snakeCell(52,34), snakeCell(47,34)};
}
void drawSnake()
{
for(int i = 0; i < SNAKEMAXSIZE; i++)
{
snake[i].draw();
}
}
void spawnApple()
{
pomme = Pomme();
pomme.randomSpawn();
}
void checkCollision()
{
// detect if apple eaten
for(int i = 0; i < SNAKEMAXSIZE; i++)
{
if((snake[i].getX() == pomme.x) && (snake[i].getY() == pomme.y))
{
pomme.randomSpawn();
}
}
// detect if snake hit wall
for(int i = 0; i < SNAKEMAXSIZE; i++)
{
if((snake[i].getX() >= 84) || (snake[i].getX() <= 0) || (snake[i].getY() >= 48) || (snake[i].getY() <= 0))
{
//gameOver();
restart();
}
}
}
void gameOver()
{
gameRunning = false;
//u8g.setFont(u8g_font_6x13);
//u8g.drawStr( 14, 30, "GAME OVER");
//delay(1000);
restart();
gameRunning = true;
}
void game()
{
if(gameRunning == true)
{
checkCollision();
moveSnake();
drawSnake();
}
}
Thanks in advance.