【问题标题】:I am not sure what is incorrect我不确定什么是不正确的
【发布时间】:2020-09-12 12:31:59
【问题描述】:

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

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

【问题讨论】:

    标签: java swing


    【解决方案1】:

    首先,只要我的代码启动,您就会看到一颗子弹飞过屏幕。

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

    所以,例如:

    t.start();
    

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

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

    其他问题:

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

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

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

    你只能开火一次,直到另一颗子弹消失

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

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

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

    【讨论】:

    • camickr 我故意把 t.start 放在了paintComponent 中。只有当 bulletFired 为 true 时,子弹才应该在绘制,并且 bulletFired 开始为 false,因此它不应该出现。第二,canFire 一开始是一个布尔值,我改变了它看看它是否有帮助 - 它没有。最后,硬编码值。应该不会影响任何事情。
    • 我再次声明一种绘画方法是只用于绘画的。您不应该启动计时器。每次调用绘画方法(您无法控制)时,都会启动 Timer。 硬编码值。应该不会影响任何事情可能不会,但鉴于给出的原因,这是一种很好的做法,并且可以防止将来出现潜在问题。 canFire 起初是一个布尔值, - 那为什么要改变它呢?问题在于您的逻辑,而不是布尔值。
    • bulletFired 开始为假 - 你怎么知道?我在fireButtet() 方法中看不到调试代码。也许你有逻辑在你不期望的时候翻转开关。当您不期望它时,标签可能仍然可见。解决问题的唯一方法是调试代码。您已获得提示。
    • 我在声明它的地方开始它是假的。
    • 仅仅因为它开始为假并不意味着某些逻辑将其更改为真。这就是逻辑问题。该代码无法按您期望的方式工作。因此,您调试您的代码并不断显示该值以查看它何时发生变化,以及它是否在您期望它发生变化时发生变化。
    【解决方案2】:

    问题很简单,就是我忘记在 if(boolean) 语句中使用 ==。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-27
      • 2012-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多