【发布时间】:2017-08-12 14:57:22
【问题描述】:
出于某种原因,每次我在我正在制作的游戏中跳跃时,跳跃都会比上一次跳跃更短。跳跃开始时长而雄伟(我的游戏设置在太空中),大约 10 次跳跃后,我的角色实际上是在地面上抽搐,因为跳跃的高度实际上不到一个像素。老实说,我无法找出它有什么问题,但我觉得这与我找到 deltaTime 的方式有关。请帮忙。我通常能够通过一些故障排除和/或谷歌搜索来解决我自己的问题,但老实说,我不知道出了什么问题,这一切对我来说都是合乎逻辑的。
很抱歉缺少 cmets。正如你可能从我讨厌的实现风格中看出的那样,这只是一个快速编写的项目,所以我不太关心以后看代码。我做这个主要是为了学习和练习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());
}
}
}
【问题讨论】:
-
"I don't really care much to look at the code later"-- 在这种情况下,你是对的,你不必担心代码看起来有多好或评论有多好,除非你问别人(我们!)为您审查它。 -
好的问题,在上面的代码中,你实际上在哪里有跳跃的逻辑?请解释这段代码,不幸的是我们无法编译或运行的代码,因为它具有我们不知道的依赖项。
-
您的增量时间不是增量时间,因为 beginTime 永远不会更新
-
欢迎来到 Stackoverflow。请通读"how do I ask a good question",并确保如果您需要其他真实人类的帮助,请努力显示minimal reproducible example。这将告诉我们您足够关心以实际找出问题所在,并让我们直奔主题,因为您显示的代码正是所涉及的代码。
标签: java game-physics