java - 按我的开火键时 SubKiller 游戏无法正常开火

标签 java

我有以下程序,它是一款 SubKiller 游戏,我有一个问题。我如何让船在我按下向下键时随时发射炸弹?到目前为止,我已经多次启动它。我可以发射第一颗炸弹,但当我试图发射第二颗时,第一颗炸弹消失了,它不会继续这样。我在这件事上被困了将近两天,请帮助我。

我将为您提供 SSCCE 代码。 这是一个名为 SubKillerPanel 的类,基本上所有东西都在这里,船在这里,炸弹在这里,潜艇在这里。

import java.awt.event.*;
import javax.swing.*;
import java.awt.Graphics;
import java.awt.Color;

public class SubKillerPanel extends JPanel {
    private static final long serialVersionUID = 1L;
    private Timer timer;
    private int width, height;
    private Boat boat;
    private Bomb bomb;
    private Submarine sub;

    public SubKillerPanel() {
        setBackground(Color.WHITE);
        ActionListener action = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                if (boat != null) {
                    boat.updateForNewFrame();
                    bomb.updateForNewFrame();
                    sub.updateForNewFrame();
                }
                repaint();
            }
        };

        timer = new Timer( 20, action );
        addMouseListener( new MouseAdapter() {
            public void mousePressed(MouseEvent evt) {
                requestFocus();
            }
        }
);
        addFocusListener( new FocusListener() {
            public void focusGained(FocusEvent evt) {
                timer.start();
                repaint();
            }

            public void focusLost(FocusEvent evt) {
                timer.stop();
                repaint();
            }
        } 
);
        addKeyListener( new KeyAdapter() {
            public void keyPressed(KeyEvent evt) {
                int code = evt.getKeyCode(); // ce tasta a fost apasata
                if (code == KeyEvent.VK_LEFT) {
                    boat.centerX -= 15;
                }
                else 
                    if (code == KeyEvent.VK_RIGHT) {
                        boat.centerX += 15;
                    }
                    else 
                        if (code == KeyEvent.VK_DOWN) {
                            if (bomb.isFalling == false)
                                bomb.isFalling = true;
                                bomb.centerX = boat.centerX;
                                bomb.centerY = boat.centerY;
                        }
            }
        } 
);
}

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (boat == null) {

            width = getWidth();
            height = getHeight();
            boat = new Boat();
            sub = new Submarine();
            bomb = new Bomb();
        }

        if (hasFocus())
            g.setColor(Color.CYAN);
        else {
            g.setColor(Color.RED);
            g.drawString("CLICK TO ACTIVATE", 20, 30);
            g.setColor(Color.GRAY);
        }

        g.drawRect(0,0,width-1,height-1);
        g.drawRect(1,1,width-3,height-3);
        g.drawRect(2,2,width-5,height-5);
        boat.draw(g);
        sub.draw(g);
        bomb.draw(g);
}

    private class Boat {
        int centerX, centerY;

        Boat() {
            centerX = width/2;
            centerY = 80;
        }

        void updateForNewFrame() {
            if (centerX < 0)
                centerX = 0;
            else 
                if (centerX > width)
                    centerX = width;
        }

        void draw(Graphics g) {
            g.setColor(Color.blue);
            g.fillRoundRect(centerX - 40, centerY - 20, 80, 40, 20, 20);
        }       
}

    private class Bomb {
        int centerX, centerY; 
        boolean isFalling; 

        Bomb() {
            isFalling = false;
        }

        void updateForNewFrame() {
            if (isFalling) {
                if (centerY > height) {
                    isFalling = false;
                }
                else 
                    if (Math.abs(centerX - sub.centerX) <= 36 && Math.abs(centerY - sub.centerY) <= 21) {
                        sub.isExploding = true;
                        sub.explosionFrameNumber = 1;
                        isFalling = false; // Bomba reapare in barca
                    }
                    else {
                        centerY += 10;
                    }
            }   
        }

        void draw(Graphics g) { 
            if ( !isFalling ) {
                centerX = boat.centerX;
                centerY = boat.centerY + 23;
            }
             g.setColor(Color.RED);
             g.fillOval(centerX - 8, centerY - 8, 16, 16); 
        }
} 

    private class Submarine {
        int centerX, centerY;
        boolean isMovingLeft;
        boolean isExploding;
        int explosionFrameNumber;

        Submarine() {
            centerX = (int)(width*Math.random());
            centerY = height - 40;
            isExploding = false;
            isMovingLeft = (Math.random() < 0.5);
        }

        void updateForNewFrame() {
            if (isExploding) {
                explosionFrameNumber++;
                if (explosionFrameNumber == 30) {
                    centerX = (int)(width*Math.random());
                    centerY = height - 40;
                    isExploding = false;
                    isMovingLeft = (Math.random() < 0.5);
                }
            }
            else {
                if (Math.random() < 0.04) {
                    isMovingLeft = ! isMovingLeft;
                }
                if (isMovingLeft) {
                    centerX -= 5;
                    if (centerX <= 0) {
                        centerX = 0;
                        isMovingLeft = false;
                    }
                }
                else {
                    centerX += 5;
                    if (centerX > width) {
                        centerX = width;
                        isMovingLeft = true;
                    }
                }
            }
        }

        void draw(Graphics g) {
            g.setColor(Color.BLACK);
            g.fillOval(centerX - 30, centerY - 15, 60, 30);
            if (isExploding) {
                g.setColor(Color.YELLOW);
                g.fillOval(centerX - 4*explosionFrameNumber, centerY - 2*explosionFrameNumber, 
                        8*explosionFrameNumber, 4*explosionFrameNumber);
                g.setColor(Color.RED);
                g.fillOval(centerX - 2*explosionFrameNumber, centerY - explosionFrameNumber/2, 
                        4*explosionFrameNumber, explosionFrameNumber);
            }
        }
    }

}

SubKiller类,main方法所在。

import javax.swing.JFrame;

public class SubKiller {
    public static void main(String[] args) {
        JFrame window = new JFrame("Sub Killer Game");
        SubKillerPanel content = new SubKillerPanel();
        window.setContentPane(content);
        window.setSize(700, 700);
        window.setLocation(0,0);
        window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        window.setResizable(false);
        window.setVisible(true);
    }
}

最佳答案

您在任何时候都只有一个炸弹被图形跟踪。您应该构建一个炸弹集合并在按下向下键时实例化一个新炸弹,然后遍历所有炸弹集合并根据需要绘制它们。

所以,而不是 private Bomb bomb;

你会得到 private List<Bomb> bombs;

之后,在任何地方更新单个 bomb您可以使用 for 循环遍历 bombs 的列表并让它们全部更新,然后如果它们不再被绘制,则将它们从列表中删除。

关于java - 按我的开火键时 SubKiller 游戏无法正常开火,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20056429/

相关文章:

java - 使用 Java 中的 GridBagLayout 无法正确调整面板大小

java - 使用 POI 创建单元格时出错

java - 如何检查输入是日期格式还是整数格式?使用java

java - 在 Java 中通过给定的最大汉明距离(不匹配数)获取所有字符串组合

java - Spring Boot 不允许对静态资源进行 POST 请求

java - Exportet jar 文件不会访问资源

java - 如何从 Avg Aggregation Builder elasticsearch 获取特定键的平均值

java - 普通类、单例类或静态方法以提高性能

java - 置换 Java 数组中位的最快方法

java - 为什么抑制功能不适用于跳跃窗口?