The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> Java Help
|
Page 2 -
Snake Game
Page 2 - Discuss Snake Game in the Java Help forum on Dev Shed. Snake Game Java Help forum discussing all Java platforms - J2ME, J2SE and J2EE - as well as relevant standards, APIs and frameworks such as Swing, Servlets, JSPs, Applets, Struts, Spring, Hibernate, ANT, EJB, and other Java-related topics.
|
|
 |
|
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

December 2nd, 2012, 06:59 PM
|
|
Registered User
|
|
Join Date: Nov 2012
Posts: 12
Time spent in forums: 2 h 36 m 46 sec
Reputation Power: 0
|
|
I'm thinking that the loop should look something like this:
Code:
for (int i = snake.size() - 1; i > 0; i--) {
/* something to make a specific index of the snake take the spot
of the one preceding it, so I know that for the left and right commands it will
somehow involve snake.some method or code.x = snake.some method or code.x + 1 */
}
Any hints on this?
|

December 2nd, 2012, 07:00 PM
|
 |
Contributing User
|
|
Join Date: Aug 2010
Location: Eastern Florida
|
|
Quote: | so if I press the up arrow, all five blocks are shifted up one space instead of only the head going up. |
How should the code print the motion of the body of the snake? The following sections need to continue in the same direction until they get to the turning point before changing direction. They can not ALL change direction at the same time.
|

December 2nd, 2012, 07:09 PM
|
|
Registered User
|
|
Join Date: Nov 2012
Posts: 12
Time spent in forums: 2 h 36 m 46 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by NormR How should the code print the motion of the body of the snake? The following sections need to continue in the same direction until they get to the turning point before changing direction. They can not ALL change direction at the same time. |
Precisely. My intention is to use the head of the snake as a guide for the user, so that when the player enters an arrow key it moves the head in the corresponding direction. However, that leaves the issue of the rest of the body. I want the rest of the body to take the position of the block that came before it. So let's take the default snake:
Code:
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;
}
This initializes the snake from a range of (11,15) to the head of (15,15). Now, lets say that I want to move the head up. The correct coordinates should be:
(12,15) , (13,15) , (14,15) , (15,15) and (15,16) and the snake should should make the following transformation:
-------------------------------------x
xxxxx (default snake) to ---> xxxx (new snake)
I don't know how to move the head up one y-value unit without moving the rest of the body up. How can I do this?
|

December 2nd, 2012, 07:13 PM
|
 |
Contributing User
|
|
Join Date: Aug 2010
Location: Eastern Florida
|
|
|
Work on the logic before writing any code. What are the steps the program needs to do to have each part of the body continue in the current direction until it gets to the turning point before starting to move in the new direction. The body sections change direction one at a time.
|

December 2nd, 2012, 09:01 PM
|
|
Registered User
|
|
Join Date: Nov 2012
Posts: 12
Time spent in forums: 2 h 36 m 46 sec
Reputation Power: 0
|
|
Been working for a few more hours now...up to this:
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)); //head
snake.add(new Coordinate (14,15)); // upper body
snake.add(new Coordinate (13,15)); // middle body
snake.add(new Coordinate (12,15)); // lower body
snake.add(new Coordinate (11,15)); // tail
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;
for (int i = 1; i < snake.size() -1; i++)
{
snake.get(i).x = snake.get(i+1).x;
}
}
if (left == true)
{
snake.get(0).x = snake.get(0).x - 1;
for (int i = 1; i < snake.size() -1; i++)
{
snake.get(i).x = snake.get(i+1).x;
}
}
if (up == true)
{
snake.get(0).y = snake.get(0).y - 1;
for (int i = 1; i < snake.size() -1; i++)
{
snake.get(i).y = snake.get(i+1).y;
}
}
if (down == true)
{
snake.get(0).y = snake.get(0).y + 1;
for (int i = 1; i < snake.size() -1; i++)
{
snake.get(i).y = snake.get(i+1).y;
}
}
}
// -------------------------------------------------------------
// 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;
}
}
}
}
I've tried to think through it as logically as possibly, changed and tested my code at least 50 times, however now when I run my program it begins correctly with the head moving to the right, however the rest of the body dissipates except for the tail at (11,15). What is the cause of this?
|

December 2nd, 2012, 09:05 PM
|
 |
Contributing User
|
|
Join Date: Aug 2010
Location: Eastern Florida
|
|
|
Try debugging the code by printing out the values of the variables so you can see what the code is doing when it executes.
Can you post the steps in your logic (as pseudo code) so we can see it?
I'm done for tonight. Back tomorrow.
|

December 3rd, 2012, 03:15 AM
|
|
|
May I suggest a different approach?
As of now you iterate over the snake arraylist and update each snake-coordinate to the value of the next snake-coordinate:
Code:
for (int i = 1; i < snake.size() -1; i++)
{
snake.get(i).x = snake.get(i+1).x;
}
This is certainly not bad, as it is true that as the snake moves the coordinate of snake-part i will become the coordinate of snake-part i+1. What is missing in your code: what happens to the tail of the snake, which is effectively at position snake.get(snake.size()-1) ? In your for-loop the update for tail is missed because you iterate until a value smaller than snake.size()-1. The old coordinate of the tail at snake.get(snake.size()-1) will still be in the arraylist.
Now, as for a different approach. As you look at the snake, there is only 1 coordinate that is really changing: the head. As the head moves forward, coordinates from the tail are truncated. All other coordinates between the head and tail remain equal, until those hit the tail and are removed as well.
My suggestion would be: during movement, add a new coordinate to position 0 of the arraylist, and remove the last item in the arraylist.
|

December 3rd, 2012, 09:52 AM
|
 |
Contributing User
|
|
Join Date: Aug 2010
Location: Eastern Florida
|
|
A suggestion for helping you debug the code:
Add a toString() method to the Coordinate class that returns a String with the values of x and y. That will show their values easily when you print them.
Add a call to the println() method in the updateSnake() method that prints out the value of the ArrayList: snake. The print out will show you how the values of the Coordinates objects are being changed and will explain: Quote: | it begins correctly with the head moving to the right, however the rest of the body dissipates except for the tail at (11,15). |
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|