java - 我不确定什么是不正确的

标签 java swing

我正在创建一个小型 Java Jpanel 游戏,其中我应该有一个通过箭头上下移动并通过空间发射的火箭。
发射方法应该像这样工作:按下空格键,物体发射并在屏幕上移动,然后当它击中某个 x 时,它就会消失。此外,你只能开火一次,直到另一颗子弹消失。
我不知道我做错了什么。首先,我的代码一启动,您就可以看到一颗子弹飞过屏幕。
第二,子弹没有消失。
第三,即使另一颗子弹仍然可见,它允许我再次开火。

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;
import java.util.Random;   
import javax.imageio.ImageIO;
import javax.swing.*;
@SuppressWarnings("serial")

public class SpaceGame extends JPanel implements ActionListener{
    Timer t = new Timer(2, this);

    private ImageIcon rocket,asteroid,bullet;
    private JLabel rocketlabel,ast1,ast2,ast3,bulletLabel;
    public static int y=90,dy=0,bulletX=110,bulletY,i=0,canFire;
    //public sound sound;
    static boolean bulletFired=false;;
    static JFrame f = new JFrame();

    SpaceGame(){
        this.setBackground(Color.black);
        rocket = new ImageIcon(getClass().getResource("rocketFinal.png"));
        rocketlabel= new JLabel(rocket);
        this.add(rocketlabel);
        asteroid = new ImageIcon(getClass().getResource("asteroid.png"));
        ast1=new JLabel(asteroid);
        ast2=new JLabel(asteroid);
        ast3=new JLabel(asteroid);
        bullet = new ImageIcon(getClass().getResource("bulletReal.png"));
        bulletLabel = new JLabel(bullet);
        canFire=1;
        bulletLabel.setVisible(false);
         this.add(ast1);this.add(ast2);this.add(ast3);this.add(bulletLabel);

        f.addKeyListener(new controller());

        this.setLayout(null);
        this.setVisible(true);
    }

    public class controller implements KeyListener{

        @Override
        public void keyPressed(KeyEvent e) {
            int keyCode = e.getKeyCode();           

               if(keyCode== KeyEvent.VK_UP) {

                    dy=-1;

                   }
                if(keyCode== KeyEvent.VK_DOWN) {

                   dy=1;
                }
              if(keyCode== KeyEvent.VK_SPACE) {
                   if(canFire==0) {

                       System.out.println(String.valueOf(canFire));
                       bulletFired = true;

                       bulletY = y; 
                       bulletX=110;
                       }canFire=1;                      
              }
             }

        @Override
        public void keyReleased(KeyEvent e) {
            int key = e.getKeyCode();

            switch(key) {
            case KeyEvent.VK_UP: dy=0; break;
            case KeyEvent.VK_DOWN: dy=0; break;

            }
        }

        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub              
        }

    }
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        rocketlabel.setBounds(45,y,rocket.getIconWidth(),80);
        fireBullet();

        paintStars(g);
        t.start();
    }

    public void paintStars(Graphics g) {
        g.setColor(Color.yellow);
        for(int i=0; i<5;i++) {

            Random rand = new Random();
            int o = rand.nextInt(500);
            int p = rand.nextInt(300);
            g.fillOval(o, p, 3, 3);

        }
    }
    public void actionPerformed(ActionEvent e) {
        if(y==-20) y=249;
        if(y==250)y=-20;
        y+=dy;
        if(bulletFired=true) {
            bulletX++;
            if(bulletX==455)bulletFired=false;bulletLabel.setVisible(false);System.out.println(String.valueOf(bulletX)); canFire=0; 

        }

        repaint();
    }
    public void fireBullet(){
    if(bulletFired=true) {
        bulletLabel.setVisible(true);
        bulletLabel.setBounds(bulletX,bulletY+25,bullet.getIconHeight(),bullet.getIconWidth());
    }

   }

    public static void main(String[] args) {
        String filepath = "SpaceGameMusic.wav";
        musicStuff musicPlayer = new musicStuff();

        musicPlayer.playMusic(filepath);
        SpaceGame t = new SpaceGame();

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(t);
        f.setSize(500,335);
        f.setVisible(true);
        f.setResizable(false);
    }
}

最佳答案

For one, as soon as my code starts you can see a bullet flying across the screen.

paintComponent() 方法仅用于绘画。您无法控制 Swing 何时确定组件需要重新绘制。

例如:

t.start();

不应该出现在绘画方法中。一旦框架可见,面板将被绘制并且计时器将启动。

您的应用程序代码应该控制计时器何时启动。

其他问题:

  1. 您不应该使用静态变量。该变量应该只是您的类的实例。

  2. paintStars() 方法不应生成随机位置。再次。绘画方法应该只绘制类的当前状态。因此,如果您想更改星星的位置,您应该使用像 randomizeStars() 这样的方法。在此方法中,您将更新 Point 对象的 ArrayList。每个 Point 实例代表一颗星星的位置。然后,paintStars() 方法将简单地迭代 ArrayList 并绘制每个星星。

  3. 您不应该使用 KeyListener。 KeyListener 仅在组件具有焦点时才起作用。您不能保证您的组件会失去焦点。相反,您应该使用按键绑定(bind)。即使组件没有焦点,键绑定(bind)也允许您处理 KeyEvent。请参阅Motion Using the Keyboard了解更多信息和工作示例。

you can only fire once until the other bullet disappears

您的 canFire 变量应该是 boolean 变量,因此它只有 true/false 值。同样,您有一个设置状态的方法。然后,您的游戏逻辑将在再次发射子弹之前检查状态。

if(y==-20) y=249;
if(y==250)y=-20;

不要对值进行硬编码。该数字应根据面板的大小而定。因此,您可以使用 getWidth() 和 getHeight() 等方法来确定面板的当前大小。

关于java - 我不确定什么是不正确的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62009708/

相关文章:

java - 幸存者空间达到 100% 满的原因是什么

java - 如何使用 SSL 设置 mySql JDBC 连接

java - 计算 3d 相机矩阵

java - Autowiring 抽象组件

java - 使用验证或重新验证删除 Swing 组件

conflict - java glassfish jdk 7 jre 6版本冲突

java - 为什么我的 Java 桌面应用程序无法运行?

java - PopUp 类似乎可以加快动画速度

Java Swing : How to remove the default-spacing for JButtons in a JPanel

java - 将换行符保存在 JTextField 中