简体   繁体   中英

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

I am making a space invaders game but I can only get one bullet to fire, how can I get multiple bullets to fire when the space bar is pressed? I am currently only using rectangles for the spaceship and for the bullets.

This is the main class. This contains the the size of the frame for the space invader game.

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

This is the shooter class. Here I draw the bullet and spaceship and set the left and right controls for the movement of the spaceship.

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

}

Based on the code, your KeyPressed/KeyReleased logic is correct for firing multiple bullets -- you are setting a boolean fireBullet to true on keyPressed events and then to false on keyReleased .

However, it appears you can only have exactly one Rectangle bullet at any given time because you have only declared one. The bullet instance will always be overwritten during the keyPressed event (the relevant line bullet = new Rectangle(0, 0, 0, 0); ).

In order to have more than one bullet on-screen at a time, you need to keep track of the bullets via a List, array, or other structure allowing multiple instances of Rectangle s representing bullet .

The refactor would look something like this:

  • Change the Rectangle bullet to List<Rectangle> bullets (or an array, or a Set, etc)
  • shootBullet should check to see if fireBullet is true. If it is, you should add a new bullet to the list
  • shootBullet should also move every bullet in the list (currently it moves the single instance of bullet)

One other thing to note -- depending on how frequently the frame updates, you may also want to keep track of how many bullets can be fired per second (the suggested changes would allow one bullet to be created per frame update, which may be too many). You would then need to track the time (or number of frame updates) since the last bullet was fired prior to spawning another. That would also need to happen in shootBullet .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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