I am trying to create a 2D platform game, by following this tutorial. I have created an Images()
-class which looks like this:
package Resources;
import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Objects; public class Images { public static BufferedImage[] tileBlocks; public Images(){ tileBlocks = new BufferedImage[1]; try{ tileBlocks[0] = ImageIO.read( // TODO: Fix the error caused by this try/catch (Objects.requireNonNull(getClass().getResourceAsStream("TileBlocks/block_brick.png"))) ); } catch (IOException e) { e.printStackTrace(); } } }
And I created an instantation of it in my GamePanel()
-class, which looks like this
package Main; import GameState.GameStateManager; import Resources.Images; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.Serial; @SuppressWarnings("BusyWait") public class GamePanel extends JPanel implements Runnable, KeyListener { @Serial private static final long serialVersionUID = 1L; // Game thread private boolean isRunning = false; int FPS = 60; // Frames per second long targetTime = 1000 / FPS; // Set target time // Set the dimension of the game-window public static final int WIDTH = 800; public static final int HEIGHT = 600; private GameStateManager gsm = new GameStateManager(); // Game state manager object public GamePanel(){ setPreferredSize(new Dimension(WIDTH, HEIGHT)); addKeyListener(this); setFocusable(true); // TODO: Fix error (Reports instantiation of utility classes using the new keyword) new Images(); start(); } // Start the game (initialize) private void start() { isRunning = true; Thread thread = new Thread(this); // Referring to Runnable thread.start(); // Call to our game-loop } // Game-loop public void run() { long start, elapsed, wait; // Keep track of time gsm = new GameStateManager(); // Initialize game state manager while (isRunning) { start = System.nanoTime(); // Start timer update(); // Update the game-logic repaint(); // Re-paint the board (built-in method from java.awt) elapsed = System.nanoTime() - start; // If everything runs in under the target time we wait (so it runs equally in all computers) wait = targetTime - elapsed / 1000000; // Divide by 1 000 000 to get milli-seconds if (wait <= 0) { wait = 5; } // Keep wait a positive value try { Thread.sleep(wait); } catch (Exception e) { e.printStackTrace(); } } } // Updating all game-logic public void update() { gsm.update(); }// Call methods from game state manager in the game panel class // Where we draw the graphics public void paintComponent(Graphics g){ super.paintComponent(g); // Built-in method from java.awt g.clearRect(0,0,WIDTH,HEIGHT); // Clear the screen before drawing gsm.draw(g); // Call method from game state manager in the game panel class } public void keyPressed(KeyEvent e) { gsm.keyPressed(e.getKeyCode()); // getKeyCode() turns KeyEvent into an integer } public void keyReleased(KeyEvent e) { gsm.keyReleased(e.getKeyCode()); // getKeyCode() turns KeyEvent into an integer } public void keyTyped(KeyEvent e) { } }
I get an error saying
Instantiation of utility class 'Images' Inspection info: Reports instantiation of utility classes using the new keyword. In utility classes, all fields and methods are static. Instantiation of such classes is most likely unnecessary and indicates a mistake.
And when I try to run the game it doesn’t launch, I only get a NullPointerException
Exception in thread "main" java.lang.NullPointerException at java.base/java.util.Objects.requireNonNull(Objects.java:208) at inf112.skeleton.app/Resources.Images.<init>(Images.java:17) at inf112.skeleton.app/Main.GamePanel.<init>(GamePanel.java:35) at inf112.skeleton.app/Main.Game.game(Game.java:10) at inf112.skeleton.app/Main.Game.main(Game.java:20)
But if I remove the the instantation, the game launches, but then it crashes with even more errors
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot load from object array because "Resources.Images.tileBlocks" is null etc...
If I remove the Objects.requireNonNull
from
tileBlocks[0] = ImageIO.read((getClass().getResourceAsStream("TileBlocks/block_brick.png"))
The game launches, but it crashes and I get another error saying
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot load from object array because "Resources.Images.tileBlocks" is null
What am I doing wrong here? Why is my list of tileBlocks null
? How can I read the image and display it on the tileBlocks
?
Advertisement
Answer
Put file “block_brick.png” in directory “TileBlocks” in classpath.