-1

Im writing RiverRaidlike game, and i have a problem with restarting the game.

When Craft crashes i want to make it able to press space and restart the game.

Problem is that i have everything drawn on the JPanel.

My research:

  • When i try to pass a game object to the Panel class and dispose the last window there is a NullPointerException...

    private void restart()
    {
        game.dispose();
        new Game();
        repaint();
    }
    

    I think it's a problem with calling constructors.. but im not sure...

  • When i try to reinitialize the JPanel it just repaints all but doesnt remove the old content

    private void initBoard() {
        addKeyListener(new TAdapter());
        setFocusable(true);
        setBackground(Color.PINK);
        setLayout(new GridBagLayout());
        craft = new Craft(ICRAFT_X, ICRAFT_Y);
    
        setMinimumSize(new Dimension(WIDTH, HEIGHT));
        initEnemiesAndAddThem();
        czas = new Timer(delay, this);
        czas.start();
    
    }
    
    private void initEnemiesAndAddThem() {
        enemy = new EnemyJet(0, -600);
        enemies.add(enemy);
        fuel = new Fuel(0, 0);
        fuels.add(fuel);
        obstacle = new Obstacle(0, -600);
        obst.add(obstacle);
    }
    private void restart()
    {
        initBoard();
    }
    
  • Lastly, when i try to implement KeyListener to the JFrame it doesnt work at all... tried to print out a string when i press space, but nothing happens...

All i can do is to stop the Timer and start it again but it pausing the game but not restarting it.

Those are the JFrame class and JPanel class:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package riverraid2;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 *
 * @author Michał
 */
public class Game extends JFrame implements KeyListener {

    private final static int WIDTH = 1024;
    private final static int HEIGHT = 768;
    Plansza panel;

    Game() {
        initGame();
    }

    private void initGame() {
        Plansza panel = new Plansza();
        setTitle("Reeevah Raaid");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(WIDTH, HEIGHT);
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        setMinimumSize(new Dimension(800, 600));
        setMaximumSize(new Dimension(1680, 1050));
        setLocationRelativeTo(null);

        // panel.setState(new StartScreen(panel));
        this.add(panel, BorderLayout.CENTER);

        pack();
        setVisible(true);
        //setExtendedState(JFrame.MAXIMIZED_BOTH);
        //setResizable(false);
    }

    public static void main(String[] args) {

        new Game();
        //ex.setVisible(true);
        // ex.pack();

    }

    @Override
    public void keyTyped(KeyEvent e) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
     public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_SPACE) {
            System.out.print("Spacja!");
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

}
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package riverraid2;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.util.ArrayList;
import javax.swing.Icon;
import javax.swing.JLabel;

/**
 *
 * @author Michał
 */
public class Plansza extends JPanel implements ActionListener {
    private boolean paused = false;
    private int ileWcisniec = 0;
    private int slowDownSally = 0;
    private int finalScore = 1;
    private Game game;
    private Timer czas;
    private Thread thread;
    private Craft craft;
    private Fuel fuel;
    private Obstacle obstacle;
    private EnemyJet enemy;
    private final int delay = 10;
    private final int ICRAFT_X = 450;
    private final int ICRAFT_Y = 600;
    private final ArrayList<Fuel> fuels = new ArrayList<>();
    private final ArrayList<EnemyJet> enemies = new ArrayList<>();
    private final ArrayList<Obstacle> obst = new ArrayList<>();
    boolean running = true;
    long licznik = System.nanoTime();

    public Plansza() {
        // setBackground(Color.WHITE);
        initBoard();
    }

    private void initBoard() {
        addKeyListener(new TAdapter());
        setFocusable(true);
        setBackground(Color.PINK);
        setLayout(new GridBagLayout());
        craft = new Craft(ICRAFT_X, ICRAFT_Y);

        setMinimumSize(new Dimension(WIDTH, HEIGHT));
        initEnemiesAndAddThem();
        czas = new Timer(delay, this);
        czas.start();

    }

