首页 > 解决方案 > 当我创建另一个子弹对象时,如何连续移动这些“子弹”?

问题描述

我刚开始学习 Java,最近学习了 Timer 类。我正在尝试将迄今为止所学的知识应用到制作这个宇宙飞船发射子弹的项目中。我的所有控件都可以正常工作,但是当我创建另一个项目符号对象时,我遇到了先前的项目符号中途停止的问题。我从昨天开始一直在搜索,但似乎找不到合适的关键字。我想我明白它为什么会停止但我怎样才能让子弹继续移动?

我在我的 JFrame 中添加了这个 GamePanel 类。

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class GamePanel extends JPanel implements KeyListener, ActionListener {

    int panelWidth = 500;
    int panelHeight = 500;
    
    JLabel spaceship;
    int shipWidth = 50;
    int shipHeight = 50;
    int shipX = 0;
    int shipY = panelHeight - shipHeight; // BOTTOM of GamePanel
    int shipXVelocity = 5;
    
    JLabel bullet;
    int bulletWidth = 10;
    int bulletHeight = 25;
    int bulletX;
    int bulletY;
    int bulleyYVelocity = 7;
    
    boolean left,right = false;
    
    Timer timer;
    
    GamePanel() {
        
        timer = new Timer(10,this);
        timer.start();
        
        this.setPreferredSize(new Dimension(panelWidth,panelHeight));
        this.setLayout(null);
        this.setBackground(Color.black);
        this.setFocusable(true);
        this.addKeyListener(this);
        
        spaceship = new JLabel();
        spaceship.setBounds(shipX, shipY, shipWidth, shipHeight);
        spaceship.setBackground(Color.green);
        spaceship.setOpaque(true);
        
        this.add(spaceship);
        
    }

    void shoot() {
        
        bulletX = shipX + (shipWidth / 2) - (bulletWidth / 2); // CENTER-TOP of spaceship
        bulletY = shipY;
        
        bullet = new JLabel();
        bullet.setBounds(bulletX, bulletY, bulletWidth, bulletHeight);
        bullet.setBackground(Color.white);
        bullet.setOpaque(true);

        this.add(bullet);
        
    }
    
    @Override
    public void keyTyped(KeyEvent e) {
        
        switch(e.getKeyChar()) {
        case 'a' : left = true;
        break;
        case 'd' : right = true;
        break;
        }
        
    }

    @Override
    public void keyPressed(KeyEvent e) {
        
        switch(e.getKeyCode()) {
        case 10 : shoot();
        break;
        }
        
    }

    @Override
    public void keyReleased(KeyEvent e) {
        
        switch(e.getKeyChar()) {
        case 'a' : left = false;
        break;
        case 'd' : right = false;
        break;
        }
        
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        
        if(left == true && shipX > 0) shipX -= shipXVelocity;
        if(right == true && shipX < panelWidth - shipWidth) shipX += shipXVelocity;
        spaceship.setLocation(shipX, shipY);
        
        if(bullet != null) { // Move if a bullet exist
            bulletY -= bulleyYVelocity;
            bullet.setLocation(bulletX, bulletY);
        }
        
        if(bulletY < 0) this.remove(bullet);;
        
    }
    
}

输出:

当我射出另一颗子弹时子弹停止

标签: javaswingobject

解决方案


有两种可能的解决方案:

  1. 多线程:对于你发射的每颗子弹,打开只为这颗子弹工作的新计时器,直到子弹停止,就像他击中某物一样。
  2. 为所有子弹创建一个列表:创建一个子弹列表,每次发射新子弹时,将其添加到列表中,而不会覆盖以前的子弹。然后,在您的 actionPerformed 方法中循环遍历整个列表,更新那里的每个项目符号并从列表中删除应该消失的项目符号。

我认为第二种解决方案更适合您的游戏,没有太多计算的是他的对象移动。


推荐阅读