โ˜• My First Java Game ยท Episode 1 of 7 ยท See All Episodes
๐Ÿƒ Episode 1 ยท Beginner ยท No Java Experience Needed

Jump Into Java!
Simple Platformer

Build your first real Java game: a player square that runs, jumps with gravity, and lands on platforms. You will learn classes, the game loop, keyboard input and collision, the foundations of every game you will ever make.

๐Ÿ‘ถ Ages 11+ โฑ๏ธ ~2 Hours โ˜• Java โœ“ Free
๐Ÿ“ฆ Variables ๐Ÿ—๏ธ Classes ๐Ÿ” Game loop โŒจ๏ธ Keyboard input ๐ŸŒ Gravity ๐Ÿงฑ Collision
โญ
0 XP
Level 1
๐Ÿ”ฅ0
Your Progress 0 / 6 steps
1
๐Ÿงฐ
Set Up Java & Your Project
Install the JDK and create the project files
Active
๐ŸŽฏ
Goal for this step

Get Java installed and an empty project ready with a window that opens.

  • 1Download and install the free JDK (Java Development Kit) from adoptium.net, pick the latest LTS version for your computer.
  • 2Install a free code editor: VS Code (with the "Extension Pack for Java") or IntelliJ IDEA Community both work great.
  • 3Make a new folder for this game and create a file called Main.java inside it.
  • 4Type the starter code below, it opens a game window using Swing, the windowing toolkit built into Java.
  • 5Run it (the โ–ถ button in your editor, or javac Main.java then java Main in a terminal). A dark empty window should appear!
Main.java
import javax.swing.*;

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame("My Java Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new GamePanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
๐Ÿ‘จโ€๐Ÿ‘ง
Parent note: Everything used in this series is free and built into Java, no game engine or extra libraries to install. If java -version prints a version number in a terminal, the JDK is installed correctly.
โœ๏ธ
Fill in the Blanks
+15 XP
The JDK stands for Java Kit. Our game window is created by the Swing class called .
๐Ÿง 
Knowledge Check
+15 XP
What does frame.setVisible(true) do?
ACompiles the Java code
BActually shows the window on screen, without it the window stays hidden
CMakes the window transparent
2
๐Ÿ”
The Game Panel & Game Loop
Create GamePanel with a timer that updates 60 times a second
Locked
๐ŸŽฏ
Goal for this step

Build the heart of every game: a panel that redraws itself about 60 times per second.

  • 1Create a new file called GamePanel.java in the same folder.
  • 2It extends JPanel (a drawable surface) and implements ActionListener (so the timer can call it).
  • 3The Timer(16, this) fires an event every 16 ms, roughly 60 frames per second.
  • 4Each tick we will move things in update(), then repaint() asks Swing to call paintComponent() again.
  • 5Run it, you should see the dark blue sky colour filling the window.
GamePanel.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class GamePanel extends JPanel implements ActionListener {
    Timer timer = new Timer(16, this);   // ~60 FPS

    public GamePanel() {
        setPreferredSize(new Dimension(800, 480));
        setBackground(new Color(25, 30, 60)); // night sky
        timer.start();
    }

    public void actionPerformed(ActionEvent e) {
        update();    // move everything
        repaint();   // then draw everything
    }

    void update() { /* movement goes here soon */ }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        // drawing goes here soon
    }
}
๐Ÿ’ก
update() then repaint() is the classic game loop: move first, draw second. Every game in this series uses this exact pattern.
๐Ÿง 
Knowledge Check
+15 XP
Why do we use a Timer that fires every 16 milliseconds?
AIt saves the game every 16 milliseconds
BIt runs our update + repaint code about 60 times per second, creating smooth animation
CIt makes the game harder over time
3
๐Ÿƒ
Draw the Player & Move Left/Right
Add player variables, keyboard input and horizontal movement
Locked
๐ŸŽฏ
Goal for this step