    private void initEnemiesAndAddThem() {
        enemy = new EnemyJet(0, -600);
        enemies.add(enemy);
        fuel = new Fuel(0, 0);
        fuels.add(fuel);
        obstacle = new Obstacle(0, -600);
        obst.add(obstacle);
    }
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        doDrawing(g);
        if (!running) {
            drawGameOver(g, "");
            g.drawString("Press SPACE to restart the game!", getWidth()/4, getHeight()/2);
        }
        Toolkit.getDefaultToolkit().sync();
    }

    private void doDrawing(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        drawStrings(g2);

        ArrayList ms = craft.getMissiles();

        for (Object m1 : ms) {
            Missile m = (Missile) m1;
            g2.drawImage(m.getImage(), m.getX(), m.getY(), this);
        }
        g2.drawImage(craft.getImage(), craft.getX(), craft.getY(), this);
        for (EnemyJet enemy : enemies) {
            g2.drawImage(enemy.getImage(), enemy.getX(), enemy.getY(), this);
        }
        for (Fuel fuel : fuels) {
            g2.drawImage(fuel.getImage(), fuel.getX(), fuel.getY(), fuel.getHeight(), fuel.getHeight(), this);
        }
        for (Obstacle o : obst) {
            g2.drawImage(o.getImage(), o.getX(), o.getY(), this);
        }
        drawStrings(g2);

    }

    private void drawGameOver(Graphics g, String msg) {
        Font small = new Font("Helvetica", Font.BOLD, 36);
        FontMetrics fm = getFontMetrics(small);

        g.setColor(Color.white);
        g.setFont(small);
        g.drawString("GAME OVER", getWidth()/4, (getHeight()/2)-50);
        g.drawString(msg, (1024 - fm.stringWidth(msg)) / 2,
                800 / 2);
    }

    public void drawStrings(Graphics2D g) {
        String score;
        String fuelString;
        score = "Score: " + finalScore;
        g.setColor(Color.WHITE);
        g.setFont(new Font("Consolas", Font.PLAIN, 48));
        g.drawString(score, 150, 48);
        fuelString = "Fuel: " + craft.getFuel();
        g.drawString(fuelString, 650, 48);
    }

    public String gameOver() {
        String msg = "";
        if (craft.getFuel() <= 0) {
            running = false;
            msg = "Zabrakło ci paliwa!";
        }
        if (finalScore == 1000000) {
            running = false;
            msg = "Gra ukończona, jesteś mistrzem River Raid, oto Twój medal Mistrza River Raid";
        }
        return msg;
    }
    private void restart()
    {
        initBoard();
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        removeAll();
        gameRunning();
        updateMissiles();
        updateCraft();
        updateEnemy();
        updateFuel();
        updateObstacles();
        checkCollision();
        gameOver();
        if (slowDownSally % 100 == 0) {
            updateArrays();
        }
        if (finalScore % 2000 == 0) {
            levelUpJets();
        }
        repaint();
        slowDownSally++;
    }
    public boolean gameState()
    {
       return running;
    }
    private void updateMissiles() {

        ArrayList ms = craft.getMissiles();

        for (int i = 0; i < ms.size(); i++) {

            Missile m = (Missile) ms.get(i);

            if (m.isVisible()) {

                m.move();
            } else {
                ms.remove(i);
            }
        }
    }

    private void updateArrays() {
        EnemyJet e = new EnemyJet(0, -600);
        enemies.add(e);
        Fuel f = new Fuel(0, -500);
        fuels.add(f);
        Obstacle o = new Obstacle(0, -600);
        obst.add(o);
    }

    private void updateEnemy() {

        for (int i = 0; i < enemies.size(); i++) {

            EnemyJet e = enemies.get(i);

            if (e.isVisible()) {

                e.move();
            } else {
                enemies.remove(i);
            }
        }
    }

    private void updateFuel() {
        for (int i = 0; i < fuels.size(); i++) {

            Fuel e = fuels.get(i);

            if (e.isVisible()) {
                e.move();
            } else {
                fuels.remove(i);
            }
        }
    }

    private void updateObstacles() {
        for (int i = 0; i < obst.size(); i++) {

            Obstacle o = obst.get(i);

            if (o.isVisible()) {
                o.move();
            } else {
                obst.remove(i);
            }
        }
    }

    private void updateCraft() {

        craft.move();
    }

    public void gameRunning() {
        if (running == false) {
            czas.stop();
        }
    }

    void checkCollision() {
        Rectangle r3 = craft.getBounds();

        for (EnemyJet enemy : enemies) {
            Rectangle r2 = enemy.getBounds();

            if (r3.intersects(r2)) {
                craft.setVisible(false);
                enemy.setVisible(false);
                running = false;
            }
        }

        ArrayList<Missile> ms = craft.getMissiles();

        for (Missile m : ms) {

            Rectangle r1 = m.getBounds();

            for (EnemyJet enemy : enemies) {

                Rectangle r2 = enemy.getBounds();

                if (r1.intersects(r2)) {
                    m.setVisible(false);
                    enemy.setVisible(false);
                    enemy.vis = false;
                    finalScore += 100;
                }
            }
        }

        for (Fuel fuel : fuels) {
            Rectangle r4 = fuel.getBounds();
            if (r3.intersects(r4)) {
                craft.addFuel(50);
                fuel.setVisible(false);
            }
        }
        for (Obstacle o : obst) {
            Rectangle r5 = o.getBounds();
            for (Missile m : ms) {

                Rectangle r1 = m.getBounds();
                if (r1.intersects(r5)) {
                    m.setVisible(false);
                }
            }
            if(r5.intersects(r3))
            {
                running = false;
            }
        }
    }

    private void levelUpJets() {
        for (EnemyJet e : enemies) {
            e.levelUp();
        }
    }

    private class TAdapter extends KeyAdapter {

        @Override
        public void keyReleased(KeyEvent e) {
            craft.keyReleased(e);

        }

        @Override
        public void keyPressed(KeyEvent e) {
           craft.keyPressed(e);    
           restart();
        }
    }
}

