Important update: Arm Announces End of Life Timeline for Mbed. This site will be archived in July 2026. Read the full announcement.
Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
Snake Game, Snake not working as intended.
Topic last updated 27 Apr 2016, by
Pak Yue Leung.
1 reply
Pak Yue Leung.
1 reply
I'm trying to make a simple snake game, on FRDM-k64F.
Everything works fine, the snake moves, it grows if a food's eaten or i press a button (to simulate food eaten, for debugging).
Except, all the snake tail section changes direction everytime I change the snake head direction.
I know that's my code's problem, I identified it, but I couldn't get a way to write my code correctly.
Any suggestions?
<<code title=SnakeGame>>
#include "mbed.h"
#include "N5110.h"
#include "SNAKELIB.h"
// VCC, SCE, RST, D/C, MOSI, SCLK, LED
N5110 lcd (PTE26 , PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3);
Ticker SnakeSpeed;
//Variables
int FoodPattern[3][3] = {{1,0,1},{0,1,0},{1,0,1}};
int SnakeHead[4][3] = {{1,1,1},{1,1,1},{1,1,1},{0,1,1}}; //Snake head template
int SnakeTail[4][3] = {{0,0,1},{0,1,1},{1,1,1},{0,1,1}}; //Snake tail template
int RandX, RandY; //Random food coordinate
int x, y; //The SnakeHead 1st pixel, max (19,10) because it's 4 blocks(and 2 blank pixel space)
int tailX[100], tailY[100], SnakeLength; //The SnakeTail pixel, max (19,10) (same above)
int prevX, prevY; //Store Previous Snake Tail X,Y status
int prev2X, prev2Y; //Store Previous Previous Snake Tail X,Y
//Functions
void RandFoodCoordinate(); //Randomize the food coordinate
void SetFoodCoordinate(); //Set the food coordinate
void SetSnakeHead();
void SetSnakeTail();
void SnakeMoving();
void DrawBorders(); //Draw the outline border.
void MainGame(); //This is the game function which's called every ticker time
void InitSnakeTail();
//Declarations
void RandFoodCoordinate()
{
RandX = rand()%19; //randomize a number between 0-18, i.e. max x coordinate = 76
RandY = rand()%10; //randomize a number between 0-9, i.e. max y coordinate = 40
}
void SetFoodCoordinate()
{
for (int a = 0; a < 3; a++){
for (int b = 0; b < 3; b++){
if (FoodPattern[a][b] == 1){
//The +2 is to make sure the food would not spawn in the border. Maximum (x,y)of food is (78,42)
//and the last pixel of food would be (80,44) [[maybe i could make it 83,47 later. need testing]]
lcd.setPixel(4*RandX+a+2,4*RandY+b+2);
}
}
}
}
void SetSnakeHead()
{
if (snakedirection == right){
for (int c = 0; c < 4; c++){
for (int d = 0; d < 3; d++){
if (SnakeHead[c][d] == 1){
lcd.setPixel(4*x+c+1,4*y+d+2); //The +1, +2 is just to align the pixel with the food correctly
}
}
}
}
else if (snakedirection == left){
for (int c = 0; c < 4; c++){
for (int d = 0; d < 3; d++){
if (SnakeHead[c][d] == 1){
lcd.setPixel(4*x-c+5,4*y+d+2); //The +5, +2 is to align the pixel with food correctly
}
}
}
}
else if (snakedirection == up){
for (int c = 0; c < 4; c++){
for (int d = 0; d < 3; d++){
if (SnakeHead[c][d] == 1){
lcd.setPixel(4*x+d+2,4*y-c+6); //+2, +6 is to align pixel with food
}
}
}
}
else if (snakedirection == down){
for (int c = 0; c < 4; c++){
for (int d = 0; d < 3; d++){
if (SnakeHead[c][d] == 1){
lcd.setPixel(4*x+d+2,4*y+c+2); //+2 +2 for pixel alignment
}
}
}
else{
for (int c = 0; c < 4; c++){
for (int d = 0; d < 3; d++){
if (SnakeHead[c][d] == 1){
lcd.setPixel(4*x+c+1,4*y+d+2); //The +1, +2 is just to align the pixel with the food correctly
}
}
}
}
}
void SetSnakeTail() //This is the function which consists of problem.
{
prevX = tailX[0]; //Stores the value of SnakeHead(x,y) so that the tail[i] can move to tail[i-1] (which is 0 in this case]
prevY = tailY[0]; //
tailX[0] = x; //tailX[0] is actually the x coordinate of SnakeHead. This makes sure the tail is following head.
tailY[0] = y; //tailY[0] is actually the y coordinate of SnakeHead. This makes sure the tail is following head.
for (int i = 1; i<SnakeLength; i++){
prev2X = tailX[i]; //Stores (x,y) of tailX[i], e.g. tailX[1]
prev2Y = tailY[i]; //
tailX[i] = prevX; //tailX[i] moves to tailX[i-1], e.g. tailX[1] to tailX[0] i.e. x (head position). Remember head already moved.
tailY[i] = prevY; //tailY[i] moves to tailY[i-1].
prevX = prev2X; //prevX becomes prev2X. So that in the next for loop tailX[i] would update to the next element.
prevY = prev2Y;
if (snakedirection == right){
for (int e = 0; e < 4; e++){
for (int f = 0; f < 3; f++){
if (SnakeTail[e][f] == 1){
lcd.setPixel(4*tailX[i]+e+1,4*tailY[i]+f+2); //move right
}
}
}
}
else if (snakedirection == left){
for (int e = 0; e < 4; e++){
for (int f = 0; f < 3; f++){
if (SnakeTail[e][f] == 1){
lcd.setPixel(4*tailX[i]-e+5,4*tailY[i]+f+2); //move left
}
}
}
}
else if (snakedirection == up){
for (int e = 0; e < 4; e++){
for (int f = 0; f < 3; f++){
if (SnakeTail[e][f] == 1){
lcd.setPixel(4*tailX[i]+f+2,4*tailY[i]-e+6); //move up
}
}
}
}
else if (snakedirection == down){
for (int e = 0; e < 4; e++){
for (int f = 0; f < 3; f++){
if (SnakeTail[e][f] == 1){
lcd.setPixel(4*tailX[i]+f+2,4*tailY[i]+e+2); //move down
}
}
}
}
}
}
void SnakeMoving() //karnaugh warping of pixels.
{
readJoystick();
if (snakedirection == right){
x++;
if (x > 19){
x = 0;}}
else if (snakedirection == left){
x--;
if (x < 0){
x = 19;}}
else if (snakedirection == up){
y--;
if (y < 0){
y = 10;}}
else if (snakedirection == down){
y++;
if (y > 10){
y = 1;}}
else {}
}
void DrawBorders() //function name says it all
{
lcd.drawRect(0,0,83,47,0);
lcd.refresh();
}
void MainGame()
{
lcd.clear();
SetSnakeHead();
if (button == 1 || (x == RandX && y == RandY)){
SnakeLength++;
RandFoodCoordinate();
SetFoodCoordinate();
}
else{
SetFoodCoordinate();
}
SetSnakeTail();
SnakeMoving();
DrawBorders();
}
//MAIN CODE
int main()
{
//Calibrate Joystick First.
calibrateJoystick(); // get centred values of joystick
//
button.mode(PullDown);
srand(time(0)); //what srand do, is to tell the program make a new set of random numbers every second the program is running
//Start the lcd initialisation
lcd.init();
RandFoodCoordinate();
SetFoodCoordinate();
x = 10; y = 5;
SnakeLength = 2;
SetSnakeHead();
InitSnakeTail();
DrawBorders();
readJoystick();
snakedirection = centre;
//And then start calling the ticker function of game
while (snakedirection == centre){
updateJoystick();
readJoystick();
if (snakedirection != centre)
break;
}
pollJoystick.attach(&updateJoystick,1.0/30.0); // read joystick 10 times per second
SnakeSpeed.attach(&MainGame,0.2); //address of the function to be attached (Main Game) and speed (0.2)
while(1)
{}
}
void InitSnakeTail()
{
tailX[0] = x;
tailY[0] = y;
for (int i = 1; i < SnakeLength; i++){
tailX[i] = x-i;
tailY[i] = y;
for (int e = 0; e < 4; e++){
for (int f = 0; f < 3; f++){
if (SnakeTail[e][f] == 1){
lcd.setPixel(4*tailX[i]+e+1,4*tailY[i]+f+2); //That +2 is to match the snake placement.
}
}
}
}
}
<</code>>
This is the link to a video showing how my code doesn't work.
[[https://www.youtube.com/watch?v=sk5fL_qBxTo]]
I'm trying to make a simple snake game, on FRDM-k64F. Everything works fine, the snake moves, it grows if a food's eaten or i press a button (to simulate food eaten, for debugging). Except, all the snake tail section changes direction everytime I change the snake head direction. I know that's my code's problem, I identified it, but I couldn't get a way to write my code correctly. Any suggestions?
SnakeGame
#include "mbed.h" #include "N5110.h" #include "SNAKELIB.h" // VCC, SCE, RST, D/C, MOSI, SCLK, LED N5110 lcd (PTE26 , PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3); Ticker SnakeSpeed; //Variables int FoodPattern[3][3] = {{1,0,1},{0,1,0},{1,0,1}}; int SnakeHead[4][3] = {{1,1,1},{1,1,1},{1,1,1},{0,1,1}}; //Snake head template int SnakeTail[4][3] = {{0,0,1},{0,1,1},{1,1,1},{0,1,1}}; //Snake tail template int RandX, RandY; //Random food coordinate int x, y; //The SnakeHead 1st pixel, max (19,10) because it's 4 blocks(and 2 blank pixel space) int tailX[100], tailY[100], SnakeLength; //The SnakeTail pixel, max (19,10) (same above) int prevX, prevY; //Store Previous Snake Tail X,Y status int prev2X, prev2Y; //Store Previous Previous Snake Tail X,Y //Functions void RandFoodCoordinate(); //Randomize the food coordinate void SetFoodCoordinate(); //Set the food coordinate void SetSnakeHead(); void SetSnakeTail(); void SnakeMoving(); void DrawBorders(); //Draw the outline border. void MainGame(); //This is the game function which's called every ticker time void InitSnakeTail(); //Declarations void RandFoodCoordinate() { RandX = rand()%19; //randomize a number between 0-18, i.e. max x coordinate = 76 RandY = rand()%10; //randomize a number between 0-9, i.e. max y coordinate = 40 } void SetFoodCoordinate() { for (int a = 0; a < 3; a++){ for (int b = 0; b < 3; b++){ if (FoodPattern[a][b] == 1){ //The +2 is to make sure the food would not spawn in the border. Maximum (x,y)of food is (78,42) //and the last pixel of food would be (80,44) [[maybe i could make it 83,47 later. need testing]] lcd.setPixel(4*RandX+a+2,4*RandY+b+2); } } } } void SetSnakeHead() { if (snakedirection == right){ for (int c = 0; c < 4; c++){ for (int d = 0; d < 3; d++){ if (SnakeHead[c][d] == 1){ lcd.setPixel(4*x+c+1,4*y+d+2); //The +1, +2 is just to align the pixel with the food correctly } } } } else if (snakedirection == left){ for (int c = 0; c < 4; c++){ for (int d = 0; d < 3; d++){ if (SnakeHead[c][d] == 1){ lcd.setPixel(4*x-c+5,4*y+d+2); //The +5, +2 is to align the pixel with food correctly } } } } else if (snakedirection == up){ for (int c = 0; c < 4; c++){ for (int d = 0; d < 3; d++){ if (SnakeHead[c][d] == 1){ lcd.setPixel(4*x+d+2,4*y-c+6); //+2, +6 is to align pixel with food } } } } else if (snakedirection == down){ for (int c = 0; c < 4; c++){ for (int d = 0; d < 3; d++){ if (SnakeHead[c][d] == 1){ lcd.setPixel(4*x+d+2,4*y+c+2); //+2 +2 for pixel alignment } } } else{ for (int c = 0; c < 4; c++){ for (int d = 0; d < 3; d++){ if (SnakeHead[c][d] == 1){ lcd.setPixel(4*x+c+1,4*y+d+2); //The +1, +2 is just to align the pixel with the food correctly } } } } } void SetSnakeTail() //This is the function which consists of problem. { prevX = tailX[0]; //Stores the value of SnakeHead(x,y) so that the tail[i] can move to tail[i-1] (which is 0 in this case] prevY = tailY[0]; // tailX[0] = x; //tailX[0] is actually the x coordinate of SnakeHead. This makes sure the tail is following head. tailY[0] = y; //tailY[0] is actually the y coordinate of SnakeHead. This makes sure the tail is following head. for (int i = 1; i<SnakeLength; i++){ prev2X = tailX[i]; //Stores (x,y) of tailX[i], e.g. tailX[1] prev2Y = tailY[i]; // tailX[i] = prevX; //tailX[i] moves to tailX[i-1], e.g. tailX[1] to tailX[0] i.e. x (head position). Remember head already moved. tailY[i] = prevY; //tailY[i] moves to tailY[i-1]. prevX = prev2X; //prevX becomes prev2X. So that in the next for loop tailX[i] would update to the next element. prevY = prev2Y; if (snakedirection == right){ for (int e = 0; e < 4; e++){ for (int f = 0; f < 3; f++){ if (SnakeTail[e][f] == 1){ lcd.setPixel(4*tailX[i]+e+1,4*tailY[i]+f+2); //move right } } } } else if (snakedirection == left){ for (int e = 0; e < 4; e++){ for (int f = 0; f < 3; f++){ if (SnakeTail[e][f] == 1){ lcd.setPixel(4*tailX[i]-e+5,4*tailY[i]+f+2); //move left } } } } else if (snakedirection == up){ for (int e = 0; e < 4; e++){ for (int f = 0; f < 3; f++){ if (SnakeTail[e][f] == 1){ lcd.setPixel(4*tailX[i]+f+2,4*tailY[i]-e+6); //move up } } } } else if (snakedirection == down){ for (int e = 0; e < 4; e++){ for (int f = 0; f < 3; f++){ if (SnakeTail[e][f] == 1){ lcd.setPixel(4*tailX[i]+f+2,4*tailY[i]+e+2); //move down } } } } } } void SnakeMoving() //karnaugh warping of pixels. { readJoystick(); if (snakedirection == right){ x++; if (x > 19){ x = 0;}} else if (snakedirection == left){ x--; if (x < 0){ x = 19;}} else if (snakedirection == up){ y--; if (y < 0){ y = 10;}} else if (snakedirection == down){ y++; if (y > 10){ y = 1;}} else {} } void DrawBorders() //function name says it all { lcd.drawRect(0,0,83,47,0); lcd.refresh(); } void MainGame() { lcd.clear(); SetSnakeHead(); if (button == 1 || (x == RandX && y == RandY)){ SnakeLength++; RandFoodCoordinate(); SetFoodCoordinate(); } else{ SetFoodCoordinate(); } SetSnakeTail(); SnakeMoving(); DrawBorders(); } //MAIN CODE int main() { //Calibrate Joystick First. calibrateJoystick(); // get centred values of joystick // button.mode(PullDown); srand(time(0)); //what srand do, is to tell the program make a new set of random numbers every second the program is running //Start the lcd initialisation lcd.init(); RandFoodCoordinate(); SetFoodCoordinate(); x = 10; y = 5; SnakeLength = 2; SetSnakeHead(); InitSnakeTail(); DrawBorders(); readJoystick(); snakedirection = centre; //And then start calling the ticker function of game while (snakedirection == centre){ updateJoystick(); readJoystick(); if (snakedirection != centre) break; } pollJoystick.attach(&updateJoystick,1.0/30.0); // read joystick 10 times per second SnakeSpeed.attach(&MainGame,0.2); //address of the function to be attached (Main Game) and speed (0.2) while(1) {} } void InitSnakeTail() { tailX[0] = x; tailY[0] = y; for (int i = 1; i < SnakeLength; i++){ tailX[i] = x-i; tailY[i] = y; for (int e = 0; e < 4; e++){ for (int f = 0; f < 3; f++){ if (SnakeTail[e][f] == 1){ lcd.setPixel(4*tailX[i]+e+1,4*tailY[i]+f+2); //That +2 is to match the snake placement. } } } } }This is the link to a video showing how my code doesn't work. https://www.youtube.com/watch?v=sk5fL_qBxTo