我的跳跃逻辑有什么问题?
出于某种原因,每次我跳进我的比赛时,跳跃比前一跳都短。跳跃开始漫长而雄伟(我的游戏设置在太空中),经过大约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());
}
}
}
没关系,我修好了。这是我计算deltaTime的方式。我决定删除deltaTime并减小重力(尽管它已经非常小巧了)。这固定了奇怪的“随着时间的推移小跳”错误的事情。
您不妨考虑删除问题 –
您必须使用deltatime,否则重力会根据帧率而变化。但是deltatime应该是自上次更新以来的时间量,而不是自启动程序以来的时间量。 – spectras
@spectras在物理上精确的模拟中,加速度和离开地面以来的时间量之间没有相关性,所以时间增量可能甚至不是必需的。 – templatetypedef
看看这个代码,用于使玩家倒下:
moveVelY += gravity * Time.deltaTime.getSeconds();
注意,这会导致播放机的Y速度由随着时间的函数量增加。就是说,就好像重力随着时间的推移而不断增加。因此,如果你早点跳起来,就像在月球上跳跃一样,如果你稍后跳跃,就像在木星或中子星表面跳跃一样。
要解决此问题,请删除对当前时间的依赖关系。只需通过引力项来增加y的速度,除非你用世界物理学做一些很酷的东西,否则它应该只是一个固定的常数。
''我以后再仔细查看代码并不太在意'' - 在这种情况下,您是对的,您不必担心代码的外观如何好或者评论如何, **除非你要求其他人(我们!)为你检查**。 –
好的问题,在上面的代码中你确实有跳跃的逻辑?请解释这段代码,我们很遗憾无法编译或运行代码,因为它具有我们不知道的依赖关系。 –
你的delta时间不是delta time,因为beginTime从不更新 –