Creating Your First Game in Java
technology·@makerhacks·
0.000 HBDCreating Your First Game in Java
https://img.inleo.io/DQmX54YAR6Ekx77TCB8R9d1KbwNk8v7jyUT2kLahPKzakoG/image.png 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) https://img.inleo.io/DQmVLJVpQ92WxzVgRf1fLf7odTuhQ2UgKSe1t8xFp9XaSvZ/image.png [piskelapp.com](https://www.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: ```java 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. https://img.inleo.io/DQmVC43XmR96k6ihXfYX22uzcAfDmRR7TXyuuBGo1bvUa31/image.png ## **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`: ```java 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: ```java 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: ```java @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 ```java // 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](https://inleo.io/@makerhacks/creating-your-first-game-in-java--fl3)
👍 khalstem, slider2990, acidyo, holbein81, xves, ghaazi, rendrianarma, enforcer48, steemflagrewards, admiralbot, aninsidejob, memehub, steemseph, nftspecialists, aussieninja, mytechtrail, darth-azrael, darth-cryptic, retrodroid, photographercr, hannes-stoffel, holovision.stem, irivers, bpcvoter4, lemouth, steemstem-trig, steemstem, dna-replication, stemsocial, roelandp, growandbow, curie, alexander.alexis, howo, abigail-dantes, aboutcoolscience, kenadis, sco, emiliomoron, pboulet, metabs, techslut, valth, dhimmel, mobbs, samminator, tsoldovieri, aidefr, madridbg, geopolis, alexdory, melvin7, francostem, gadrian, de-stem, deholt, temitayo-pelumi, nattybongo, stem.witness, prosocialise, inibless, cindynancy, noelyss, llunasoul, doctor-cog-diss, merit.ahama, superlotto, failingforwards, hairgistix, yixn, cloh76, someguy123, metroair, talentclub, ohamdache, steemvault, seinkalar, boxcarblue, michelle.gent, rt395, cryptofiloz, altleft, whywhy, newilluminati, clpacksperiment, pandasquad, yozen, zyx066, dauerossi, bartosz546, photohunt, takowi, irgendwo, putu300, qberry, minerthreat, steemstorage, meritocracy, dcrops, aries90, rhemagames, yadamaniart, therising, cakemonster, dawnoner, the100, tfeldman, neumannsalva, adelepazani, zipporah, cheese4ead, armandosodano, double-negative, federacion45, bitrocker2020, princessmewmew, coindevil, bil.prag, vickoly, lukasbachofner, belug, humbe, arunava, investingpennies, hetty-rowan, fineartnow, dynamicrypto, nateaguila, thelittlebank, kristall97, instagram-models, justyy, jayna, gunthertopp, steveconnor, vcclothing, followjohngalt, soylegionario, sam99, jjerryhan, bscrypto, multifacetas, danwhodoesart, kevinwong, stayoutoftherz, sorin.cristescu, sunsea, utube, greddyforce, kylealex, steemean, callmesmile, dune69, empath, bflanagin, the.success.club, steemcryptosicko, michelmake.util, kryptof, revo, meno, florian-glechner, baltai, bilpcoinbpc, zonguin, enzor, dreamm, detlev, enjar, gabrielatravels, neneandy, moriaty, acgalarza, jijisaurart, xeldal, mcsvi, hive-199963, lichtkunstfoto, kiemurainen, juancar347, qwerrie, dresden.theone, sportscontest, fantasycrypto, tiffin, ibt-survival, elevator09, mproxima, sanderjansenart, hiddendragon, reggaesteem, vindiesel1980, holovision.cash, adol, enki, juecoree, stem-espanol, carilinger, jerrybanfield, lorenzor, azulear, tomastonyperez, elvigia, erickyoussif, acont, fran.frey, iamphysical, ydavgonzalez, miguelangel2801, josedelacruz, andrick, aleestra, giulyfarci52, aqua.nano, psicoluigi, uche-nna, hk-curation, wasined, neddykelly, buttcoins, aiziqi, sincensura, robertbira, nfttunz, eric-boucher, brofund, brofi, upfundme, bozz.sports, beardoin, dab-vote, brofund-witness, dailydab, clubvote, ennyta, endopediatria, vixmemon, bluefinstudios, m1alsan, opticus, gamersclassified, davidlionfish,