What is the java snake game code?

509    Asked by makram_8714 in Java , Asked on Oct 11, 2022

 I am a self - taught coder, and have been learning Java / C# for the last 2 1/2 years (inconsistently).

I have recently created a snake game in Java with the help of an online tutorial. I have rearranged the program into separate classes & methods. I am sceptical on how good of a programmer I am, and I code messy.

I don't really want help on how to make the game better in visuals, levels, or anything like that. I am asking those who are more advanced programmers to help me with implementing programming techniques, better organisation, how to comment better, etc. Pretty much anything that will help me become a better programmer.

Also, I have commented a few things out of pure guesswork, so if it appears as if I have gotten something wrong, please correct me!

Also, any extra tips for my future projects would be much appreciated!


Game.Java


import java.awt.EventQueue;
import javax.swing.JFrame;
public class Game extends JFrame {
Game() {
    add(new Board());
    setResizable(false);
    pack();
    setTitle("Snake");
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
    // Creates a new thread so our GUI can process itself
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame frame = new Game();
            frame.setVisible(true);
        }
    });
}
}
Snake.Java
public class Snake {
// Stores the joints / body part locations for our snake
private final int[] x = new int[Board.getAllDots()];
private final int[] y = new int[Board.getAllDots()];
// Stores direction of our snake
private boolean movingLeft = false;
private boolean movingRight = false;
private boolean movingUp = false;
private boolean movingDown = false;
private int joints = 0; // Stores # of dots / joints the snake has (starts
                        // with 3)
public int getSnakeX(int index) {
    return x[index];
}
public int getSnakeY(int index) {
    return y[index];
}
public void setSnakeX(int i) {
    x[0] = i;
}
public void setSnakeY(int i) {
    y[0] = i;
}
public boolean isMovingLeft() {
    return movingLeft;
}
public void setMovingLeft(boolean movingLeft) {
    this.movingLeft = movingLeft;
}
public boolean isMovingRight() {
    return movingRight;
}
public void setMovingRight(boolean movingRight) {
    this.movingRight = movingRight;
}
public boolean isMovingUp() {
    return movingUp;
}
public void setMovingUp(boolean movingUp) {
    this.movingUp = movingUp;
}
public boolean isMovingDown() {
    return movingDown;
}
public void setMovingDown(boolean movingDown) {
    this.movingDown = movingDown;
}
public int getJoints() {
    return joints;
}
public void setJoints(int j) {
    joints = j;
}
public void move() {
    for (int i = joints; i > 0; i--) {
        // Moves the joints of the snake 'up the chain'
        // Meaning, the joint of the snake all move up one
        x[i] = x[(i - 1)];
        y[i] = y[(i - 1)];
    }
    // Moves snake to the left
    if (movingLeft) {
        x[0] -= Board.getDotSize();
    }
    // To the right
    if (movingRight) {
        x[0] += Board.getDotSize();
    }
    // Down
    if (movingDown) {
        y[0] += Board.getDotSize();
    }
    // And finally up
    if (movingUp) {
        y[0] -= Board.getDotSize();
    }
    // Dotsize represents the size of the joint, so a pixel of DOTSIZE
    // gets added on to the snake in that direction
}
 }


Answered by manisha Murakami

There's lots that can be improved about this regarding the java snake game code, so let's get started.


Use the Random class instead of Math.random()

Instead of this

Math.random() * RANDOMPOSITION

Do this

int randomNumber = this.random.nextInt(RANDOMPOSITION)

The reason for this is that random.nextInt is more efficient and less biassed (see here https://stackoverflow.com/questions/738629/math-random-versus-random-nextintint for more information about that).

Enums instead of booleans

Instead of having four booleans representing the direction that the snake is moving, instead make these into an enum. It could look like this:

public enum Direction {

    RIGHT,

    LEFT,

    UP,

    DOWN;

}

Then, instead of this redundant code:

if ((key == KeyEvent.VK_LEFT) && (!snake.isMovingRight())) {
    snake.setMovingLeft(true);
    snake.setMovingUp(false);
    snake.setMovingDown(false);
}
You can just have snake.setDirection(Direction.LEFT)
I would also recommend replacing this one
// Check to see if the game is running
private boolean inGame = true;

With a GameState enum. That way, you can easily add a PAUSED and a GAME_OVER state depending on your needs.

Separate Game Model from Rendering

Looking at the Board class, it appears to be responsible for tying many different parts of the game together. I see the rendering, input, game state, game speed, game setup, game rules, and collision checking all in this one class.

It is good programming practice to separate the input and rendering from the underlying game model. This will allow you to switch out the rendering and input and still use the game model code almost unchanged. You can also port the game over to another language much more easily.

To achieve this, you will need a class that just handles the rendering and input. You could call this SnakeWindow. This class would be responsible for rendering the contents of the game board to the screen each frame, and for calling methods of the game model when receiving input. It would also update the game model each tick.

Object Oriented design

Following the idea of separating the game model from the rendering, there are many places where the code could be made more object oriented. It is not mandatory to write code in an object oriented way, but it is especially helpful when you are a beginner, and I personally find that it makes code easier to write and understand.

Below the SnakeWindow class there would be the SnakeGame class that would be responsible for the rules of the game. This class would have things like the speed of the game, or the speed that food spawns. It would have fields for the Snake object as well as the Board object. The window would update the SnakeGame each tick, and the game object would call the necessary methods of the snake and the board.

The Board object could have a simple int[][], and each position on the board could have a 0 for empty space, a 1 for a wall, and a 2 if a food is present. I think it would be best if it were responsible for the creation of food, so it could have a variable such as maxFood, and the Board would be called each tick to create the food.

Eventually you could change these integers to something more self documenting, such as an enum with values for FOOD, WALL, and EMPTY.

The window class would get information about the Snake and the Board from the game object and display this information on the screen. Related to this, I would remove all information about the dotSize from the game model and keep this information in the window. It's best to treat the board as discrete [x][y] locations and let the window be responsible for what size to draw them.

I would put the collision methods for the walls and food in the SnakeGame class, checking the positions of the snake against the positions of walls and food in the Board object. You could put the collision method for the snake against itself in this class, or alternatively put it inside the Snake class. For clarity though I would put it in the game class to keep all of the main game logic and rules in a central location.



Your Answer

Interviews

Parent Categories