2017-08-12 60 views
-3

出于某种原因,每次我跳进我的比赛时,跳跃比前一跳都短。跳跃开始漫长而雄伟(我的游戏设置在太空中),经过大约10次跳跃后,我的角色真正地在地面上跳动,因为跳跃实际上小于一个像素的高度。我真的不知道它有什么问题,但我觉得它与我找到deltaTime的方式有关。请帮忙。我通常可以通过一些疑难解答和/或一些Google搜索来解决我自己的问题,但我真的不知道什么是错的,这对我来说都是合乎逻辑的。我的跳跃逻辑有什么问题?

抱歉,缺少评论。正如你可以从我讨厌的执行风格中看出的那样,这只是一个快速编写的项目,所以我以后不太关注代码。我主要是为了学习和练习Java。

我知道有很多课外参考,所以如果你需要看到一个(我相信我包括重要的),请让我知道。

播放器类(其延伸实体):

import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.util.ArrayList; 

import main.Main; 
import scenes.Scene; 
import threads.Time; 

public class Player extends Entity { 

    private Scene scene; 

    private int HorizontalAxis = 0; 

    public float speed = 0.5f; 
    public float gravity = 0.001f; 
    public float jumpSpeed = 1f; 

    private float moveVelX = 0, moveVelY = 0; 

    public Player(String name, String tag, int x, int y, int w, int h, String spritePath, Scene scene) { 
     super(name, tag, x, y, w, h, spritePath); 
     this.scene = scene; 
    } 

    public void Update() { 

     //System.out.println(isGrounded()); 

     if (Main.keyInput.getKeyState("MoveLeft")) { 
      HorizontalAxis = -1; 
     } 
     if (Main.keyInput.getKeyState("MoveRight")) { 
      HorizontalAxis = 1; 
     } 
     if (Main.keyInput.getKeyState("MoveLeft") == Main.keyInput.getKeyState("MoveRight")) { 
      HorizontalAxis = 0; 
     } 

     moveVelX = (HorizontalAxis * speed); 

     if (isGrounded()) { 
      moveVelY = 0; 

      if (Main.keyInput.getKeyState("Jump") || Main.keyInput.getKeyState("JumpAlt")) { 
       moveVelY = -jumpSpeed; 
      } 
     } else { 
      moveVelY += gravity * Time.deltaTime.getSeconds(); 
     } 

     setTrueX(getTrueX() + moveVelX); 
     setTrueY(getTrueY() + moveVelY); 
     System.out.println(moveVelY); 
    } 

    public void render(Graphics2D g) { 
     g.drawImage(getSprite(), getX(), getY(), getWidth(), getHeight(), Main.display); 
    } 

    public boolean isGrounded() { 
     ArrayList<Entity> groundEntities = scene.FindEntitiesWithTag("Ground"); 

     if (groundEntities.size() > 0) { 
      for (int i = 0; i < groundEntities.size(); i++) { 
       if (this.hitbox.intersects(groundEntities.get(i).hitbox)) { 
        return true; 
       } 
      } 

      return false; 
     } else { 
      System.err.println("There is no ground in the scene!"); 
      return false; 
     } 
    } 

} 

实体类:

import java.awt.Color; 
import java.awt.Graphics2D; 
import java.awt.Image; 
import java.awt.Rectangle; 
import java.awt.Toolkit; 

import main.Main; 

public class Entity { 

    public static enum AutoDrawTypes { NONE, RECTANGLE, RECTANGLE_ROUND, OVAL }; 
    public static AutoDrawTypes autoDrawType = Entity.AutoDrawTypes.NONE; 

    public String name; 
    public String tag; 

    protected float x, y; 

    protected int arcWidth, arcHeight; 

    protected Rectangle hitbox = new Rectangle(); 
    protected Image sprite; 

    protected Color color; 

    public Entity(String tag, String name, int x, int y, int w, int h, String spritePath) { 
     this.name = name; 
     this.tag = tag; 
     this.x = x; 
     this.y = y; 
     hitbox.setBounds((int)(getTrueX() - Camera.getX()), (int)(getTrueY() - Camera.getY()), w, h); 
     setSprite(spritePath); 
     this.autoDrawType = Entity.AutoDrawTypes.NONE; 
    } 

    public Entity(String tag, String name, int x, int y, int w, int h) { 
     this.name = name; 
     this.tag = tag; 
     this.x = x; 
     this.y = y; 
     hitbox.setBounds((int)(getTrueX() - Camera.getX()), (int)(getTrueY() - Camera.getY()), w, h); 
     this.autoDrawType = Entity.AutoDrawTypes.NONE; 
    } 

    public Entity(String tag, String name, int x, int y, int w, int h, Entity.AutoDrawTypes autoDrawType, Color color) { 
     this.name = name; 
     this.tag = tag; 
     this.x = x; 
     this.y = y; 
     hitbox.setBounds((int)(getTrueX() - Camera.getX()), (int)(getTrueY() - Camera.getY()), w, h); 
     this.autoDrawType = autoDrawType; 
     this.color = color; 
    } 

