簡體   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