We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
Page Index Toggle Pages: 1
Snake game (Read 3456 times)
Snake game
Jun 26th, 2009, 3:52pm
 
Hy,
I'm new here...
I'm trying to do a classic snake game in Processing and I have a problem...
When I want to change direction of the snake I don't see every pieces of the snake moving from vertical to horizontal or from horizontal to vertical... it moves all the pieces together. I tried to delete the last piece and move it to the top of the snake, but in vain. I used ellipses to create the snake pieces.
I really need help with this problem, and I need it quickly ... Please help me...
My English is not so good,  I hope you understand what my problem is.
You can download the code from rapidshare.de/files/47672650/Snake.rar.html.
Re: Snake game
Reply #1 - Jun 27th, 2009, 6:40am
 
It sounds like you are changing direction of all the pieces at once, rather than doing them in succession. What you would want to do is have some kind of variable that signals when it's ok for the next piece to change direction. That way you get that "snake-like" movement. I haven't looked at the code, so I don't know if you are using arrays for your snake pieces or objects. If you are using objects, you could just have some direction booleans or an int with directions 1-4. So when you press a key to change direction, each snake piece checks the piece in front of it to make sure it has changed direction, before it changes itself.
Re: Snake game
Reply #2 - Jun 27th, 2009, 8:05am
 
I did what you suggest me... but nothing...
Here is the part of code when the snake moves down and I change its direction to left:
Code:
void downLeft()
{
head.moveLeft();
fill(0);
head.createEllipse();
fill(255);
for(int i=1;i<ellipseList.size();i++)
{
Ellipse prev=(Ellipse)ellipseList.get(i-1);
if(prev.getDir()==dir)
{
Ellipse e=(Ellipse)ellipseList.get(i);
e.moveLeft();
e.createEllipse(head.getX()+(i*10),head.getY());
}
}
}
Re: Snake game
Reply #3 - Jun 27th, 2009, 8:48am
 