Get a player square on screen that runs left and right with the arrow keys.

  • 1Add player variables at the top of GamePanel: position, size and speed.
  • 2Implement KeyListener so the panel hears the keyboard, and remember which keys are held down with two booleans.
  • 3In update(), move the player while a key is held.
  • 4In paintComponent(), draw the player as an orange rectangle.
  • 5Add addKeyListener(this); setFocusable(true); in the constructor or keys will be ignored!
GamePanel.java (additions)
    int px = 100, py = 380;          // player position
    int pw = 34, ph = 44;            // player size
    int speed = 5;
    boolean leftHeld, rightHeld;

    void update() {
        if (leftHeld)  px -= speed;
        if (rightHeld) px += speed;
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(new Color(255, 119, 0));
        g.fillRect(px, py, pw, ph);
    }

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_LEFT)  leftHeld = true;
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) rightHeld = true;
    }
    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_LEFT)  leftHeld = false;
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) rightHeld = false;
    }
    public void keyTyped(KeyEvent e) {}
โŒจ๏ธ
Code Challenge
+20 XP
Make the player move with the arrow keys. Fill in the blanks:
GamePanel.java
if (leftHeld)  px  speed;
if (rightHeld) px  speed;
g.fillRect(, py, pw, ph);
๐Ÿ’ก Hint: Moving left means the x position gets smaller. fillRect draws at (x, y).
๐Ÿง 
Knowledge Check
+15 XP
Why do we track leftHeld/rightHeld booleans instead of moving inside keyPressed?
ABooleans use less memory
BSo movement is smooth every frame while the key is held, instead of stuttering with key-repeat
CJava does not allow movement inside keyPressed
4
๐ŸŒ
Gravity & Jumping
Add vertical velocity, gravity each frame, and a jump key
Locked
๐ŸŽฏ
Goal for this step

Make the player fall with gravity and jump with a satisfying arc when you press Up.

  • 1Add a vertical velocity variable vy and a boolean onGround.
  • 2Every frame, gravity pulls: vy += 1, then py += vy.
  • 3Jumping is just setting vy to a big negative number, but only when standing on something!
  • 4For now, treat the bottom of the window as the floor so you can test.
  • 5Run it: you should fall, land, and jump with a smooth arc. That arc is real physics!
GamePanel.java (update method)
    int vy = 0;
    boolean onGround = false;

    void update() {
        if (leftHeld)  px -= speed;
        if (rightHeld) px += speed;

        vy += 1;          // gravity accelerates you down
        py += vy;         // apply velocity

        // temporary floor at the bottom of the window
        if (py + ph >= 480) {
            py = 480 - ph;
            vy = 0;
            onGround = true;
        }
    }

    public void keyPressed(KeyEvent e) {
        // ... existing arrow keys ...
        if (e.getKeyCode() == KeyEvent.VK_UP && onGround) {
            vy = -16;         // launch upward!
            onGround = false;
        }
    }
๐Ÿ’ก
Bigger gravity (+2) feels heavy and snappy; a stronger jump (-20) floats higher. Play with the numbers until it feels like your game.
โœ๏ธ
Fill in the Blanks
+15 XP
Gravity works by adding to the velocity: vy += 1, then adding velocity to the position: py += . To jump we set vy to a number, and we only allow it when is true.
๐Ÿง 
Knowledge Check
+15 XP
What would happen if we let the player jump when onGround is false?
ANothing changes
BThe player could jump again in mid-air, infinite flying!
CThe game would crash
5
๐Ÿงฑ
Platforms & Collision
Add an array of platforms and land on top of them
Locked
๐ŸŽฏ
Goal for this step

Replace the temporary floor with real platforms the player can land on and jump between.

  • 1Java has a perfect class for this: java.awt.Rectangle, it even has an intersects() method for collision!
  • 2Create an array of platform rectangles: a ground piece plus floating ledges.
  • 3After applying vy, check each platform: if the player overlaps one while falling, snap on top of it.
  • 4Draw every platform in green in paintComponent.
  • 5Delete the temporary window-bottom floor from the last step and go platform hopping!
