如何用Java重启游戏

时间:2016-05-25 12:13:38

标签: java swing

我正在写RiverRaidlike游戏,我在重启游戏方面遇到了问题。

当Craft崩溃时,我想让它能够按空间并重新开始游戏。

问题是我在JPanel上绘制了所有内容。

我的研究:

  • 当我尝试将游戏对象传递给Panel类并处理最后一个窗口时,会出现NullPointerException ......

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

    我认为这是调用构造函数的问题..但我不确定......

  • 当我尝试重新初始化JPanel时,它只会重新绘制所有内容但不删除旧内容

    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();
    }
    
  • 最后,当我尝试将KeyListener实现到JFrame时,它根本不起作用...当我按空格时试图打印出一个字符串,但没有任何反应......

我所能做的就是停止计时器并再次启动它,但它会暂停游戏但不会重新启动它。

这些是JFrame类和JPanel类:

/*
 * 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();
        }
    }
}

这不是NullPointerException的问题,但我认为更多的概念性问题,关于如何重新启动游戏...我只是建议我的一次尝试给出了这个错误,但我这样做是为了显示努力找到解决方案。< / p>

2 个答案:

答案 0 :(得分:0)

我无法回答为什么你得到一个空指针。我建议您只创建一个重置游戏而不是创建新游戏对象的方法。至于JPanel没有重置自己,你似乎并没有真正重置任何东西。考虑编写一个可以重置所有字段的方法。希望这有用!

答案 1 :(得分:0)

没有必要重新初始化所有内容,就像在initBoard(侦听器)中那样。那很好。尝试分离您的功能。您正在以相同的方法设置大小并创建工艺等。你所需要的只是重新初始化你的位置,一些价值观,布尔状态,只有影响游戏的东西。为这些创建一个单独的方法,并随时调用它们,并且不要忘记清除你的arraylists。

相关问题