# more help with snake game

• October 2nd, 2012, 10:25 AM
godlynom
more help with snake game
Hello all, this is godlynom again, thanks to those who helped me last time. Everything is working, now I just need the body parts to be added after I collide with the food. Essentially everytime you run into a food, you need to grow a body part, or another snake object behind the current one. I have been working on this for quite a bit now and have run into a roadblock, I feel like I need to create an array of SnakeBody objects, but I am confused as to how to go about that. We have not done too many arrays in class, if someone could just at least point me in the right way, that would be wonderful. Here is my code so far, there is some extraneous methods from me trying to figure out how to get it to work.
Food Class:
import java.awt.*;

public class Food
Code :

```{ double x = 0, y = 0; private double myX; // x and y coordinates of center private double myY; private double myDiameter; private Color myColor; private double myRadius; private double myHeight; private static final int FRAME = 495;     public Food() { myX = 0; myY = 200; myHeight = 15; myColor = Color.RED; myRadius = myDiameter/2; } public Food(double x, double y, double d, Color c) { myX = x; myY = y; myHeight = d; myColor = c; myRadius = d/2; } public double getX() { return myX; } public double getY() { return myY; } public double getDiameter() { return myDiameter; } public Color getColor() { return myColor; } public double getRadius() { return myRadius; } public double getHeight() { return myHeight; }   // modifier methods public void setX(double x) { myX = x; } public void setY(double y) { myY = y; } public void setColor(Color c) { myColor = c; } public void setDiameter(double d) { myDiameter = d; myRadius = d/2; } public void setRadius(double r) { myRadius = r; myDiameter = 2*r; } // instance methods public void jump(int rightEdge, int bottomEdge) { // moves location to random (x, y) within the edges myX = rightEdge; myY = bottomEdge; }   public void draw(Graphics myBuffer) { myBuffer.setColor(myColor); myBuffer.fillRect((int)(myX), (int)(myY), (int)myHeight, (int)myHeight); } }```

SnakeBody Class:
Code :

``` import java.awt.*;   public class SnakeBody { private double myX; // x and y coordinates of center private double myY; private double myDiameter; private Color myColor; private double myRadius; private double myHeight; private Graphics myBuffer;   double x =350, y = 350, velx = 0, vely = 0, x1 = 0, y1 = 0;   // constructors public SnakeBody() //default constructor { myX = 0; myY = 0; myHeight = 15; myColor = Color.RED; myRadius = myDiameter/2;   } public SnakeBody(double x, double y, double d, Color c) { myX = x; myY = y; myHeight = d; myColor = c; myRadius = d/2; } // accessor methods public int getX() { return (int) myX; } public int getY() { return (int) myY; } public double getDiameter() { return myDiameter; } public Color getColor() { return myColor; } public double getRadius() { return myRadius; } public double getHeight() { return myHeight; } // modifier methods public void setX(double x) { myX = x; } public void setY(double y) { myY = y; } public void setColor(Color c) { myColor = c; } public void setDiameter(double d) { myDiameter = d; myRadius = d/2; } public void setRadius(double r) { myRadius = r; myDiameter = 2*r; } // instance methods public void draw(Graphics myBuffer) { myBuffer.setColor(myColor); myBuffer.fillRect((int)(myX), (int)(myY), (int)myHeight, (int)myHeight); } }```

Snake Class(Panel):
Code :