GamePanel.java
    Rectangle[] platforms = {
        new Rectangle(0, 440, 800, 40),     // ground
        new Rectangle(150, 340, 140, 16),
        new Rectangle(380, 260, 140, 16),
        new Rectangle(610, 180, 140, 16)
    };

    void update() {
        // ... movement + gravity from before ...
        onGround = false;
        Rectangle player = new Rectangle(px, py, pw, ph);
        for (Rectangle plat : platforms) {
            if (player.intersects(plat) && vy >= 0
                && py + ph - vy <= plat.y) {
                py = plat.y - ph;   // snap on top
                vy = 0;
                onGround = true;
            }
        }
    }

    // in paintComponent:
    //   g.setColor(new Color(6, 214, 160));
    //   for (Rectangle plat : platforms) g.fillRect(plat.x, plat.y, plat.width, plat.height);
โŒจ๏ธ
Code Challenge
+20 XP
Complete the collision check that lands the player on a platform:
GamePanel.java
if (player.(plat) && vy >= 0) {
    py = plat.y - ;   // stand on top
    vy = ;
    onGround = true;
}
๐Ÿ’ก Hint: Rectangle has a built-in overlap method. To stand ON a platform, the player bottom (py + height) must equal the platform top.
๐Ÿง 
Knowledge Check
+15 XP
Why do we only land when vy >= 0?
ASo we pass through platforms from below while jumping up, and only land when falling down
BBecause negative numbers crash Java
CTo make the player move faster
6
๐Ÿ†
Coins, Score & Winning
Collect coins on the platforms and show a win screen
Locked
๐ŸŽฏ
Goal for this step

Add collectable coins, a score counter, and a WIN screen when you grab them all.

  • 1Store coins in an ArrayList<Rectangle> so we can remove them when collected.
  • 2Place one coin above each floating platform.
  • 3Each frame, if the player intersects a coin: remove it and add 10 to score.
  • 4Draw the score top-left with g.drawString(), and coins as gold squares.
  • 5When the list is empty, draw a giant YOU WIN message. You finished your first Java game!
GamePanel.java
    java.util.List<Rectangle> coins = new java.util.ArrayList<>(java.util.List.of(
        new Rectangle(205, 300, 18, 18),
        new Rectangle(435, 220, 18, 18),
        new Rectangle(665, 140, 18, 18)));
    int score = 0;

    void update() {
        // ... previous code ...
        coins.removeIf(c -> {
            if (new Rectangle(px, py, pw, ph).intersects(c)) { score += 10; return true; }
            return false;
        });
    }

    protected void paintComponent(Graphics g) {
        // ... player + platforms ...
        g.setColor(new Color(255, 209, 102));
        for (Rectangle c : coins) g.fillRect(c.x, c.y, c.width, c.height);
        g.setColor(Color.WHITE);
        g.setFont(new Font("Arial", Font.BOLD, 18));
        g.drawString("Score: " + score, 16, 26);
        if (coins.isEmpty()) {
            g.setFont(new Font("Arial", Font.BOLD, 48));
            g.drawString("YOU WIN!", 290, 240);
        }
    }
๐Ÿ’ก
Want more? Add a falling-off-screen respawn (if (py > 480) px = 100;), more platforms, or a timer to beat. This is YOUR game now.
โœ๏ธ
Fill in the Blanks
+15 XP
We use an instead of an array for coins because we need to items while the game runs. The text on screen is drawn with g..
๐Ÿง 
Knowledge Check
+15 XP
You finished a platformer with a game loop, gravity, collision and scoring. Which part decides how often everything updates?
ApaintComponent
BThe Swing Timer firing every 16 ms
CThe JFrame
๐ŸŽ‰๐Ÿ†๐ŸŽฎโœจ๐ŸŽ‰
Workshop Complete!
You built a real platformer in pure Java, game loop, gravity, jumping and collision, all coded by you. Episode 2 turns you loose on Brick Breaker!
0
Total XP
1
Level
0
Best Streak
0%
Accuracy
โ–ถ Episode 2: Brick Breaker โ†’
โญ View My Progress & Certificates

This workshop was free and took many hours to build. If it helped you learn something new, consider supporting the project.

☕ Support on Ko-fi