简体   繁体   English

如何使用 JavaFx 让我的角色跳跃?

[英]How do I make my character jump using JavaFx?

I want to make my character jump using JavaFx.我想使用 JavaFx 让我的角色跳跃。 When I click SPACE many times fast, the character fall down rapidly and disappear.当我多次快速点击SPACE时,角色迅速下落并消失。 When I click SPACE many times but slower, the character jumps as it should.当我多次单击SPACE但速度较慢时,角色会按原样跳跃。

I am not sure what the problem is but I think it has something to do with AnimationTimer and its frames.我不确定问题是什么,但我认为它与 AnimationTimer 及其帧有关。 Maybe I am using a wrong way to make my character jump, so if it is that, can someone give me the right way?也许我用错误的方式让我的角色跳跃,所以如果是这样,有人能给我正确的方法吗? I have to use JavaFx.我必须使用 JavaFx。
Avatar: image of my character.头像:我的角色形象。 I used gravity and AnimationTimer to make curve like a jump.我使用了重力和 AnimationTimer 来制作像跳跃一样的曲线。

int gravity = 0;
boolean left, right;
window.getScene().setOnKeyPressed(ePress -> {
           KeyCode keycode = ePress.getCode();
           if(keycode.equals(keycode.D)){
               avatar.setTranslateX(avatar.getTranslateX() + 35);
               right = true;
           }
           if(keycode.equals(keycode.A)){
               avatar.setTranslateX(avatar.getTranslateX() - 35);
               left = true;
           }
           if(keycode.equals(keycode.W)){
               avatar.setTranslateY(avatar.getTranslateY() - 35);
           }
           if(keycode.equals(keycode.S)){
               avatar.setTranslateY(avatar.getTranslateY() + 35);
           }
           if(keycode.equals(keycode.SPACE)){
               double ypreviousPos = avatar.getTranslateY();
               jumpTimer = new AnimationTimer(){
                   @Override
                   public void handle(long now) {
                       avatar.setTranslateY(avatar.getTranslateY() - 10 + gravity);
                       gravity = gravity + 1;
                       if(ypreviousPos == avatar.getTranslateY()){
                             jumpTimer.stop();
                             gravity = 0;
                         }
                       if(right == true ){
                         avatar.setTranslateX(avatar.getTranslateX() + 10);
                         avatar.setTranslateY(avatar.getTranslateY() - 10 + gravity);
                         gravity = gravity + 1;
                         if(ypreviousPos == avatar.getTranslateY()){
                             jumpTimer.stop();
                             gravity = 0;
                         }
                       }  
                        if(left == true ){
                         avatar.setTranslateX(avatar.getTranslateX() - 10);
                         avatar.setTranslateY(avatar.getTranslateY() - 10 + gravity);
                         gravity = gravity + 1;
                         if(ypreviousPos == avatar.getTranslateY()){
                             jumpTimer.stop();
                             gravity = 0;
                         }
                       }
                   }

               };
                   jumpTimer.start();
           }                
        });

        window.getScene().setOnKeyReleased(eRel -> {
             KeyCode keycode = eRel.getCode();
           if(keycode.equals(keycode.D)){
               right = false;
           }
           if(keycode.equals(keycode.A)){
               left = false;
           }
        });
    });

You need to avoid starting a new AnimationTimer if one is already running: otherwise two (or more) AnimationTimer s will be modifying the translateY property, and the gravity field, simultaneously.如果一个新的AnimationTimer已经在运行,你需要避免启动它:否则两个(或多个) AnimationTimer将同时修改translateY属性和gravity场。 As a consequence, you are probably skipping the start position and at least one of the animation timers fails to stop.因此,您可能会跳过开始位置,并且至少有一个动画计时器无法停止。

Replacing更换

if(keycode.equals(keycode.SPACE))

with

if(keycode.equals(keycode.SPACE) && gravity==0)

should work.应该管用。

Note also that it's generally a bad idea to test for equality with floating point types.另请注意,测试浮点类型的相等性通常是一个坏主意。 Because of possible rounding errors in floating point arithmetic, you might never get exact equality where you expect it.由于浮点运算中可能存在舍入错误,您可能永远不会在您期望的地方获得完全相等。 (In this case, I think it will work, since you are only adding integer values to your double ; however, you should follow best practice anyway.) You should probably also replace (在这种情况下,我认为它会起作用,因为您只是将整数值添加到您的double ;但是,无论如何您都应该遵循最佳实践。)您可能还应该替换

if(ypreviousPos == avatar.getTranslateY())

with

if(ypreviousPos <= avatar.getTranslateY())

Finally, you might consider refactoring this so there is only a single AnimationTimer , running constantly, and just arrange for your key handler to change values that cause the timer to make a jump happen.最后,您可能会考虑重构它,以便只有一个AnimationTimer持续运行,并且只需安排您的键处理程序更改导致计时器发生跳转的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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