I am having trouble creating the snake, let alone making the animation. I need someone to assist me in creating such things, as well as helping me complete the program. Thanks

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
 * @(#)SnakeGame.java
 *
 *
 * @author 
 * @version 1.00 2009/4/30
 */


public class SnakeGame extends JFrame
{
	// the starting position for the food
		private int foodX = 180;
   		private int foodY = 120;
   	
   		// the starting position for the snake
   		private int snakeX = 240;
   		private int snakeY = 168;
	
	// the time delay for the snake
	private final int TIME_DELAY = 1;
	
	// Timer for the Snake
	private Timer timeSnake;
	
	// Make sure the moving is working	
	private boolean movingOn = true;
	
	// the minimum range for the snake
	private final int MINIMUM_Y = 0;
	
	// the maximum range for the snake
	private final int MAXIMUM_Y = 240;
	
	// the minimum domain for the snake
	private final int MINIMUM_X = 0;
	
	// the maximum domain for the snake
	private final int MAXIMUM_X = 360;
	
	
	
	// Creates the keyboard panel for the computer to read the keyboard.
	private KeyboardPanel keyboardPanel = new KeyboardPanel();

		
		
	// TimerListener for the animation
	private class TimerListener implements ActionListener
   	{
   		public void actionPerformed(ActionEvent e)
   		{
   			if(movingOn)
   			{
   				if(snakeY < MINIMUM_Y && snakeX < MINIMUM_X)
   				{
   				 	System.exit(0);
   				}	
   				 else
   				 	movingOn = false;		
   			}
   			else
   			{
   				if (snakeY < MAXIMUM_Y)
   				{
   					snakeX += 4 ;
   					snakeY += 4;
   				}
   				else
   					movingOn = true;	
   			}
   			repaint();
   		}
   	}	
	
	// class for the Snake Game
	public SnakeGame()
	{
	
	  /*add(new Food());*/
	  
	  add(keyboardPanel);
	  
	  keyboardPanel.setFocusable(true);
	 
	  timeSnake = new Timer(TIME_DELAY, new TimerListener());
	  
	  
	  
	/**
	 * the KeyboardPanel class is for the receiving the 
	 * key input.
	 */  
	}
	
	 class KeyboardPanel extends JPanel
	{
		
   	
   	// Controls the snakes movements	
	public KeyboardPanel()
	{
	addKeyListener(new KeyAdapter()
	  {
	  	public void keyPressed(KeyEvent e)
	  	{
	  		switch(e.getKeyCode())
	  		{
	  			case KeyEvent.VK_DOWN: snakeY+= 8; break;
	  			case KeyEvent.VK_UP:  snakeY-= 8; break;
	  			case KeyEvent.VK_RIGHT: snakeX += 8; break;
	  			case KeyEvent.VK_LEFT: snakeX -= 8; break;
	  			default: e.getKeyChar();
	  		}
	  		
	  		repaint();
	  	}
	  });
	}
	
		public void paintComponent(Graphics g)
   		{
   		
   			super.paintComponent(g);
   			g.setColor(Color.red);
   			g.fillRect(foodX, foodY, 8, 8);
   		
   			g.setColor(Color.green);
   			g.fillOval(snakeX, snakeY, 8, 8);
   		}	
	}
	// Main class
    public static void main(String [] args)
    {
    	SnakeGame snake = new SnakeGame();
    	
    	snake.setSize(360, 240);
    	
    	snake.setTitle("SNAKE");
    	
    	// centers the frame
    	snake.setLocationRelativeTo(null);
    	
    	snake.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	
    	snake.setVisible(true);
    	
    }
    
   /* creates the components for the food and snake
   class Food extends JPanel
   {
   	
   		
   	
   	}*/
   	
   	
   	}

Dani AI

Generated

Quick summary and a simple roadmap to fix the problems shown in the thread (especially the movement/boundary bug and how to extend the body). already has a working display and keyboard input; the remaining issues are mostly logic and coordinate-management, not Swing magic.

Start with a single, consistent model

  • Use a fixed cell size (8–10 px) and treat the board as a grid. Move the head by exactly one cell per Timer tick (or per logical step).
  • Keep the snake body as an ordered ArrayList<Point> (head at index 0). On each move compute a new head position from the current direction, insert it at index 0, and remove the last element unless food was eaten. This makes growing, redrawing and self-collision checks straightforward. (This follows the conceptual advice from but puts it into a concrete, grid-based workflow.)

Fix the boundary / focus / timer issues

  • Don’t gate boundary checks behind a confusing boolean like movingOn. Let the Timer always call the same “step” routine; that routine moves the snake if a direction is set and then checks collisions. If you want pause, use an explicit paused flag toggled by a key. That eliminates the toggle bug you saw in your prints.
  • Compute wall limits from the actual play area: use panel.getWidth()/getHeight() (or setPreferredSize + pack()) and subtract margins and the cell size. Hard-coded constants that don’t match the drawable area cause the snake to run off-screen.
  • KeyListener requires focus; call requestFocusInWindow() on the game panel or, preferably, switch to Swing Key Bindings so arrow presses are reliable.

Drawing and debugging tips

  • Always override paintComponent and call super.paintComponent(g). Iterate the segment list and draw each segment (or an image) from its Point coordinates. Draw walls relative to the panel size.
  • During debugging, stop calling System.exit on collision; instead stop the Timer and print the head coordinates or show a dialog so you can inspect values. Add temporary printlns to verify the cell grid aligns with the drawn rectangle and that increments equal the cell size.

These steps keep the design simple and make it easy to add fruit, walls, and collision detection incrementally. The animation tutorial mentioned earlier (see ’s post) is a good read for Timer basics, and ’s high‑level checklist is a solid design guide.

Recommended Answers

All 11 Replies

Dear,

Please honour to our community. Post your code problems not your problems.

Dear,

Please honour to our community. Post your code problems not your problems.

I don't know how to name the problem in code form, thats why i am asking for help. I am brand new to animation and i wanted to know if any of it can be tweaked instead of starting anew, if possible. My apologies for not being more descriptive

A member here suggested this tutorial on animation a few days ago:

I don't know how helpful it will be, or if it answers your question, just passing it along since it is an animation tutorial suggested by a reliable member here.

Seems to me a Snake has several things:

1. Number of segments in its body.
2. (x,y) location of each segment of its body.
3. Direction its head is moving (north, south, east, west)
4. Its velocity (reciprocal of the amount of time it takes for the snake to move one pixel).
5. Color of Snake's head.
6. Color of Snake's body.

For #2 above, have an ordered Collection of pixel points (ArrayList or Vector would work well here).

Have a paint function in the Snake class that paints the snake by painting each coordinate in 2 above.

Your game will have walls. Those walls need coordinates and a color. The interior needs to have a color. You need a function to check whether there the snake has collided with the wall or with itself.

You need a function that moves the snake in a certain direction.

You need a Listener of some kind in order to change directions (KeyListener or ActionListener attached to a Button probably).

All this comes before any Runnable threads, timers, or animation. If you get this underlying part down, the animation is simply repainting that snake every time a timer fires or a thread finishes sleeping. Start with just being able to move the snake around manually with your keyboard or buttons. Then you can add fruits to the game and the ability to have the snake increase in length. Then add the animation, timers, etc.

Thanks for the help. I want to know how do you create the barriers for the walls. And as far as the body goes, using the ArrayList, how would I copy the image so the image is added on the body?

Thanks for the help. I want to know how do you create the barriers for the walls. And as far as the body goes, using the ArrayList, how would I copy the image so the image is added on the body?

Image? What image? I was thinking you would draw a rectangle on a panel using fillRect.

Ditto with the walls. They'll have coordinates and you'll paint a rectangle onto your JPanel (or whatever you're using for the game playing area). If you have an image you want to draw instead, use one of the drawImage functions.

well yeah. As of now, i do have the original snake icon as a drawImage figure. FillOval. Im saying to copy the rectangle to extned the body, do i keep calling the Graphics class, or is that possible?

well yeah. As of now, i do have the original snake icon as a drawImage figure. FillOval. Im saying to copy the rectangle to extned the body, do i keep calling the Graphics class, or is that possible?

By Image, I assume you are referring to the Image class and are planning on painting that image (for example, an Image created from a JPEG photo). fillOval is similar to fillRect, except it's an oval rather than rectangle. It's unrelated to Images, as far as I can see.

I was thinking along the lines of, if you have a Snake with five segments (each segment being a 10 x 10 square) and the five segments are located at (50,50), (50, 60), (50,70), (50, 80), (50,90), you'd have these lines somewhere:

g.drawRect (50, 50, 10, 10);
g.drawRect (50, 60, 10, 10);
g.drawRect (50, 70, 10, 10);
g.drawRect (50, 80, 10, 10);
g.drawRect (50, 90, 10, 10);

You'd implement this in a loop and use variables instead of hard-coding these values, but you'd have one call to drawRect for each segment in the snake's body.

Walls could be rectangles too. Again, you have coordinates and thickness. Obviously the wall needs to be a different color from the snake, which needs to be a different color from the open space, which needs to be a different color from the fruits. But the concept is the same. Each time the snake moves or gets longer or a fruit appears or disappears, you repaint everything.

I really appreciate the help by the way. I am kind of new to all these GUI operations, seeing that this was the last lesson we learned in my programming class before our exams, so it was rushed. But I wanted to show you what i have so far. When i compile and run it, it shows the window with the box, the snake( a green oval), and food( a red box). When i use the arrows, the snake moves but it overruns the box and goes past the window. I thought i had set the barrier with the TimeListener, but i don't work.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


/**
 * @(#)SnakeGame.java
 *
 *
 * @author 
 * @version 1.00 2009/4/30
 */


public class SnakeGame extends JFrame
{
	// the starting position for the food
		private int foodX = 180;
   		private int foodY = 120;
   	
   		// the starting position for the snake
   		private int snakeX = 220;
   		private int snakeY = 168;
	
	// the time delay for the snake
	private final int TIME_DELAY = 25;
	
	// Timer for the Snake
	private Timer timeSnake;
	
	// Make sure the moving is working	
	private boolean movingOn = true;
	
	private int arrowNum;
	
	// the minimum range for the snake
	private final int BARRIER_MIN_Y = 10;
	
	// the maximum range for the snake
	private final int BARRIER_Y = 280;
	
	// the minimum domain for the snake
	private final int BARRIER_MIN_X = 10;
	
	// the maximum domain for the snake
	private final int BARRIER_X = 390;

	
	
	
	
	// Creates the keyboard panel for the computer to read the keyboard.
	private KeyboardPanel keyboardPanel = new KeyboardPanel();

		
		
	// TimerListener for the animation
	private class TimerListener implements ActionListener
   	{
   		public void actionPerformed(ActionEvent e)
   		{
   			if(movingOn)
   			{
   				if(snakeY < BARRIER_MIN_Y || snakeX < BARRIER_MIN_X)
   				{
   				 	System.exit(0);
   				}	
   				else if(snakeY > BARRIER_Y || snakeX > BARRIER_X)
   				{
   					System.exit(0);
   				}	
   				 else
   				 	movingOn = false;		
   			}
   			else
   			{
   				if (arrowNum == 1)
   				{
   					snakeY += 2;
   				}
   				else if(arrowNum == 2)
   				{
   					snakeY -= 2;
   				}
   				else if(arrowNum == 3)
   				{
   					snakeX += 2;
   				}
   				else if(arrowNum == 4)
   				{
   					snakeX -= 2;
   				}			
   				else
   					movingOn = true;	
   			}
   			repaint();
   		}
   	}	
	
	// class for the Snake Game
	public SnakeGame()
	{
	
	  add(keyboardPanel);
	  
	  keyboardPanel.setFocusable(true);
	 
	  timeSnake = new Timer(TIME_DELAY, new TimerListener());
	  timeSnake.start();
	  
	  
	  
	/**
	 * the KeyboardPanel class is for the receiving the 
	 * key input.
	 */  
	}


	
	 class KeyboardPanel extends JPanel
	{
		
   	
   	/* 
   	 *
   	 * Controls the snakes movements	
   	 *
   	 */
	public KeyboardPanel()
	{
	addKeyListener(new KeyAdapter()
	  {
	  	public void keyPressed(KeyEvent e)
	  	{
	  		switch(e.getKeyCode())
	  		{
	  			case KeyEvent.VK_DOWN:
	  				 arrowNum = 1;
	  				 snakeY+= 1; break;
	  			case KeyEvent.VK_UP:  
	  				arrowNum = 2;
	  				snakeY-= 1; break;
	  			case KeyEvent.VK_RIGHT:
	  				 arrowNum = 3;
	  				 snakeX += 1; break;
	  			case KeyEvent.VK_LEFT: 
	  				arrowNum = 4;
	  				snakeX -= 1; 
	  				break;
	  			default: e.getKeyChar();
	  		}
	  		
	  		repaint();
	  	}
	  });
	}
	
		public void paintComponent(Graphics g)
   		{
   		
   			super.paintComponent(g);
   			g.setColor(Color.red);
   			g.fillRect(foodX, foodY, 9, 9);
   		
   			g.setColor(Color.green);
   			g.fillOval(snakeX, snakeY, 9, 9);
   			
   			g.setColor(Color.blue);
   			g.drawRect(10, 10, 280, 390);
   		}	
	}

	/***
	 *
	 * This class is the main class that creates the frame for the game and calls
	 * the game
	 *
	 *
	 *
	 */
	
    public static void main(String [] args)
    {
    	SnakeGame snake = new SnakeGame();
    	
    	snake.setSize(360, 450);
    	
    	snake.setTitle("SNAKE");
    	
    	// centers the frame
    	snake.setLocationRelativeTo(null);
    	
    	snake.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	
    	snake.setVisible(true);
    	
    }
}

I am guessing that the problem is here, and concerns the variable movingOn . What does movingOn represent? Is it true if the snake is moving, false otherwise? It seems to me that very possibly once movingOn is set to false, it will never again be set to true. If it is never again set to true, will the barrier condition ever be tested? In other words, will lines 37 and 38 ever be executed, and if they are not, will lines 8 through 17 ever be executed after the initial keypress? Stick some breakpoints or System.out.println debugging statements in that if-block to see what I mean. After movement begins, the block of code from line 8 - 17 doesn't appear to ever be executed.

// TimerListener for the animation
	private class TimerListener implements ActionListener
   	{
   		public void actionPerformed(ActionEvent e)
   		{
   			if(movingOn)
   			{
   				if(snakeY < BARRIER_MIN_Y || snakeX < BARRIER_MIN_X)
   				{
   				 	System.exit(0);
   				}	
   				else if(snakeY > BARRIER_Y || snakeX > BARRIER_X)
   				{
   					System.exit(0);
   				}	
   				 else
   				 	movingOn = false;		
   			}
   			else
   			{
   				if (arrowNum == 1)
   				{
   					snakeY += 2;
   				}
   				else if(arrowNum == 2)
   				{
   					snakeY -= 2;
   				}
   				else if(arrowNum == 3)
   				{
   					snakeX += 2;
   				}
   				else if(arrowNum == 4)
   				{
   					snakeX -= 2;
   				}			
   				else
   					movingOn = true;	
   			}
   			repaint();
   		}
   	}

When i take out the " if(movingOn)" and the "else" the snake is moving as it normally should. I also switched the boolean, but i am not sure if this is true.

public void actionPerformed(ActionEvent e)
   		{
   			
   			System.out.println("movingOn: " + movingOn);
   			/*if(movingOn)
   			{*/
   				if(snakeY <= BARRIER_MIN_Y || snakeX <= BARRIER_MIN_X)
   				{
   				 	movingOn = false;
   				 	System.exit(0);
   				 	
   				}	
   				else if(snakeY >= BARRIER_Y || snakeX >= BARRIER_X)
   				{
   					movingOn = false;
   					System.exit(0);
   				}	
   				 else
   				 	movingOn = true;		
   			/*}
   			else
   			{*/
   				if (arrowNum == 1)
   				{
   					snakeY += 2;
   				}
   				else if(arrowNum == 2)
   				{
   					snakeY -= 2;
   				}
   				else if(arrowNum == 3)
   				{
   					snakeX += 2;
   				}
   				else if(arrowNum == 4)
   				{
   					snakeX -= 2;
   				}			
   				else
   					movingOn = false;	
   			/*}*/
   			repaint();
   		}
   	}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.