Tutorial [Java]: Creating a Snake Game [Part 05] - Controller Input

Note: I have completely rewritten and improved this game. Most of my traffic comes from these posts, so I've not deleted them. Please use the new version which can be found here.

What good is a game if there's no way for the player to interact with it? As I mentioned in the last part of the tutorial, this section will cover the controller input that is used in the Snake Game. This section will probably be relatively short, since we've already implemented most of the code in the Snake class. Anyway, let's begin!

Let's open up our Engine class and make extend KeyAdapter. For anyone who is unfamilar, KeyAdapter implements KeyListener, but doesn't handle any of the events. When we extend this, it enables us to just implement what methods we want to implement instead of all of the methods in the interface. The downside to this is that we can't handle both Mouse and Keyboard input at the same time. However, since our game is only using the Keyboard for input, this isn't an issue.

public class Engine extends KeyAdapter {

Now we need to register the Engine class as a KeyboardListener for the canvas on the screen. Unless we do this, none of our events will fire, and we wont be able to process any KeyEvents. To register our listener, simply add this into your constructor:

private Engine(Canvas canvas) {
 //Rest of constructor...

Next, let's override the keyPressed method from KeyAdapter. This is where we will parse our user input, allowing the player to interact with the game.

public void keyPressed(KeyEvent e) {


Now, we need to have this code change the direction of the snake when the W, A, S, and D keys are pressed, so let's go into the Snake class and implement this functionality. In the Snake Game, the snake can not go in a direction opposite it's current direction, so we need to write a little logic to prevent that from happening. Add this to your Snake class:

public void setDirection(Direction direction) {
 if(direction.equals(Direction.UP) && currentDirection.equals(Direction.DOWN)) {
 } else if(direction.equals(Direction.DOWN) && currentDirection.equals(Direction.UP)) {
 } else if(direction.equals(Direction.LEFT) && currentDirection.equals(Direction.RIGHT)) {
 } else if(direction.equals(Direction.RIGHT) && currentDirection.equals(Direction.LEFT)) {
 this.temporaryDirection = direction;

Now we need to handle the actual key events to call this method when one of the controls is pressed. This is also quite simple to do, and shouldn't need any explaining.

if(e.getKeyCode() == KeyEvent.VK_W) {
if(e.getKeyCode() == KeyEvent.VK_S) {
if(e.getKeyCode() == KeyEvent.VK_A) {
if(e.getKeyCode() == KeyEvent.VK_D) {

Before we end this chapter, I want to give a quick explanation as to why there are two variables for the direction of the snake. It's quite simple really; our game runs on one thread, and user input runs on another. This means that we have to poll the direction every time we update the snake. Otherwise, we run the risk of breaking the game by pressing more than one key per update. For example, assume the snake is travelling in the UP direction. Before the game's loop executes, the user presses LEFT, and then DOWN. This would set the direction to DOWN, even though the last direction the snake moved was UP, causing us to lose the game. This is perfectly legal as the last direction that was set was LEFT, and not UP. With two variables, we're able to track the true direction of the snake, and only change it when the game updates.

Now our game is set for receiving user input, and controlling the snake in response to this input. If you want to play around with the code so far, you can call resetSnake in the Snake or Engine constructor, though it wont do anything but move around yet. In the next section, we'll cover the scoring system, eating and spawning fruit, and growing in size.

Posted in , , , , , . Bookmark the permalink. RSS feed for this post.

Leave a Reply


Swedish Greys - a WordPress theme from Nordic Themepark. Converted by LiteThemes.com.