It's not a problem of NullPointerException but i think more conceptional problem, about how to restart the game... I only suggested that one of my tries gave that error but I did it to show an effort in findin the solution.

tdbr
  • 316
  • 1
  • 3
  • 9
  • 1
    as a sidenode. Your current attempt to restart the `Game` is basicly to restart the whole application (`new Game()` does get called in your `main`). At least this isn´t the most favorable solution to restarting it. I might try it with resetting the variables to the default values they got initialized with to represent a new `Game`. – SomeJavaGuy May 25 '16 at 12:18
  • Ok, but how to make it to the Images? How to remove them all and then reinitialize? – tdbr May 25 '16 at 12:24
  • Dispose the main frame; create a new one. Display it. You seem to call `dispose()` on an instance variable called `game`. You then create a `new Game()`, but don't assign it to anything. This is obviously wrong. – Boris the Spider May 25 '16 at 12:28
  • haha, i tried it for milion times... How to dispose the old one? I know how to make a new one no problem, but what with the old one which is over? – tdbr May 25 '16 at 12:55

2 Answers2

0

I can't answer why you are getting a null pointer. I would suggest that you would just create a method that would reset the game instead of creating a new game object. As for the JPanel not resetting itself, it doesn't seem that you actually reset anything. Consider writing a method that would reset all your fields. Hope this is helpful!

Phia-CM
  • 67
  • 1
  • 9
0

There is no need to reinitialize everything, like you do in your initBoard (listener). Those are fine. Try to separate your functions. You are setting size and creating a craft and so on in the same method. All you need is to reinitialize your positions, some values, bool states, only stuffs that affects the game play. Make a separated method for these, and call them whenever you want, and don't forget to clear your arraylists.

eldo
  • 1,327
  • 2
  • 16
  • 27