Posts

Creating Your First Game in Java

1 comments·0 reblogs
makerhacks
72
·
0 views
·
min-read

Image from thread

In this tutorial, we'll look at how to create a simple game in Java:

  • Moving a sprite around the screen
  • Controlling the sprite using the keyboard
  • Loading a PNG image as the sprite graphic
  • Ensuring the sprite stays within the boundaries of the playfield.

Step 1: Setting Up Your Java Project

Before we begin coding, make sure you have the following:

  • A Java Development Kit (JDK) installed (JDK 8 or later is recommended)
  • A text editor (VS Code, IntelliJ, or Eclipse)
  • A PNG image file for your sprite (name it sprite.png and place it in your project folder)

Image from thread

piskelapp.com is an amazing free, online pixel graphics editor.

Step 2: Creating a Basic Java Window

Every game needs a playfield of some kind so we need to generate a window to display our game content. We'll use Java Swing to create a window with a drawing area.

Create a new Java file called ControlledSprite.java and paste the following code:

import javax.swing.*; 
import java.awt.*; 
 
public class ControlledSprite extends JPanel { 
    public ControlledSprite() { 
        setFocusable(true); // Allows the panel to receive keyboard input 
    } 
 
    @Override 
    protected void paintComponent(Graphics g) { 
        super.paintComponent(g); 
        g.setColor(Color.RED); 
        g.fillOval(200, 100, 50, 50); // Draws a simple red circle as a placeholder sprite 
    } 
 
    public static void main(String[] args) { 
        JFrame frame = new JFrame("Simple Game"); 
        ControlledSprite panel = new ControlledSprite(); 
        frame.add(panel); 
        frame.setSize(500, 300); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.setVisible(true); 
    } 
} 

This code creates a window and draws a red circle, which will act as our sprite for now.

Image from thread

Step 3: Moving the Sprite with the Keyboard

Now, let's make the sprite move using the keyboard. Modify your ControlledSprite class to implement KeyListener:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
 
public class ControlledSprite extends JPanel implements KeyListener { 
    private int x = 200, y = 100; // Sprite position 
    private final int SPEED = 5; // Movement speed 
 
    public ControlledSprite() { 
        setFocusable(true); 
        addKeyListener(this); 
    } 
 
    @Override 
    protected void paintComponent(Graphics g) { 
        super.paintComponent(g); 
        g.setColor(Color.RED); 
        g.fillOval(x, y, 50, 50); 
    } 
 
    @Override 
    public void keyPressed(KeyEvent e) { 
        if (e.getKeyCode() == KeyEvent.VK_LEFT) x -= SPEED; 
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) x += SPEED; 
        if (e.getKeyCode() == KeyEvent.VK_UP) y -= SPEED; 
        if (e.getKeyCode() == KeyEvent.VK_DOWN) y += SPEED; 
        repaint(); // Redraw sprite at new position 
    } 
 
    @Override 
    public void keyReleased(KeyEvent e) {} 
    @Override 
    public void keyTyped(KeyEvent e) {} 
 
    public static void main(String[] args) { 
        JFrame frame = new JFrame("Controlled Sprite"); 
        ControlledSprite panel = new ControlledSprite(); 
        frame.add(panel); 
        frame.setSize(500, 300); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.setVisible(true); 
    } 
} 

Now, when you press the arrow keys, the sprite moves around the screen.

Step 4: Loading a PNG Image as the Sprite

Let's replace the red circle with an actual sprite image. Make sure you have a sprite.png file in the same directory as your Java file.

Modify the code to load and display the sprite image:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import javax.imageio.ImageIO; 
 
public class ControlledSprite extends JPanel implements KeyListener { 
    private BufferedImage sprite; 
    private int x = 200, y = 100; // Sprite position 
    private final int SPEED = 5; // Movement speed 
 
    public ControlledSprite() { 
        try { 
            sprite = ImageIO.read(new File("sprite.png")); // Load sprite image 
        } catch (Exception e) { 
            System.err.println("Image not found!"); 
        } 
        setFocusable(true); 
        addKeyListener(this); 
    } 
 
    @Override 
    protected void paintComponent(Graphics g) { 
        super.paintComponent(g); 
        if (sprite != null) { 
            g.drawImage(sprite, x, y, null); 
        } 
    } 
 
    @Override 
    public void keyPressed(KeyEvent e) { 
        if (e.getKeyCode() == KeyEvent.VK_LEFT) x -= SPEED; 
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) x += SPEED; 
        if (e.getKeyCode() == KeyEvent.VK_UP) y -= SPEED; 
        if (e.getKeyCode() == KeyEvent.VK_DOWN) y += SPEED; 
        repaint(); 
    } 
 
    @Override 
    public void keyReleased(KeyEvent e) {} 
    @Override 
    public void keyTyped(KeyEvent e) {} 
 
    public static void main(String[] args) { 
        JFrame frame = new JFrame("Controlled Sprite"); 
        ControlledSprite panel = new ControlledSprite(); 
        frame.add(panel); 
        frame.setSize(500, 300); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.setVisible(true); 
    } 
} 

