繁体   English   中英

Space Invaders Game - 按下空格键时只有一颗子弹发射。 如何让多发子弹发射?

[英]Space Invaders Game - Only one bullet is firing when space bar is pressed. How to get multiple bullets to fire?

我正在制作太空侵略者游戏,但我只能发射一颗子弹,按下空格键时如何让多颗子弹发射? 我目前只对宇宙飞船和子弹使用矩形。

这是主要的class。 这包含太空侵略者游戏的框架大小。

public static void main(String[] args) {
        JFrame jf = new JFrame();
        jf.setTitle("Shooter");
        jf.setSize(700, 500);
        jf.setResizable(false);
        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        Shooter ss = new Shooter();
        jf.add(ss);
        jf.setVisible(true);
        Thread t = new Thread(ss);
        t.start();
    }

这是射手 class。 这里我画了子弹和飞船,并设置了飞船运动的左右控制。

public class Shooter extends JPanel implements KeyListener, Runnable {

    int rectXPos = (700 / 2) - 50 / 2;
    int rectYPos = 425;
    boolean rightPressed, leftPressed, spaceBarPressed, fireBullet, shot;
    Rectangle bullet;
    int bulletXPos, bulletYPos;

    public Shooter() {
        addKeyListener(this);
        this.setFocusTraversalKeysEnabled(false);
        this.setFocusable(true);
    }

    public void paintComponent(Graphics g) {
        g.setColor(Color.BLUE);
        g.drawRect(0, 0, 700, 500);
        g.fillRect(0, 0, 700, 500);

        g.setColor(Color.YELLOW);
        g.drawRect(rectXPos, rectYPos, 50, 30);
        g.fillRect(rectXPos, rectYPos, 50, 30);

        if (shot) {
            g.setColor(Color.RED);
            g.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
        }
        repaint();
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            rightPressed = true;
            if (rectXPos >= 630) {
                rectXPos = 630;
            } else {
                moveRight();
            }
        }
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            leftPressed = true;
            if (rectXPos <= 5) {
                rectXPos = 5;
            } else {
                moveLeft();
            }
        }
        if (e.getKeyCode() == KeyEvent.VK_SPACE) {
            if (bullet == null) {
                fireBullet = true;
                if (fireBullet) {
                    bulletXPos = rectXPos;
                    bulletYPos = rectYPos;
                    bullet = new Rectangle(bulletXPos + 25, bulletYPos, 3, 5);
                    shot = true;
                }
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            rightPressed = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            leftPressed = false;
        }
        if (e.getKeyCode() == KeyEvent.VK_SPACE) {
            fireBullet = false;
            if (bullet.y <= -5) {
                bullet = new Rectangle(0, 0, 0, 0);
                shot = false;
                fireBullet = true;
            }
        }
    }

    public void shootBullet() {
        if (shot) {
            bullet.y--;
            System.out.println("shot fired");
        }
    }

    public void moveRight() {
        rightPressed = true;
        rectXPos += 15;
    }

    public void moveLeft() {
        leftPressed = true;
        rectXPos -= 15;
    }

    @Override
    public void run() {
        try {
            while (true) {
                moveRight();
                moveLeft();
                shootBullet();
                Thread.sleep(5);
            }
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }

}

根据代码,您的 KeyPressed/KeyReleased 逻辑对于发射多个子弹是正确的——您将 boolean fireBullet设置为 true 上的keyPressed事件,然后设置为 false 上的keyReleased

但是,您似乎在任何给定时间只能拥有一个Rectangle bullet ,因为您只声明了一个。 keyPressed事件期间,子弹实例将始终被覆盖(相关行bullet = new Rectangle(0, 0, 0, 0); )。

为了一次在屏幕上显示多个项目符号,您需要通过 List、数组或其他允许多个表示项目符号的Rectangle实例的结构来跟踪bullet

重构看起来像这样:

  • Rectangle bullet更改为List<Rectangle> bullets (或数组,或 Set 等)
  • shootBullet应该检查fireBullet是否为真。 如果是,您应该在列表中添加一个新项目符号
  • shootBullet还应该移动列表中的每个子弹(目前它移动子弹的单个实例)

需要注意的另一件事 - 根据帧更新的频率,您可能需要跟踪每秒可以发射多少子弹(建议的更改将允许在每次帧更新时创建一个子弹,这可能也是许多)。 然后,您需要在生成另一个子弹之前跟踪自最后一颗子弹发射以来的时间(或帧更新次数)。 这也需要在shootBullet中发生。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM