Thread: Snake Game

Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    12
    Rep Power
    0

    Snake Game


    Hello everybody,

    I am working on a program where I need to create a "Snake Game" program, a game where the snake grows steadily with time and the player must keep the snake from colliding with itself or a wall. I have been given three java class files to begin with, listed below:

    Code:
     import java.awt.Color;
    import java.awt.Font;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.util.ArrayList;
    
    import javax.swing.ImageIcon;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    /**
     * The main game class that reads user input,
     * maintains a snake and updates game board
     * 
     *
     **/
    public class MainGame implements ActionListener {
    
    	// size of the game board (30 * 30 by default)
    	private final int WIDTH = 30;
    	private final int HEIGHT = 30;
    	
    	private final int Init_Snake_Length = 5;
    	
    	// delay of detecting user input ( in milliseconds )
    	private final int DELAY = 100;
    	
    	// grow the snake every GROWTH_INTERVAL milliseconds
    	private final int GROWTH_INTERVAL = 5000;
    	// move the snake every MOVE_INTERVAL milliseconds
    	private final int MOVE_INTERVAL = 500;
    	
    	// The snake (as a list of coordinates in the 2D board array)
    	private ArrayList<Coordinate> snake;
    	
    	// The game board object - read GameBoard.java
    	private GameBoard board; 
    	
    	// Flag variables indicating which direction is chosen
    	// by user. Only one of the four can be true at any moment
    	private boolean left = false;
    	private boolean right = true;
    	private boolean up = false;
    	private boolean down = false;
    
    	private Timer timer;
    	private long growCounter;
    	private long moveCounter;
    	
    	public MainGame() {
    		board = new GameBoard(WIDTH, HEIGHT);
    		initGame();
    		board.addKeyListener(new TAdapter());
    	}
    	
    	public static void main(String[] argv) {
    		MainGame mg = new MainGame();
    	}
    	
    	public void initGame() {
    		snake = new ArrayList<Coordinate>();
    		
    		// -------------------------------------------------------------
    		// Task 1: Initiate the snake to the center of the board
    		// by filling in the coordinates
    		//
    
    		
    		
    		// Task 1 end
    		// -------------------------------------------------------------
    		
    		board.updateSnake(snake);
    		
    		timer = new Timer(DELAY, this);
    		timer.start();
    		growCounter = 0;
    		moveCounter = 0;
    		
    		left = false;
    		right = true;
    		up = false;
    		down = false;		
    	}
    	
    	private void moveSnake() {
    
    		// -------------------------------------------------------------
    		// Task 2: Move the snake by updating the list of coordinates properly
    		// The direction to move to is given by the four flag variables (left, right, up, down)
    		//
    
    		
    		// Task 2 end
    		//--------------------------------------------------------------
    
    	}	
    	
    	private void growSnake() {
    		// -------------------------------------------------------------
    		// Task 3: Grow the snake by updating the list of coordinates properly
    		//
    
    		
    		
    		// Task 3 end
    		//--------------------------------------------------------------
    	}
    
    
    	private void checkCollision() {
    		boolean collision = false;
    		
    		// -------------------------------------------------------------
    		// Task 4: Insert code here to detect collision
    		//
    
    		
    		
    		// Task 4 end
    		//--------------------------------------------------------------		
    		
    		
    		if (collision) {
    			gameOver();
    		}
    	}
    	
    	private void gameOver() {
    		JOptionPane.showMessageDialog(board, "Game Over");
    		System.exit(0);
    	}
    	
    	/**
    	 * The actions to be performed every DELAY milliseconds
    	 */
    	public void actionPerformed(ActionEvent e) {
    		
    		if ( ++growCounter * DELAY >= GROWTH_INTERVAL) {
    			growSnake();
    			growCounter = 0;
    		} 
    		if ( ++moveCounter * DELAY >= MOVE_INTERVAL) {
    			moveSnake();
    			moveCounter = 0;
    		}
    
    		checkCollision();
    		board.resetBoard();
    		board.updateSnake(snake);
    		board.repaint();
    
    	}
    
    
    	/**
    	 * A key listener class for reading user's input.
    	 * 
    	 *
    	 */
    	private class TAdapter extends KeyAdapter {
    
    		public void keyPressed(KeyEvent e) {
    
    			int key = e.getKeyCode();
    
    			if ((key == KeyEvent.VK_LEFT) && (!right)) {
    				left = true;
    				up = false;
    				down = false;
    			}
    
    			if ((key == KeyEvent.VK_RIGHT) && (!left)) {
    				right = true;
    				up = false;
    				down = false;
    			}
    
    			if ((key == KeyEvent.VK_UP) && (!down)) {
    				up = true;
    				right = false;
    				left = false;
    			}
    
    			if ((key == KeyEvent.VK_DOWN) && (!up)) {
    				down = true;
    				right = false;
    				left = false;
    			}
    		}
    	}
    }
    Code:
     import java.awt.Color;
    import java.awt.Frame;
    import java.awt.Graphics;
    import java.awt.Toolkit;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.util.ArrayList;
    
    /**
     * This class represents the board of the snake game
     * and is responsible for drawing the board in graphical
     * mode
     * 
     *
     */
    public class GameBoard extends Frame {
    
    	private static final long serialVersionUID = 1L;
    
    	// Lists all possible types of a board item. You can add more types 
    	// such as SNAKE_HEAD or SNAKE_TAIL if you want to extend the drawing part
    	public enum BoardItem { SNAKE_PART, EMPTY };
    
    	// width & height of the board ( number of cells in 2D array. not actual number of pixels displayed)
    	private int WIDTH;
    	private int HEIGHT;
    	
    	// the 2D array to store the current board information
    	private BoardItem[][] board;
    	
    	private final int PieceSize = 10;
    	private final Color SnakeColor = Color.green;
    	
    	public GameBoard( int WIDTH, int HEIGHT ) {
    		super("COMP 110 - Snake");
    		this.WIDTH = WIDTH;
    		this.HEIGHT = HEIGHT;
    		board = new BoardItem[WIDTH][HEIGHT];
    		this.resetBoard();
    		this.setBackground(Color.black);
    		this.setFocusable(true);
    
    		this.setSize(WIDTH * PieceSize, HEIGHT * PieceSize);
    		this.setVisible(true);
    		this.setLocationRelativeTo(null);
    		this.addWindowListener(new WindowAdapter(){
    			  public void windowClosing(WindowEvent we){
    				  System.exit(0);
    			  }
    			  });
    	
    		this.setResizable(false);
    	}
    	
    	/**
    	 * reset the whole board to empty (without snake)
    	 */
    	public void resetBoard() {
    		for (int i = 0; i<WIDTH; i++)
    			for(int j = 0; j<HEIGHT; j++)
    				board[i][j]	 = BoardItem.EMPTY;
    	}
    	
    	/**
    	 * set one cell of the board to be one of the board item ( SNAKE_PART or EMPTY )
    	 * @param x board cell coordinate X
    	 * @param y board cell coordinate X
    	 * @param i board item type (BoardItem.SNAKE_PART or BoardItem.EMPTY)
    	 */
    	private void setBoardItem( int x, int y, BoardItem i) {
    		board[x][y] = i;
    	}
    	
    	/**
    	 * Accept a snake ( as a list of coordinates )
    	 * Set each coordinate in the 2D board to be of SNAKE type
    	 * @param snake
    	 */
    	public void updateSnake( ArrayList<Coordinate> snake ) {
    		for( Coordinate c : snake) {
    			this.setBoardItem(c.x, c.y, BoardItem.SNAKE_PART);
    		}
    	}
    
    	/**
    	 * draw the game board
    	 */
    	public void paint(Graphics g) {
    		super.paint(g);
    		
    		for (int i = 0; i<WIDTH; i++)
    			for(int j = 0; j<HEIGHT; j++)
    				if (board[i][j] == BoardItem.SNAKE_PART) {
    					g.setColor(SnakeColor);
    					g.fillRect(i*PieceSize, j*PieceSize, PieceSize, PieceSize);
    				}
    		
    		Toolkit.getDefaultToolkit().sync();
    		g.dispose();
    		
    	}
    	
    }
    Code:
     /**
     * A simple coordinate class to represent the 
     * location of an element in a 2D array.
     * 
     *
     */
    public class Coordinate {
    	public int x;
    	public int y;
    	
    	public Coordinate( int x, int y) {
    		this.x = x;
    		this.y = y;
    	}
    	
    }
    I am supposed to fill in the code for tasks 1-4 labeled in MainGame.java. Once the basic tasks are done, I should be able to play a simple snake game that looks like this:
    http://liuyi1.com/comp110/prog/snake.png

    Normally, my first step in program design is creating an outline of the program, listing all of the major steps and the actions I need to take to fulfill them. Luckily, this is already partially done for me, as I can focus my attention on those four tasks described in MainGame.java.

    For step one, I am supposed to initiate the snake to the middle of the board. The gameboard is 30 units by 30 units, so I assume I should initialize the snake at (15,15)? And to accomplish this, should I create a snake constructor and set it to these coordinates?
  2. #2
  3. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,714
    Rep Power
    348
    should I create a snake constructor and set it to these coordinates?
    What determines the "snakes" location? Can it be set in the constructor?
    You should read the code to see.

    What happens when you compile and execute the code?
    Experiment with changing it to get it to do what you want.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    12
    Rep Power
    0
    Originally Posted by NormR
    What determines the "snakes" location? Can it be set in the constructor?
    You should read the code to see.

    What happens when you compile and execute the code?
    Experiment with changing it to get it to do what you want.
    Upon closer reading of the code, I now know that I cannot use a constructor because I am filling in the method body. So far, the method reads

    Code:
     public void initGame() {
    		snake = new ArrayList<Coordinate>();
    		
    		// -------------------------------------------------------------
    		// Task 1: Initiate the snake to the center of the board
    		// by filling in the coordinates
    		//
    
    		
    		
    		// Task 1 end
    		// -------------------------------------------------------------
    		
    		board.updateSnake(snake);
    		
    		timer = new Timer(DELAY, this);
    		timer.start();
    		growCounter = 0;
    		moveCounter = 0;
    		
    		left = false;
    		right = true;
    		up = false;
    		down = false;		
    	}
    According to this, my gut reaction would be to set the snake at (15, 15) under the line of code that reads "snake = new ArrayList<Coordinate>();".

    However, I am not sure to do that. In addition to this problem, I noticed a final static variable labeled Init_Snake_Length that is set to 5. Thus, the snake is initially 5 units long. Does this mean that the head unit should be set to (15, 15) and the four body units set behind it ranging from (11,15) to (14,15)?
  6. #4
  7. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,714
    Rep Power
    348
    Your instructor must expect that you know some java to have given you this assignment.

    The comment:
    Code:
    // Task 1: ...
    looks like the place the author has left open for you to add the code to position the snake.


    To see what is required to be added to the program you need to look at the code that will draw the snake on the screen. Reading and understanding that code will tell you what needs to be done for any snake parts to be drawn.

    If you can not read the code enough to understand what it does, I don't know how you will be able to do this assignment. You might ask your instructor what he expects.
    Last edited by NormR; November 29th, 2012 at 01:43 PM.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    12
    Rep Power
    0
    Sorry, was gone for a few days and didn't have a chance to look at the program, but now I can return to it.

    So, for task one I am supposed to initiate the snake to the center of the board by filling in the coordinates. I see that I already have the code

    Code:
     snake = new ArrayList<Coordinate>();
    So I already have the ArrayList created for me, I just need to change the position where it is initialized. I have been messing around with different ways to do this for a little while now, and I don't know how. I want to change the snake so that the head is initialized at (15,15). I have tried

    Code:
     Coordinate = (15,15);
    Code:
     <Coordinate> = (15,15)
    Code:
     snake<15,15>;
    But none of these would compile. How could I correctly compile this information to get the snake to be where I want it?
  10. #6
  11. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,714
    Rep Power
    348
    You need to use the new statement to call a constructor. See the tutorial:
    http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    12
    Rep Power
    0
    Originally Posted by NormR
    You need to use the new statement to call a constructor.
    I haven't created any constructors though, so do I need to create a new one outside of the method for it to call or modify the default one?
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    12
    Rep Power
    0
    Figured it out actually:

    Code:
     public void initGame() {
    		snake = new ArrayList<Coordinate>();
    		snake.add(new Coordinate (15,15));
    My first major breakthrough! Ha
  16. #9
  17. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,714
    Rep Power
    348
    Glad you got it. Now on to the next task.
  18. #10
  19. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    12
    Rep Power
    0
    Update on my code:

    Code:
     import java.util.*;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.util.ArrayList;
    
    import javax.swing.ImageIcon;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    /**
     * The main game class that reads user input,
     * maintains a snake and updates game board
     * 
     *
     **/
    public class MainGame implements ActionListener {
    
    	// size of the game board (30 * 30 by default)
    	private final int WIDTH = 30;
    	private final int HEIGHT = 30;
    	
    	private final int Init_Snake_Length = 5;
    	
    	// delay of detecting user input ( in milliseconds )
    	private final int DELAY = 100;
    	
    	// grow the snake every GROWTH_INTERVAL milliseconds
    	private final int GROWTH_INTERVAL = 5000;
    	// move the snake every MOVE_INTERVAL milliseconds
    	private final int MOVE_INTERVAL = 500;
    	
    	// The snake (as a list of coordinates in the 2D board array)
    	private ArrayList<Coordinate> snake;
    	
    	// The game board object - read GameBoard.java
    	private GameBoard board; 
    	
    	// Flag variables indicating which direction is chosen
    	// by user. Only one of the four can be true at any moment
    	private boolean left = false;
    	private boolean right = true;
    	private boolean up = false;
    	private boolean down = false;
    
    	private Timer timer;
    	private long growCounter;
    	private long moveCounter;
    	
    	public MainGame() {
    		board = new GameBoard(WIDTH, HEIGHT);
    		initGame();
    		board.addKeyListener(new TAdapter());
    	}
    	
    	public static void main(String[] argv) {
    		MainGame mg = new MainGame();
    	}
    	
    	public void initGame() {
    		snake = new ArrayList<Coordinate>();
    		snake.add(new Coordinate (15,15)); // 0
    		snake.add(new Coordinate (14,15)); // 1 
    		snake.add(new Coordinate (13,15)); // 2
    		snake.add(new Coordinate (12,15)); // 3
    		snake.add(new Coordinate (11,15)); // 4
    		
    		board.updateSnake(snake);
    		
    		timer = new Timer(DELAY, this);
    		timer.start();
    		growCounter = 0;
    		moveCounter = 0;
    		
    		left = false;
    		right = true;
    		up = false;
    		down = false;		
    	}
    	
    	private void moveSnake() {
    		
    		for (int i = snake.size() - 1; i > 0; i--){
    			snake.set(i, snake.get(i-1));
    		}
    		
    		if (right == true) {
    			snake.get(0).x = snake.get(0).x + 1;
    			
    		}
    		
    		if (left == true) {
    			snake.get(0).x = snake.get(0).x-1;
    		}
    			
    		if (up == true) {
    			snake.get(0).y = snake.get(0).y-1;
    		}
    		
    		if (down == true) {
    			snake.get(0).y = snake.get(0).y+1;
    		}
    		
    	}
    I can now get the head of the snake to move around freely, however I cannot get the body of the snake to follow it. The head moves, however the other parts of the snake disappear one by one as the snake head moves. Any suggestions?
  20. #11
  21. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,714
    Rep Power
    348
    The posted code does not compile because of missing method: actionPerformed

    Please post the complete code for the program.
    Last edited by NormR; December 2nd, 2012 at 05:54 PM.
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    12
    Rep Power
    0
    Slight changes made:

    Code:
     import java.util.*;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.util.ArrayList;
    
    import javax.swing.ImageIcon;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    /**
     * The main game class that reads user input,
     * maintains a snake and updates game board
     * 
     *
     **/
    public class MainGame implements ActionListener {
    
    	// size of the game board (30 * 30 by default)
    	private final int WIDTH = 30;
    	private final int HEIGHT = 30;
    	
    	private final int Init_Snake_Length = 5;
    	
    	// delay of detecting user input ( in milliseconds )
    	private final int DELAY = 100;
    	
    	// grow the snake every GROWTH_INTERVAL milliseconds
    	private final int GROWTH_INTERVAL = 5000;
    	// move the snake every MOVE_INTERVAL milliseconds
    	private final int MOVE_INTERVAL = 500;
    	
    	// The snake (as a list of coordinates in the 2D board array)
    	private ArrayList<Coordinate> snake;
    	
    	// The game board object - read GameBoard.java
    	private GameBoard board; 
    	
    	// Flag variables indicating which direction is chosen
    	// by user. Only one of the four can be true at any moment
    	private boolean left = false;
    	private boolean right = true;
    	private boolean up = false;
    	private boolean down = false;
    
    	private Timer timer;
    	private long growCounter;
    	private long moveCounter;
    	
    	public MainGame() {
    		board = new GameBoard(WIDTH, HEIGHT);
    		initGame();
    		board.addKeyListener(new TAdapter());
    	}
    	
    	public static void main(String[] argv) {
    		MainGame mg = new MainGame();
    	}
    	
    	public void initGame() {
    		snake = new ArrayList<Coordinate>();
    		snake.add(new Coordinate (15,15));
    		snake.add(new Coordinate (14,15));
    		snake.add(new Coordinate (13,15));
    		snake.add(new Coordinate (12,15));
    		snake.add(new Coordinate (11,15));
    		
    		board.updateSnake(snake);
    		
    		timer = new Timer(DELAY, this);
    		timer.start();
    		growCounter = 0;
    		moveCounter = 0;
    		
    		left = false;
    		right = true;
    		up = false;
    		down = false;		
    	}
    	
    	private void moveSnake() {
    		
    		for (int i = snake.size() - 1; i > 0; i--){
    			snake.set(i, snake.get(i-1));
    		
    		
    		if (right == true) {
    			snake.get(i).x = snake.get(i).x + 1;
    			
    		}
    		
    		if (left == true) {
    			snake.get(i).x = snake.get(i).x-1;
    		}
    			
    		if (up == true) {
    			snake.get(i).y = snake.get(i).y-1;
    		}
    		
    		if (down == true) {
    			snake.get(i).y = snake.get(i).y+1;
    		}
    		
    		}	
    	}
    			
    
    		// -------------------------------------------------------------
    		// Task 2: Move the snake by updating the list of coordinates properly
    		// The direction to move to is given by the four flag variables (left, right, up, down)
    		//
    
    		
    		// Task 2 end
    		//--------------------------------------------------------------
    
    		
    	
    	private void growSnake() {
    		// -------------------------------------------------------------
    		// Task 3: Grow the snake by updating the list of coordinates properly
    		//
    
    		
    		
    		// Task 3 end
    		//--------------------------------------------------------------
    	}
    
    
    	private void checkCollision() {
    		boolean collision = false;
    		
    		// -------------------------------------------------------------
    		// Task 4: Insert code here to detect collision
    		//
    
    		
    		
    		// Task 4 end
    		//--------------------------------------------------------------		
    		
    		
    		if (collision) {
    			gameOver();
    		}
    	}
    	
    	private void gameOver() {
    		JOptionPane.showMessageDialog(board, "Game Over");
    		System.exit(0);
    	}
    	
    	/**
    	 * The actions to be performed every DELAY milliseconds
    	 */
    	public void actionPerformed(ActionEvent e) {
    		
    		if ( ++growCounter * DELAY >= GROWTH_INTERVAL) {
    			growSnake();
    			growCounter = 0;
    		} 
    		if ( ++moveCounter * DELAY >= MOVE_INTERVAL) {
    			moveSnake();
    			moveCounter = 0;
    		}
    
    		checkCollision();
    		board.resetBoard();
    		board.updateSnake(snake);
    		board.repaint();
    
    	}
    
    
    	/**
    	 * A key listener class for reading user's input.
    	 * 
    	 *
    	 */
    	private class TAdapter extends KeyAdapter {
    
    		public void keyPressed(KeyEvent e) {
    
    			int key = e.getKeyCode();
    
    			if ((key == KeyEvent.VK_LEFT) && (!right)) {
    				left = true;
    				up = false;
    				down = false;
    			}
    
    			if ((key == KeyEvent.VK_RIGHT) && (!left)) {
    				right = true;
    				up = false;
    				down = false;
    			}
    
    			if ((key == KeyEvent.VK_UP) && (!down)) {
    				up = true;
    				right = false;
    				left = false;
    			}
    
    			if ((key == KeyEvent.VK_DOWN) && (!up)) {
    				down = true;
    				right = false;
    				left = false;
    			}
    		}
    	}
    }
    When I run this, I get a 5 unit long snake appear in the middle of the grid as expected. The snake also initially moves to the right, as expected. However, only the head moves and the rest of the body disappears.
  24. #13
  25. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,714
    Rep Power
    348
    Please edit your post and wrap the code in code tags.

    Try debugging the code by adding printlns that show what the values of the variables that control where the snake's sections are printed.
  26. #14
  27. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    12
    Rep Power
    0
    Code:
    import java.util.*;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.util.ArrayList;
    
    import javax.swing.ImageIcon;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    /**
     * The main game class that reads user input,
     * maintains a snake and updates game board
     * 
     *
     **/
    public class MainGame implements ActionListener {
    
    	// size of the game board (30 * 30 by default)
    	private final int WIDTH = 30;
    	private final int HEIGHT = 30;
    	
    	private final int Init_Snake_Length = 5;
    	
    	// delay of detecting user input ( in milliseconds )
    	private final int DELAY = 100;
    	
    	// grow the snake every GROWTH_INTERVAL milliseconds
    	private final int GROWTH_INTERVAL = 5000;
    	// move the snake every MOVE_INTERVAL milliseconds
    	private final int MOVE_INTERVAL = 500;
    	
    	// The snake (as a list of coordinates in the 2D board array)
    	private ArrayList<Coordinate> snake;
    	
    	// The game board object - read GameBoard.java
    	private GameBoard board; 
    	
    	// Flag variables indicating which direction is chosen
    	// by user. Only one of the four can be true at any moment
    	private boolean left = false;
    	private boolean right = true;
    	private boolean up = false;
    	private boolean down = false;
    
    	private Timer timer;
    	private long growCounter;
    	private long moveCounter;
    	
    	public MainGame() {
    		board = new GameBoard(WIDTH, HEIGHT);
    		initGame();
    		board.addKeyListener(new TAdapter());
    	}
    	
    	public static void main(String[] argv) {
    		MainGame mg = new MainGame();
    	}
    	
    	public void initGame() {
    		snake = new ArrayList<Coordinate>();
    		snake.add(new Coordinate (15,15));
    		snake.add(new Coordinate (14,15));
    		snake.add(new Coordinate (13,15));
    		snake.add(new Coordinate (12,15));
    		snake.add(new Coordinate (11,15));
    		
    		board.updateSnake(snake);
    		
    		timer = new Timer(DELAY, this);
    		timer.start();
    		growCounter = 0;
    		moveCounter = 0;
    		
    		left = false;
    		right = true;
    		up = false;
    		down = false;		
    	}
    	
    	private void moveSnake() {
    		
    		
    		if (right == true) 
    		{
    			snake.get(0).x = snake.get(0).x + 1;
    			snake.get(1).x = snake.get(1).x + 1;
    			snake.get(2).x = snake.get(2).x + 1;
    			snake.get(3).x = snake.get(3).x + 1;
    			snake.get(4).x = snake.get(4).x + 1;
    		}
    			
    			
    		
    		if (left == true) 
    		{
    			snake.get(0).x = snake.get(0).x - 1;
    			snake.get(1).x = snake.get(1).x - 1;
    			snake.get(2).x = snake.get(2).x - 1;
    			snake.get(3).x = snake.get(3).x - 1;
    			snake.get(4).x = snake.get(4).x - 1;
    		}
    			
    		if (up == true) 
    		{
    			snake.get(0).y = snake.get(0).y-  1;
    			snake.get(1).y = snake.get(1).y - 1;
    			snake.get(2).y = snake.get(2).y - 1;
    			snake.get(3).y = snake.get(3).y - 1;
    			snake.get(4).y = snake.get(4).y - 1;
    		}
    
    		
    		if (down == true) 
    		{
    			snake.get(0).y = snake.get(0).y + 1;
    			snake.get(1).y = snake.get(1).y + 1;
    			snake.get(2).y = snake.get(2).y + 1;
    			snake.get(3).y = snake.get(3).y + 1;
    			snake.get(4).y = snake.get(4).y + 1;
    		
    		}
    		
    		}		
    
    		// -------------------------------------------------------------
    		// Task 2: Move the snake by updating the list of coordinates properly
    		// The direction to move to is given by the four flag variables (left, right, up, down)
    		//
    
    		
    		// Task 2 end
    		//--------------------------------------------------------------
    
    		
    	
    	private void growSnake() {
    		// -------------------------------------------------------------
    		// Task 3: Grow the snake by updating the list of coordinates properly
    		//
    
    		
    		
    		// Task 3 end
    		//--------------------------------------------------------------
    	}
    
    
    	private void checkCollision() {
    		boolean collision = false;
    		
    		// -------------------------------------------------------------
    		// Task 4: Insert code here to detect collision
    		//
    
    		
    		
    		// Task 4 end
    		//--------------------------------------------------------------		
    		
    		
    		if (collision) {
    			gameOver();
    		}
    	}
    	
    	private void gameOver() {
    		JOptionPane.showMessageDialog(board, "Game Over");
    		System.exit(0);
    	}
    	
    	/**
    	 * The actions to be performed every DELAY milliseconds
    	 */
    	public void actionPerformed(ActionEvent e) {
    		
    		if ( ++growCounter * DELAY >= GROWTH_INTERVAL) {
    			growSnake();
    			growCounter = 0;
    		} 
    		if ( ++moveCounter * DELAY >= MOVE_INTERVAL) {
    			moveSnake();
    			moveCounter = 0;
    		}
    
    		checkCollision();
    		board.resetBoard();
    		board.updateSnake(snake);
    		board.repaint();
    
    	}
    
    
    	/**
    	 * A key listener class for reading user's input.
    	 * 
    	 *
    	 */
    	private class TAdapter extends KeyAdapter {
    
    		public void keyPressed(KeyEvent e) {
    
    			int key = e.getKeyCode();
    
    			if ((key == KeyEvent.VK_LEFT) && (!right)) {
    				left = true;
    				up = false;
    				down = false;
    			}
    
    			if ((key == KeyEvent.VK_RIGHT) && (!left)) {
    				right = true;
    				up = false;
    				down = false;
    			}
    
    			if ((key == KeyEvent.VK_UP) && (!down)) {
    				up = true;
    				right = false;
    				left = false;
    			}
    
    			if ((key == KeyEvent.VK_DOWN) && (!up)) {
    				down = true;
    				right = false;
    				left = false;
    			}
    		}
    	}
    }
    Now, I have a 5-unit snake that I can move left, right, up, and down. Only problem is instead of the head directing the way as normal snake games should be, all 5 blocks move in unison, so if I press the up arrow, all five blocks are shifted u one space instead of only the head going up.

    I need to figure out a loop that constantly shifts the position of the snake in accordance with the head. For example, if the head moves from its original coordinates of (15,15) one space to the right to (16,15), I want the other four parts of the body to fill in the ordered pair occupied previously by the block in front of it.
  28. #15
  29. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    12
    Rep Power
    0
    Code:
    import java.util.*;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.FontMetrics;
    import java.awt.Graphics;
    import java.awt.Image;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.util.ArrayList;
    
    import javax.swing.ImageIcon;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    /**
     * The main game class that reads user input,
     * maintains a snake and updates game board
     * 
     *
     **/
    public class MainGame implements ActionListener {
    
    	// size of the game board (30 * 30 by default)
    	private final int WIDTH = 30;
    	private final int HEIGHT = 30;
    	
    	private final int Init_Snake_Length = 5;
    	
    	// delay of detecting user input ( in milliseconds )
    	private final int DELAY = 100;
    	
    	// grow the snake every GROWTH_INTERVAL milliseconds
    	private final int GROWTH_INTERVAL = 5000;
    	// move the snake every MOVE_INTERVAL milliseconds
    	private final int MOVE_INTERVAL = 500;
    	
    	// The snake (as a list of coordinates in the 2D board array)
    	private ArrayList<Coordinate> snake;
    	
    	// The game board object - read GameBoard.java
    	private GameBoard board; 
    	
    	// Flag variables indicating which direction is chosen
    	// by user. Only one of the four can be true at any moment
    	private boolean left = false;
    	private boolean right = true;
    	private boolean up = false;
    	private boolean down = false;
    
    	private Timer timer;
    	private long growCounter;
    	private long moveCounter;
    	
    	public MainGame() {
    		board = new GameBoard(WIDTH, HEIGHT);
    		initGame();
    		board.addKeyListener(new TAdapter());
    	}
    	
    	public static void main(String[] argv) {
    		MainGame mg = new MainGame();
    	}
    	
    	public void initGame() {
    		snake = new ArrayList<Coordinate>();
    		snake.add(new Coordinate (15,15));
    		snake.add(new Coordinate (14,15));
    		snake.add(new Coordinate (13,15));
    		snake.add(new Coordinate (12,15));
    		snake.add(new Coordinate (11,15));
    		
    		board.updateSnake(snake);
    		
    		timer = new Timer(DELAY, this);
    		timer.start();
    		growCounter = 0;
    		moveCounter = 0;
    		
    		left = false;
    		right = true;
    		up = false;
    		down = false;		
    	}
    	
    	private void moveSnake() {
    		
    		
    		if (right == true) 
    		{
    			snake.get(0).x = snake.get(0).x + 1;
    			snake.get(1).x = snake.get(1).x + 1;
    			snake.get(2).x = snake.get(2).x + 1;
    			snake.get(3).x = snake.get(3).x + 1;
    			snake.get(4).x = snake.get(4).x + 1;
    		}
    			
    			
    		
    		if (left == true) 
    		{
    			snake.get(0).x = snake.get(0).x - 1;
    			snake.get(1).x = snake.get(1).x - 1;
    			snake.get(2).x = snake.get(2).x - 1;
    			snake.get(3).x = snake.get(3).x - 1;
    			snake.get(4).x = snake.get(4).x - 1;
    		}
    			
    		if (up == true) 
    		{
    			snake.get(0).y = snake.get(0).y-  1;
    			snake.get(1).y = snake.get(1).y - 1;
    			snake.get(2).y = snake.get(2).y - 1;
    			snake.get(3).y = snake.get(3).y - 1;
    			snake.get(4).y = snake.get(4).y - 1;
    		}
    
    		
    		if (down == true) 
    		{
    			snake.get(0).y = snake.get(0).y + 1;
    			snake.get(1).y = snake.get(1).y + 1;
    			snake.get(2).y = snake.get(2).y + 1;
    			snake.get(3).y = snake.get(3).y + 1;
    			snake.get(4).y = snake.get(4).y + 1;
    		
    		}
    		
    		}		
    
    		// -------------------------------------------------------------
    		// Task 2: Move the snake by updating the list of coordinates properly
    		// The direction to move to is given by the four flag variables (left, right, up, down)
    		//
    
    		
    		// Task 2 end
    		//--------------------------------------------------------------
    
    		
    	
    	private void growSnake() {
    		// -------------------------------------------------------------
    		// Task 3: Grow the snake by updating the list of coordinates properly
    		//
    
    		
    		
    		// Task 3 end
    		//--------------------------------------------------------------
    	}
    
    
    	private void checkCollision() {
    		boolean collision = false;
    		
    		// -------------------------------------------------------------
    		// Task 4: Insert code here to detect collision
    		//
    
    		
    		
    		// Task 4 end
    		//--------------------------------------------------------------		
    		
    		
    		if (collision) {
    			gameOver();
    		}
    	}
    	
    	private void gameOver() {
    		JOptionPane.showMessageDialog(board, "Game Over");
    		System.exit(0);
    	}
    	
    	/**
    	 * The actions to be performed every DELAY milliseconds
    	 */
    	public void actionPerformed(ActionEvent e) {
    		
    		if ( ++growCounter * DELAY >= GROWTH_INTERVAL) {
    			growSnake();
    			growCounter = 0;
    		} 
    		if ( ++moveCounter * DELAY >= MOVE_INTERVAL) {
    			moveSnake();
    			moveCounter = 0;
    		}
    
    		checkCollision();
    		board.resetBoard();
    		board.updateSnake(snake);
    		board.repaint();
    
    	}
    
    
    	/**
    	 * A key listener class for reading user's input.
    	 * 
    	 *
    	 */
    	private class TAdapter extends KeyAdapter {
    
    		public void keyPressed(KeyEvent e) {
    
    			int key = e.getKeyCode();
    
    			if ((key == KeyEvent.VK_LEFT) && (!right)) {
    				left = true;
    				up = false;
    				down = false;
    			}
    
    			if ((key == KeyEvent.VK_RIGHT) && (!left)) {
    				right = true;
    				up = false;
    				down = false;
    			}
    
    			if ((key == KeyEvent.VK_UP) && (!down)) {
    				up = true;
    				right = false;
    				left = false;
    			}
    
    			if ((key == KeyEvent.VK_DOWN) && (!up)) {
    				down = true;
    				right = false;
    				left = false;
    			}
    		}
    	}
    }
    Now, I have a 5-unit snake that I can move left, right, up, and down. Only problem is instead of the head directing the way as normal snake games should be, all 5 blocks move in unison, so if I press the up arrow, all five blocks are shifted up one space instead of only the head going up.

    I need to figure out a loop that constantly shifts the position of the snake in accordance with the head. For example, if the head moves from its original coordinates of (15,15) one space to the right to (16,15), I want the other four parts of the body to fill in the ordered pair occupied previously by the block in front of it.
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo