【问题标题】:Jetpack Joyride user movementJetpack Joyride 用户移动
【发布时间】:2021-10-04 03:48:49
【问题描述】:

我正在尝试创建一个类似于喷气背包兜风的游戏,在该游戏中,用户可以按住空格键向上并松开向下旅行。我正在使用计时器来模拟重力并使用keyPressedkeyReleased 来检查用户是否按住空格键。我正在使用打印语句来确定 keyPressed 和 keyReleased 都在工作,但我不知道为什么物理没有运行。我不知道问题是否是我的 if 语句没有更新,是否是在 if 语句中创建的新计时器。无论哪种方式,重力都没有改变,我被卡住了。感谢您的帮助。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Calendar;



public class Game implements KeyListener {
    JFrame frame;
    JLabel player;

    public boolean grounded = false;
    public int velocity = 0;
    public int finalY = 0;
    public boolean spaceHeld = false;


    Action spaceAction;

    Game() {
         
        frame = new JFrame("Nicholas Seow-Xi Crouse");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(1920, 1080);
        frame.setLayout(null);
        
        frame.setFocusable(true);
        frame.addKeyListener(this);

        player = new JLabel();
        player.setBackground(Color.red);
        player.setBounds(10, 1800, 50, 50);
        player.setOpaque(true);

        frame.add(player);
        frame.setVisible(true);
        
         Timer flightTime = new Timer();
         TimerTask flight = new TimerTask() {
         
            public void run() {
                  if(velocity > -5) {
                  velocity -= 1;
                  }
                  else{
                  velocity = -5;
                  }
                  if (finalY < -61) {
                   finalY = finalY + velocity;
                   }
                   else{
                   finalY = -61;
                   }
                   player.setLocation(player.getX(), player.getY() + finalY);
                   if (player.getY() <= 0){
                   cancel();
                   velocity = 0;
                   finalY = 0;
                   player.setLocation(player.getX(), 0);
                    
                   }  
            }
      };
         

         Timer gravityTime = new Timer();
         TimerTask gravity = new TimerTask() {


            //creates a timer run method that simulates the falling gravity when not grounded
            public void run() {
                if(velocity < 5){
                velocity += 1;
                }
                else{
                velocity = 5;
                }
                //creates the variable the tells where the player is located
                if (finalY < 61) {
                finalY = finalY + velocity;
                }
                else{
                finalY = 61;
                }
                player.setLocation(player.getX(), player.getY() + finalY);
                if (player.getY() >= 1000){
                cancel();
                velocity = 0;
                finalY = 0;
                player.setLocation(player.getX(), 990); 
                }
                
            }
        };

        if (spaceHeld == false ) {
            gravityTime.scheduleAtFixedRate(gravity, 0, 33);
        }
        if (spaceHeld == true ) {
            flightTime.scheduleAtFixedRate(flight, 0 ,33);
    }
}

public void keyTyped(KeyEvent e) {
}

public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_SPACE){
spaceHeld = true;
//debug
System.out.println(spaceHeld);
}
}

public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_SPACE){
spaceHeld = false;
//debug
System.out.println(spaceHeld);
}
}
}

【问题讨论】:

    标签: java if-statement


    【解决方案1】:

    代码是基于事件的,目前没有任何东西会触发您的计时器启动。为此,您只需在关键事件中移动计时器计划/开始操作:

    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_SPACE){
    
                //Cancel the other timer here so that they don't overlap
                gravity.cancel();
                gravityTime.cancel();
    
                //Create a new instance of the timer
                flightTime = new Timer();
                flight = new TimerTask() {
         
                    public void run() {
                        if(velocity > -5) {
                            velocity -= 1;
                        }
                        else{
                            velocity = -5;
                        }
                        if (finalY < -61) {
                            finalY = finalY + velocity;
                        }
                        else{
                            finalY = -61;
                        }
    
                        player.setLocation(player.getX(), player.getY() + finalY);
                        if (player.getY() <= 0){
                            cancel();
                            velocity = 0;
                            finalY = 0;
                            player.setLocation(player.getX(), 0);
                        }  
                    }
                };
    
                //Now start the timer
                flightTime.scheduleAtFixedRate(flight, 0 ,33);
            }
        }
        
        //Do the same for the gravity method
        public void keyReleased(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_SPACE){
    
                ......
    
            }
        }
    }
    

    请注意,您还应该取消具有相反键事件的其他计划任务,以免它们相互重叠并重视奇怪的结果。

    要使 keyPressed 方法可以访问 flightTimegravityTime,只需将它们声明为类变量:

    public class Game implements KeyListener {
        JFrame frame;
        JLabel player;
    
        public boolean grounded = false;
        public int velocity = 0;
        public int finalY = 0;
        public boolean spaceHeld = false;
    
        //Move them here but don't assign a value:
        public Timer flightTime;
        public TimerTask flight;
        public Timer gravityTime;
        public TimerTask gravity;
    

    您仍然可以稍后在 Game 方法中创建对象:

    flightTime = new Timer();
    flight = new TimerTask() {
        ....
    };
    

    【讨论】:

    • 你好,这个方法对我有用,虽然我收到一个异常说重力任务已经安排好了。有什么想法吗?
    • @ZZBowzer 确保在再次尝试运行之前先取消它gravity.cancel();,或者如果任务已经在运行,则无需再次启动它,让它运行?
    • 您也可以在 KeyPressed 方法中移动计时器的创建(请参阅上面我编辑的代码),但是如果计时器没有正确停止,这仍然可能会导致计时器重叠的问题。老实说,最好使用单个计时器/任务来控制永远不需要取消/启动的动画,并让它读取一个布尔值以查看它是否应该向上或向下移动。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-01
    • 2014-03-31
    • 2016-10-25
    • 2021-04-16
    相关资源
    最近更新 更多