Now, the sprite is an image instead of a red circle!

Step 5: Keeping the Sprite Inside the Playfield

Modify the movement code to prevent the sprite from leaving the screen:

@Override 
public void keyPressed(KeyEvent e) { 
    if (sprite != null) { 
        int spriteWidth = sprite.getWidth(); 
        int spriteHeight = sprite.getHeight(); 
        int panelWidth = getWidth(); 
        int panelHeight = getHeight(); 
 
        if (e.getKeyCode() == KeyEvent.VK_LEFT && x > 0) x -= SPEED; 
        if (e.getKeyCode() == KeyEvent.VK_RIGHT && x < panelWidth - spriteWidth) x += SPEED; 
        if (e.getKeyCode() == KeyEvent.VK_UP && y > 0) y -= SPEED; 
        if (e.getKeyCode() == KeyEvent.VK_DOWN && y < panelHeight - spriteHeight) y += SPEED; 
    } 
    repaint(); 
} 

Full, Commented Code

 
// This example introduces a graphical sprite under keyboard control 
 
import javax.swing.*; 
import java.awt.*; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import javax.imageio.ImageIO; 
 
public class ControlledSprite extends JPanel implements KeyListener { 
    private BufferedImage sprite; // Stores the sprite image 
    private int x = 250-16, y = 150-32; // Initial sprite position 
    private final int SPEED = 200; // Movement speed (pixels per second) 
    private boolean up, down, left, right; // Movement flags 
    private long lastTime; // Stores the last frame's timestamp 
 
    public ControlledSprite() { 
        // Attempt to load the sprite image 
        try { 
            sprite = ImageIO.read(new File("sprite.png")); 
        } catch (Exception e) { 
            System.err.println("Error: Image file not found!"); 
        } 
 
        setFocusable(true); // Ensures the panel can receive keyboard input 
        addKeyListener(this); // Adds key listener for movement 
        lastTime = System.nanoTime(); // Initialize time tracking 
 
        // Timer to update movement every ~16ms (~60 FPS) 
        Timer timer = new Timer(16, e -> updatePosition()); 
        timer.start(); 
    } 
 
    private void updatePosition() { 
        long now = System.nanoTime(); 
        double deltaTime = (now - lastTime) / 1_000_000_000.0; // Convert nanoseconds to seconds 
        lastTime = now; 
 
        // Ensure sprite is loaded before checking its size 
        if (sprite != null) { 
            int spriteWidth = sprite.getWidth(); 
            int spriteHeight = sprite.getHeight(); 
            int panelWidth = getWidth(); 
            int panelHeight = getHeight(); 
 
            // Move sprite, ensuring it stays within bounds 
            if (left) x = Math.max(0, x - (int) (SPEED * deltaTime)); 
            if (right) x = Math.min(panelWidth - spriteWidth, x + (int) (SPEED * deltaTime)); 
            if (up) y = Math.max(0, y - (int) (SPEED * deltaTime)); 
            if (down) y = Math.min(panelHeight - spriteHeight, y + (int) (SPEED * deltaTime)); 
        } 
 
        repaint(); // Request repaint to update sprite position 
    } 
 
    @Override 
    protected void paintComponent(Graphics g) { 
        super.paintComponent(g); // Clears the previous frame 
        if (sprite != null) { 
            g.drawImage(sprite, x, y, null); // Draw the sprite at its new position 
        } 
    } 
 
    // Handles key press events 
    @Override 
    public void keyPressed(KeyEvent e) { 
        switch (e.getKeyCode()) { 
            case KeyEvent.VK_LEFT -> left = true; 
            case KeyEvent.VK_RIGHT -> right = true; 
            case KeyEvent.VK_UP -> up = true; 
            case KeyEvent.VK_DOWN -> down = true; 
        } 
    } 
 
    // Handles key release events 
    @Override 
    public void keyReleased(KeyEvent e) { 
        switch (e.getKeyCode()) { 
            case KeyEvent.VK_LEFT -> left = false; 
            case KeyEvent.VK_RIGHT -> right = false; 
            case KeyEvent.VK_UP -> up = false; 
            case KeyEvent.VK_DOWN -> down = false; 
        } 
    } 
 
    @Override 
    public void keyTyped(KeyEvent e) {} // Not used, but required by KeyListener 
 
    public static void main(String[] args) { 
        // Create a frame to contain the panel 
        JFrame frame = new JFrame("Controlled Sprite"); 
        ControlledSprite panel = new ControlledSprite(); 
        frame.add(panel); 
        frame.setSize(500, 300); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.setVisible(true); 
    } 
} 
 
 
 

Next Steps

Hopefully you can now understand how to create a basic game with a controllable sprite. If there is interest, in future tutorials we can add animation, collision detection, and more!

Posted Using INLEO