``` import javax.swing.*;   import java.awt.*; import java.awt.event.*; import java.awt.image.*;   public class Snake extends JPanel implements ActionListener, KeyListener { Timer t = new Timer(75, this); double x =0, y = 0, velx = 0, vely = 0, x1 = 0, y1 = 0; private static final int FRAME = 480; private Food food; private SnakeBody snake, snake1;   int count = 0; int distance = 15;   public Snake() { t.start(); addKeyListener(this); setFocusable(true); setFocusTraversalKeysEnabled(false);   x = 240; y = 240;   x1 = 15 * (int)(Math.random()* 32); y1 = 15 * (int)(Math.random()* 32); food = new Food(x1,y1,15,Color.BLUE); snake = new SnakeBody(x,y,15, Color.RED); SnakeBody[] snake1 = new SnakeBody[100]; } public void paintComponent(Graphics g) { super.paintComponent(g); food.draw(g); snake.draw(g); collide(snake, food); for(int i = 0; i < 480; i+=15) { g.setColor(Color.BLACK); g.drawLine(i,FRAME,i,0); g.drawLine(FRAME,i,0,i); } g.drawLine(FRAME,0,FRAME,FRAME); g.drawLine(0,FRAME,FRAME,FRAME);   g.setColor(Color.BLACK); g.setFont(new Font("Monospaced",Font.BOLD,24)); g.drawString("Count:" + count, FRAME - 300, 25); } public void actionPerformed(ActionEvent e) { x += velx; y += vely; if(x<0) { x = 465; } if(x>465) { x = 0; } if(y<0) { y = 465; } if(y>465) { y = 0; } snake.setX(x); snake.setY(y);   repaint(); } private void collide(SnakeBody snake, Food food) { double d = distance(snake.getX(),snake.getY(),food.getX(),food.getY());   if(d < snake.getHeight()/2 + food.getHeight()/2) { int x3 = 15 * (int)(Math.random()* 32); int y3 = 15 * (int)(Math.random()* 32); food.jump(x3,y3); snake.newBody(snake); count += 250; }   } private double distance(double x1, double y1, double x2, double y2) { return Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2)); } public void up() { vely = -15; velx = 0; } public void down() { vely = 15; velx = 0; } public void left() { velx = -15; vely = 0; } public void right() { velx = 15; vely = 0; } public void keyPressed(KeyEvent e) { int code = e.getKeyCode(); if(code == KeyEvent.VK_LEFT) { if(velx == 15) { up(); } else if(velx == -15) { down(); } else if(vely == 15) { right(); } else if(vely == -15) { left(); } else { left(); } } if(code == KeyEvent.VK_RIGHT) {   if(velx == 15) { down(); } else if(velx == -15) { up(); } else if(vely == 15) { left(); } else if(vely == -15) { right(); }   else { right(); } } } public void keyTyped(KeyEvent e){} public void keyReleased(KeyEvent e){} }```

Main Class:
Code :

```import javax.swing.JFrame;   public class SnakeMain { public static void main(String[] args) { JFrame f = new JFrame("Snake Game"); Snake s = new Snake(); f.add(s); f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(489,515); } }```

thanks
• October 2nd, 2012, 10:27 AM
godlynom
Re: more help with snake game
The food class did not copy all over, here is the code again
Code :