I had a look at your code.
First remark: in general, programmers are lazy and try to do more with less... You have several functions that are identical, which is a waste of time (for you and those reading), a source of confusion and make the code hard to maintain (any change must be done several time).
Here is a trimmed down version of your main code (Ellipse code is OK), which work exactly as before... And it still leaves a lot to be improved.
Code:
ArrayList ellipseList;
Ellipse head;
int dir;
int prevDir;
PFont f;
String mesaj="";
boolean ok=false;
Ellipse food;
void setup()
{
size(400,400);
f=loadFont("CurlzMT-22.vlw");
textFont(f);
ellipseList=new ArrayList();
head=new Ellipse(width/2,height/2);
ellipseList.add(head);
food=new Ellipse(int(random(10,390)),int(random(10,390)),6);
mesaj="Press mouse to start the game!\nUse arrows to move the snake.";
dir=2;
}
void draw()
{
fill(0);
background(#FFCCCC);
text(mesaj,width/2-100,height/2);
if(ok)
{
food.createEllipse();
eat(ellipseList.size());
switch(dir)
{
case 0:
up();
break;
case 1:
down();
break;
case 2:
right();
break;
case 3:
left();
break;
}
}
}

void up()
{
head.moveUp();
fill(0);
head.createEllipse();
fill(255);
for(int i=1;i<ellipseList.size();i++)
{
Ellipse e=(Ellipse)ellipseList.get(i);
e.moveUp();
e.createEllipse(head.getX(),head.getY()+(i*10));
}
}

void down()
{
head.moveDown();
fill(0);
head.createEllipse();
fill(255);
for(int i=1;i<ellipseList.size();i++)
{
Ellipse e=(Ellipse)ellipseList.get(i);
e.moveDown();
e.createEllipse(head.getX(),head.getY()-(i*10));
}
}

void left()
{
head.moveLeft();
fill(0);
head.createEllipse();
fill(255);
for(int i=1;i<ellipseList.size();i++)
{
Ellipse e=(Ellipse)ellipseList.get(i);
e.moveLeft();
e.createEllipse(head.getX()+(i*10),head.getY());
}
}

void right()
{
head.moveRight();
fill(0);
head.createEllipse();
fill(255);
for(int i=1;i<ellipseList.size();i++)
{
Ellipse e=(Ellipse)ellipseList.get(i);
e.moveRight();
e.createEllipse(head.getX()-(i*10),head.getY());
}
}

boolean eat(int p)
{
int x=head.getX();
int y=head.getY();
if(dist(x,y,food.getX(),food.getY())<6)
{
ellipseList.add(new Ellipse(x,y+(p*10)));
food=new Ellipse(int(random(10,390)),int(random(10,390)),6);
return true;
}
return false;
}

void mousePressed()
{
mesaj="";
ok=true;
dir=2;
}

void keyPressed()
{
if(key==CODED)
{
prevDir=dir;
if(keyCode==UP)
{
dir=0;
}
if(keyCode==DOWN)
{
dir=1;
}
if(keyCode==RIGHT)
{
dir=2;
}
if(keyCode==LEFT)
{
dir=3;
}
}
}

Now, I see the problem: when changing direction, the snake rigidly move the whole body in the new direction.

A way to solve this might be for each ellipse to get the position of the previous one.
Gotta go right now, will show a way later.
Re: Snake game
Reply #4 - Jun 27th, 2009, 9:12pm
 
Thanks for the code... but my problem still remain.... Cry
Re: Snake game
Reply #5 - Jun 28th, 2009, 1:41am
 
OK, got it. The most tripping part was the smooth movement: if works OK if the snake is moving straight, but when it turns, I don't see how the head would stick to the remainder of the body which has to stay in place.
Here is my version:
Code:
ArrayList ellipseList;
Ellipse head;
int SEGMENT_SIZE = 10;
int dir;
int prevPosX, prevPosY;
PFont f;
String mesaj="";
boolean ok=false;
Ellipse food;
void setup()
{
size(400, 400);
f=loadFont("CurlzMT-22.vlw");
textFont(f);
ellipseList = new ArrayList();
head = new Ellipse(width/2, height/2);
ellipseList.add(head);
dir=2;
// Start with head and small body
ellipseList.add(new Ellipse(width/2 - 2 * SEGMENT_SIZE, height/2));
addFood();
mesaj="Press mouse to start the game!\nUse arrows to move the snake.";
frameRate(10);
}
void draw()
{
fill(0);
background(#FFCCCC);
text(mesaj,width/2-100,height/2);
if(ok)
{
food.createEllipse();
tryToEatAndMove(ellipseList.size());
}
}

boolean tryToEatAndMove(int p)
{
int x = head.getX();
int y = head.getY();
if (dist(x, y, food.getX(), food.getY()) < 6)
{
// Move the body
move();
// Get last two segments
Ellipse e1 = (Ellipse) ellipseList.get(ellipseList.size() - 1);
Ellipse e2 = (Ellipse) ellipseList.get(ellipseList.size() - 2);
int dX = e1.getX() - e2.getX();
int dY = e1.getY() - e2.getY();
// Add another segment at the end
ellipseList.add(new Ellipse(e1.getX() + dX, e1.getY() + dY));
// Add food to replace the one being eat
addFood();
println("Length: " + ellipseList.size());
return true;
}
// Not on food, just move
move();
return false;
}
void addFood()
{
food = new Ellipse(int(random(10, 390)), int(random(10, 390)),6);
}
void move()
{
prevPosX = head.getX();
prevPosY = head.getY();
switch(dir)
{
case 0:
head.moveUp();
break;
case 1:
head.moveDown();
break;
case 2:
head.moveRight();
break;
case 3:
head.moveLeft();
break;
}
followHead();
}

void followHead()
{
fill(0);
head.createEllipse();
fill(255);
for (int i = 1; i < ellipseList.size(); i++)
{
Ellipse e = (Ellipse) ellipseList.get(i);
int ppX = e.getX();
int ppY = e.getY();
// Move the segment where the previous one was
e.x = prevPosX; e.y = prevPosY; // Need Ellipse.setX and setY...
prevPosX = ppX;
prevPosY = ppY;
e.createEllipse();
}
}

void mousePressed()
{
mesaj="";
ok=true;
dir=2;
}

void keyPressed()
{
if(key==CODED)
{
if(keyCode==UP)
{
dir=0;
}
if(keyCode==DOWN)
{
dir=1;
}
if(keyCode==RIGHT)
{
dir=2;
}
if(keyCode==LEFT)
{
dir=3;
}
}
}

class Ellipse
{
int x; int y; int l;
Ellipse(int _x, int _y)
{
x=_x; y=_y; l=10;
}
Ellipse(int _x, int _y, int _l)
{
x=_x; y=_y; l=_l;
}
void createEllipse()
{
ellipse(x,y,l,l);
}
void createEllipse(int a,int b)
{
ellipse(a,b,l,l);
}

void moveUp()
{
y-=l;
if(y<0) y=height;
}
void moveDown()
{
y+=l;
if(y>height) y=0;
}
void moveRight()
{
x+=l;
if(x>width) x=0;
}
void moveLeft()
{
x-=l;
if(x<0) x=width;
}
int getX()
{
return x;
}
int getY()
{
return y;
}
int getL()
{
return l;
}
}
Re: Snake game
Reply #6 - Jun 28th, 2009, 2:48am
 
THANK YOU for the help
I will be forever grateful!
You're the best! Wink
Re: Snake game
Reply #7 - Jan 16th, 2010, 6:28pm
 
Check this version.

class Snake
{
 int x; int y; int h;
 
   
 Snake(int xc, int yc)
 {
   x=xc; y=yc; h=14;
 }
 Snake(int xc, int yc, int s)
 {
   x=xc; y=yc; h=s;
 
 }
 void createSnake()
 {
   ellipse(x,y,h,h);
 
 }
 void createSnake(int a,int b)
 {
   ellipse(a,b,h,h);

   
 }

 
 void moveSnakeUp()
 {
   if(gameEnd == false){
   y= y - h;
   if(y<0){
     end();
   y=height;
   
   gameEnd = true;
   newSession();
   }
   }  
 }
 void moveSnakeDown()
 {
   if(gameEnd == false){
   y = y + h;
   if(y>height){
     end();
   y=0;
   gameEnd = true;
   newSession();
   }
   }
   }  
 
 void moveSnakeRight()
 {
   if(gameEnd == false){
   x = x + h;
   if(x>width){
     end();
   x=0;
   gameEnd = true;
   newSession();
   }
   }
   }  
 
 void moveSnakeLeft()
 {
   if(gameEnd == false){
   x = x - h;
   if(x<0){
   x=width;
   end();
   gameEnd = true;
   newSession();
   }
   }
   }  
 
 int getXc()
 {
   return x;
 }
 int getYc()
 {
   return y;
 }
 int getH()
 {
   
   return h;

 
 }
}


import pitaru.sonia_v2_9.*;
Sample backMusic;
ArrayList snakeSegments;
Snake head;
int SEGMENT_SIZE = 0;
int direction;
int prevPosX;
int prevPosY;
int timer;
int timeLength = 1000;
PFont font;
PFont fontt;
String welcomeMessage="";
String gameOver = "";
String exitGame = "";
String startAllOver = "";
String message = "";
boolean isOk=false;
boolean newGame = false;
boolean gameEnd = false;
boolean stopGame = false;
boolean changeLevel;
int score = 0;
int speed = (int)random(1,5);
int xMove = 0;
Snake food;
int gameLevel = 0;
PImage backImage;
PImage inBack;
void setup()
{
 size(500, 500);
 backImage = loadImage("back.jpg");
 backImage.resize(500,500);
 font=loadFont("Broadway-28.vlw");
 fontt=loadFont("Chiller-Regular-28.vlw");

 textFont(font);
 snakeSegments = new ArrayList();
 head = new Snake(width/8, height/20);
 snakeSegments.add(head);
 direction=0;
 Sonia.start(this);
 backMusic = new Sample("backgroundM.wav");  
 snakeSegments.add(new Snake(width, height));
 addFood();
 welcomeMessage="CLICK THE SCREEN TO START!" + "\n  ";
 message = "B or b = Background Music" + "\nC or c = Cancel Music.";


}
void draw()
{
 fill(random(0,255),random(0,255),random(0,255));
 background(backImage);

 text(welcomeMessage,10,height/2);
 text(gameOver,150,height/2);
 text(exitGame,60,400);
 text(message, 1,460);
 if(mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
   cursor(HAND);

 }

 if(isOk )
 {
   background(0);
   frameRate(5);
   food.createSnake();
   tryToEatAndMove(snakeSegments.size());
   cursor(ARROW);
   
 }

 newSession();
}

boolean tryToEatAndMove(int p)
{
 int x = head.getXc();
 int y = head.getYc();
 if (dist(x, y, food.getXc(), food.getYc()) < 12)
 {
   move();
   Snake s1 = (Snake) snakeSegments.get(snakeSegments.size() - 1);
   Snake s2 = (Snake) snakeSegments.get(snakeSegments.size() - 2);
   int dX = s1.getXc() - s2.getXc();
   int dY = s1.getYc() - s2.getYc();
   snakeSegments.add(new Snake(s1.getXc() + dX, s1.getYc() + dY));
   addFood();  
   return true;
 }
 move();
 return false;
}
void addFood()
{
 food = new Snake(int(random(10, 390)), int(random(10, 390)),14);
}
void move()
{  
 scoreLogic();  
 prevPosX = head.getXc();
 prevPosY = head.getYc();
 switch(direction)
 {
 case 0:
   head.moveSnakeUp();    
   break;
 case 1:
   head.moveSnakeDown();
   break;
 case 2:
   head.moveSnakeRight();
   break;
 case 3:
   head.moveSnakeLeft();
   break;
 }
 followHead();
}

void followHead()
{
 fill(200,25,0);
 head.createSnake();
 fill(0,255,0);
 for (int i = 1; i < snakeSegments.size(); i++)  {
   Snake s = (Snake) snakeSegments.get(i);
   int ppX = s.getXc();
   int ppY = s.getYc();
   s.x = prevPosX;
   s.y = prevPosY;
   prevPosX = ppX;
   prevPosY = ppY;
   s.createSnake();
 }
}

void mousePressed()
{
 exitGame = "";
 welcomeMessage="";

 startAllOver = "";
 isOk=true;
 newGame = true;
 stopGame= true;

 direction=2;  
}

void keyPressed()
{
 if(key==CODED)
 {
   if(keyCode==UP)
   {
     direction=0;
   }
   if(keyCode==DOWN)
   {
     direction=1;
   }
   if(keyCode==RIGHT)
   {
     direction=2;
   }
   if(keyCode==LEFT)
   {
     direction=3;
   }

 }
 if(key == 'b' || key == 'B')
 {
   backMusic.play();
 }
 if(key == 'c' || key == 'C')
 {
   backMusic.stop();
 }
}
void scoreLogic(){
 stroke(4);
 score = snakeSegments.size()*10-20;
 textFont(fontt);
 fill(255,0,300);
 rect(190, 460 , 200, 20 );
 fill(0,255,255);  
 rect(190 + score, 460  , 4, 20 );
 text("Score:", 80, 480);
 fill(100,255,255);
 text(score, 400, 480);
 score++;
}
void end(){
 textFont(font);
 gameOver = "Game Over!!!" + "\n  ";  
 exitGame = "Click Me to Exit the Game";
 backMusic.stop();
 isOk = false;
}

void newSession(){
 if(mouseX > 0 && mouseX < width && mouseY > height/2 && mouseY < height && mousePressed){
   exit();

 }
 if(mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height/2 && gameEnd == true && mousePressed){

 snakeSegments = new ArrayList();
 head = new Snake(width/8, height/20);
 snakeSegments.add(head);
 followHead();
 move();
 tryToEatAndMove(snakeSegments.size());
 }
}

Page Index Toggle Pages: 1