    public Entity(String tag, String name, int x, int y, int w, int h, Entity.AutoDrawTypes autoDrawType, Color color, int arcWidth, int arcHeight) { 
     this.name = name; 
     this.tag = tag; 
     this.x = x; 
     this.y = y; 
     hitbox.setBounds((int)(getTrueX() - Camera.getX()), (int)(getTrueY() - Camera.getY()), w, h); 
     this.autoDrawType = autoDrawType; 
     this.color = color; 
     this.arcWidth = arcWidth; 
     this.arcHeight = arcHeight; 
    } 

    public void UpdatePositionRelativeToCamera() { 
     hitbox.setBounds((int)(getTrueX() - Camera.getX()), (int)(getTrueY() - Camera.getY()), getWidth(), getHeight()); 
    } 

    public Entity() { 

    } 

    public void Update() { 
    } 

    public void render(Graphics2D g) { 
     g.setColor(color); 
     if (autoDrawType == Entity.AutoDrawTypes.RECTANGLE) { 
      g.fillRect(getX(), getY(), getWidth(), getHeight()); 
     } 
     if (autoDrawType == Entity.AutoDrawTypes.RECTANGLE_ROUND) { 
      g.fillRoundRect(getX(), getY(), getWidth(), getHeight(), arcWidth, arcHeight); 
     } 
     if (autoDrawType == Entity.AutoDrawTypes.OVAL) { 
      g.fillOval(getX(), getY(), getWidth(), getHeight()); 
     } 
    } 

    public void setTrueX(float x) {this.x = x;} 
    public void setTrueY(float y) {this.y = y;} 
    public void setX(int x) {hitbox.x = x;} 
    public void setY(int y) {hitbox.y = y;} 
    public void setWidth(int width) {hitbox.width = width;} 
    public void setHeight(int height) {hitbox.height = height;} 
    public void setSprite(String path) { 
     Toolkit tk = Toolkit.getDefaultToolkit(); 
     if (tk == null) { 
      System.err.println("Default Toolkit could not be fetched."); 
      return; 
     } 
     sprite = tk.getImage(Main.class.getResource(path)); 
     if (sprite == null) { 
      System.err.println("Image not found at + '" + path + "'. Check path in resources folder."); 
      return; 
     } 
    } 

    public float getTrueX() {return this.x;} 
    public float getTrueY() {return this.y;} 
    public int getX() {return hitbox.x;} 
    public int getY() {return hitbox.y;} 
    public int getWidth() {return hitbox.width;} 
    public int getHeight() {return hitbox.height;} 
    public Image getSprite() {return sprite;} 

} 

时序类(其在本申请的开始运行作为一个线程):

import java.time.Duration; 
import java.time.Instant; 

public class Time implements Runnable { 

    public static boolean running = false; 

    public static Duration deltaTime = Duration.ZERO; 
    public static Instant beginTime = Instant.now(); 

    public void run() { 
     while (running) { 
      deltaTime = Duration.between(beginTime, Instant.now()); 
     } 
    } 
} 
+4

''我以后再仔细查看代码并不太在意'' - 在这种情况下,您是对的,您不必担心代码的外观如何好或者评论如何, **除非你要求其他人(我们!)为你检查**。 –

+0

好的问题,在上面的代码中你确实有跳跃的逻辑?请解释这段代码,我们很遗憾无法编译或运行代码,因为它具有我们不知道的依赖关系。 –

+1

你的delta时间不是delta time,因为beginTime从不更新 –

回答

0

没关系,我修好了。这是我计算deltaTime的方式。我决定删除deltaTime并减小重力(尽管它已经非常小巧了)。这固定了奇怪的“随着时间的推移小跳”错误的事情。

+1

您不妨考虑删除问题 –

+0

您必须使用deltatime,否则重力会根据帧率而变化。但是deltatime应该是自上次更新以来的时间量,而不是自启动程序以来的时间量。 – spectras

+0

@spectras在物理上精确的模拟中,加速度和离开地面以来的时间量之间没有相关性,所以时间增量可能甚至不是必需的。 – templatetypedef

0

看看这个代码,用于使玩家倒下:

moveVelY += gravity * Time.deltaTime.getSeconds(); 

注意,这会导致播放机的Y速度由随着时间的函数量增加。就是说,就好像重力随着时间的推移而不断增加。因此,如果你早点跳起来,就像在月球上跳跃一样,如果你稍后跳跃,就像在木星或中子星表面跳跃一样。

要解决此问题,请删除对当前时间的依赖关系。只需通过引力项来增加y的速度,除非你用世界物理学做一些很酷的东西,否则它应该只是一个固定的常数。