```import java.awt.*;   public class Food { double x = 0, y = 0; private double myX; // x and y coordinates of center private double myY; private double myDiameter; private Color myColor; private double myRadius; private double myHeight; private static final int FRAME = 495;     public Food() { myX = 0; myY = 200; myHeight = 15; myColor = Color.RED; myRadius = myDiameter/2; } public Food(double x, double y, double d, Color c) { myX = x; myY = y; myHeight = d; myColor = c; myRadius = d/2; } public double getX() { return myX; } public double getY() { return myY; } public double getDiameter() { return myDiameter; } public Color getColor() { return myColor; } public double getRadius() { return myRadius; } public double getHeight() { return myHeight; }   // modifier methods public void setX(double x) { myX = x; } public void setY(double y) { myY = y; } public void setColor(Color c) { myColor = c; } public void setDiameter(double d) { myDiameter = d; myRadius = d/2; } public void setRadius(double r) { myRadius = r; myDiameter = 2*r; } // instance methods public void jump(int rightEdge, int bottomEdge) { // moves location to random (x, y) within the edges myX = rightEdge; myY = bottomEdge; }   public void draw(Graphics myBuffer) { myBuffer.setColor(myColor); myBuffer.fillRect((int)(myX), (int)(myY), (int)myHeight, (int)myHeight); } }```
• October 2nd, 2012, 10:35 AM
helloworld922
Re: more help with snake game
I would recommend using a List, more specifically a ArrayList. It's created like any other object and you don't have to worry too much about the low-level details required with arrays (specifically you don't have to manually resize ArrayLists).

Lists are regular objects so you use them as you would any other object:

Code java:

```// create a new list ArrayList<String> names = new ArrayList<String>();   // add items to the list names.add("Andrew"); names.add("Bill"); names.add("Charles");   // print out all items in the list for(int i = 0; i < names.size(); ++i) { System.out.println(names.get(i)); }```
• October 2nd, 2012, 10:37 AM
KevinWorkman
Re: more help with snake game
That's way too much code for us to wade through, and we can't do your homework for you. I suggest breaking your problem down into an SSCCE and focusing on one thing at a time.
• October 2nd, 2012, 04:23 PM
godlynom
Re: more help with snake game
So if I were to make many snake objects, would i just create an:

Code :

`ArrayList <SnakeBody> snake = new ArrayList <SnakeBody>();`

and then call them one by one in a for loop based on that?

@KevinWorkman I was not asking you to do this for me, and this is not homework, doing this for fun and practice, just wanted some advice on a direction to go, like helloworld922 did, thought posting the code would help some folks
• October 2nd, 2012, 05:28 PM
godlynom
Re: more help with snake game
as an update, i worked on my class and now the snake body parts get created and drawn, but only for a second, so you see the body part and then it disappears, any help?
Snake class:
Code :

``` import javax.swing.*; import java.util.ArrayList; import java.awt.*; import java.awt.event.*; import java.awt.image.*;   public class Snake extends JPanel implements ActionListener, KeyListener { Timer t = new Timer(75, this); double x =0, y = 0, velx = 0, vely = 0, x1 = 0, y1 = 0; private static final int FRAME = 480; private boolean dup,ddown,dright,dleft, go; private Food food; private SnakeBody snakeH; private ArrayList<SnakeBody> snake = new ArrayList<SnakeBody>();   int count = 0; int distance = 15;     public Snake() { addKeyListener(this); setFocusable(true); setFocusTraversalKeysEnabled(false); go = true;   x = 240; y = 240;   x1 = 15 * (int)(Math.random()* 32); y1 = 15 * (int)(Math.random()* 32); food = new Food(x1,y1,15,Color.BLUE); snake.add(new SnakeBody(x,y,15, Color.RED)); SnakeBody temp = new SnakeBody(0,0,0,Color.red); snakeH=new SnakeBody(0,0,0,Color.RED); t.start(); } public void paintComponent(Graphics g) { super.paintComponent(g); food.draw(g); for(SnakeBody s: snake) { s.draw(g); } for(int i = 0; i < 480; i+=15) { g.setColor(Color.BLACK); g.drawLine(i,FRAME,i,0); g.drawLine(FRAME,i,0,i); } g.drawLine(FRAME,0,FRAME,FRAME); g.drawLine(0,FRAME,FRAME,FRAME);   g.setColor(Color.BLACK); g.setFont(new Font("Monospaced",Font.BOLD,24)); g.drawString("Count:" + count, FRAME - 300, 25); } public void actionPerformed(ActionEvent e) { x += velx; y += vely; if(x<0) { x = 465; } if(x>465) { x = 0; } if(y<0) { y = 465; } if(y>465) { y = 0; } snakeH.setX(x); snakeH.setY(y); SnakeBody temp=new SnakeBody(0,0,0,Color.red); SnakeBody temp1=new SnakeBody(0,0,0,Color.red); go=true; collide(snakeH, food); for(SnakeBody s: snake) { if(snake.indexOf(s)==0) { snakeH=new SnakeBody(0,0,0,Color.red); snakeH=s; } } if(go) { int i=0; for(SnakeBody s: snake) { if(snake.indexOf(s)>=1) { temp1=s; s.follow(snake.get(i)); temp=temp1; } else { snakeH = s; temp=s; } i=snake.indexOf(s); } } go=true;   repaint(); } private void collide(SnakeBody s, Food food) { int dx=0,dy=0; if(dup) { dx=0; dy=-15; } else if(ddown) { dx=0; dy=15; } else if(dleft) { dx = -15; dy = 0; } else if(dright) { dx = 15; dy = 0; } double d = distance(s.getX()+dx,s.getY()+dy,food.getX(),food.getY());   if(d < s.getHeight()/2 + food.getHeight()/2) { snake.add(0,new SnakeBody(food.getX(),food.getY(),15,Color.red)); int x3 = 15 * (int)(Math.random()* 32); int y3 = 15 * (int)(Math.random()* 32); food.jump(x3,y3); go=false; count += 250; }   } private double distance(double x1, double y1, double x2, double y2) { return Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2)); } public void up() { vely = -15; velx = 0; dup=true; ddown=false; dleft = false; dright = false; } public void down() { vely = 15; velx = 0; dup=false; ddown=true; dleft = false; dright = false; } public void left() { velx = -15; vely = 0; dup=false; ddown=false; dleft = true; dright = false; } public void right() { velx = 15; vely = 0; dup=false; ddown=false; dleft = false; dright = true; } public void keyPressed(KeyEvent e) { int code = e.getKeyCode(); if(code == KeyEvent.VK_LEFT) { if(velx == 15) { up(); } else if(velx == -15) { down(); } else if(vely == 15) { right(); } else if(vely == -15) { left(); } else { left(); } } if(code == KeyEvent.VK_RIGHT) {   if(velx == 15) { down(); } else if(velx == -15) { up(); } else if(vely == 15) { left(); } else if(vely == -15) { right(); }   else { right(); } } } public void keyTyped(KeyEvent e){} public void keyReleased(KeyEvent e){} }```

and here is the follow method in the SnakeBody class:
Code :

```public void follow(SnakeBody snake) { myX=snake.getX(); myY=snake.getY(); myHeight = snake.getHeight(); }```
• October 2nd, 2012, 05:34 PM
Norm
Re: more help with snake game
Quote:

body part and then it disappears, any help?
Try debugging the code by printing out the values of the variables that control the drawing of the body. Are their values changing and causing the code to stop drawing the body?
• October 2nd, 2012, 06:51 PM
godlynom
Re: more help with snake game
well i debugged the paintComponent, and whenever i collide with a food, a new SnakeBody is created and read every single tick, however, it is not being drawn
• October 2nd, 2012, 07:28 PM
Norm
Re: more help with snake game
Quote:

it is not being drawn
Why isn't it being drawn? Does the println statement in its draw() method print out?

Quote:

new SnakeBody is created and read every single tick,
When you create a new SnakeBody object, is it added to the GUI so it will be seen when its drawn?
Are you calling a method in an obJect that has not been added to the GUI?
• October 2nd, 2012, 07:44 PM
godlynom
Re: more help with snake game
well i put the debugger here
Code :

``` for(SnakeBody s: snake) { s.draw(g); System.out.println(s); }```
and each time i got a food it created a new SnakeBody, and then also was drawing them all every single tick
• October 2nd, 2012, 07:50 PM
Norm
Re: more help with snake game
Quote:

drawing them all every single tick
Is it working now?
• October 2nd, 2012, 08:59 PM
godlynom
Re: more help with snake game
no, they still disappear, are the coordinates getting changed to the first snake's, or is the SnakeBody not being actually drawn, it says it is, trying to figure this out now
• October 2nd, 2012, 09:06 PM
Norm
Re: more help with snake game
Quote:

are the coordinates getting changed
Time for more debugging: add the x,y values to the printlns in the SnakeBody draw() method so you can see where the draw method is putting the rectangles. Also print out the width and height values.
• October 2nd, 2012, 09:13 PM
godlynom
Re: more help with snake game
okay, yea, my assumption was correct, they do draw, but then their x and y are changed to that of the original snake, thus merging back into one snake
• October 2nd, 2012, 09:16 PM
Norm
Re: more help with snake game
Are you saying that all the drawing is done on top of each other?
• October 2nd, 2012, 09:21 PM
godlynom
Re: more help with snake game
they are drawn separately, with different x's and y's, but then the next time they move they all become the original snake's x and y and then are drawn upon each other, so it is all the bodyparts in one box basically
• October 2nd, 2012, 09:23 PM
Norm
Re: more help with snake game
Where in the code are the values changed so that they are on top of each other?
• October 2nd, 2012, 09:27 PM
godlynom
Re: more help with snake game
I think it is this code
Code :

```if(go) { int i=0; for(SnakeBody s: snake) { if(snake.indexOf(s)>=1) { temp1=s; s.follow(snake.get(i)); temp=temp1; } else { snakeH = s; temp=s; } i=snake.indexOf(s); } }```

Code :

```public void follow(SnakeBody snake) { myX=snake.getX(); myY=snake.getY(); myHeight = snake.getHeight(); }```
• October 2nd, 2012, 09:32 PM
Norm
Re: more help with snake game
Sorry, its your code. You should be able to see where it changes the x & y values for the SnakeBody objects.
What are the x and y values set to in the follow() method?
• October 2nd, 2012, 09:42 PM
godlynom
Re: more help with snake game
yea, i tested it out, the problem is in my follow method, what i do is i set the x and y of the bodyparts to the x and y of the snake, so now i need to make it so that it appears behind the snake, but travels at the same velocity and direction
• October 2nd, 2012, 09:57 PM
Norm
Re: more help with snake game
Now you see the problem you should be able to fix it.

Done for tonight. Back tomorrow.
• October 4th, 2012, 03:32 PM
godlynom
Re: more help with snake game
I have figured it out, the snake game is up and running, everything works, all the collides and all, now to customize it how i want, thanks so much for your help both times Norm and anyone else who also helped