我正在尝试制作一个 java 2d 游戏,而且总体上看起来效果很好。唯一的问题是,我不知道如何设置我的“增量”时间,以使运动在 30 FPS 和 1000 FPS 上移动相同。
这是我的实体类代码:
import java.awt.Rectangle;
import map.Tile;
import graphics.Sprite;
public class Entity {
private String name;
private float positionx, positiony; // Current coordinate
private int targetx,targety; // Target coordinate
private double vx, vy; // Current vector
private double lx, ly; // Last vector
private float speed;
private Sprite sprite;
public Entity(String name, int x, int y, Sprite sprite){
this.name = name;
this.speed = 1f;
this.positionx = x;
this.positiony = y;
this.sprite = sprite;
main.Main.e.addEntity(this); // These kind of calls are ugly, and should be fixed.
}
public void remove(){
main.Main.e.removeEntity(this);
sprite.remove();
}
public void setVector(double vx, double vy){
this.vx = vx;
this.vy = vy;
}
public void update(long delta){
//Multiply modifier to make it act the same on 30 fps as 1000 fps.
vx = vx*delta;
vy = vy*delta;
// Calculate vector
double distance = Math.sqrt((vx * vx) + (vy * vy));
if(distance > 0){ // Have we reached the target yet?
vx = ((vx / distance));
vy = ((vy / distance));
}else{
vx = 0;
vy = 0;
}
//Check collision with objects:
Rectangle rx = new Rectangle((int) (vx+positionx), (int)positiony, 32, 32);
Rectangle ry = new Rectangle((int) positionx, (int)(vy+positiony), 32, 32);
for(Entity e : main.Main.e.getEntities()){
if(this != e){
if(isIntersecting(rx, e.getBounds())){
vx = 0; // Disallow x direction.
}
if(isIntersecting(ry, e.getBounds())){
vy = 0; // Disallow y direction.
}
}
}
//Check tiles:
for(Tile t : main.Main.m.getNeighbours(positionx,positiony)){
if(t.isBlocking()){
if(isIntersecting(rx, t.getBounds())){
vx = 0;
}
if(isIntersecting(ry, t.getBounds())){
vy = 0;
}
}
}
//Update the position:
positionx += vx*speed;
positiony += vy*speed;
//Animate:
animate(vx, vy);
}
public boolean isIntersecting(Rectangle r1, Rectangle r2){
return r1.intersects(r2);
}
public Rectangle getBounds(){
return new Rectangle((int) positionx,(int) positiony,32,32);
}
public void setMoveTo(int x, int y){
this.targetx = x;
this.targety = y;
}
//This function is used by the bots, and not on players (they are setting the vector and use update directly):
public void moveTo(long delta){
setVector((targetx-positionx),(targety-positiony));
update(delta);
}
public void animate(double dx, double dy){
sprite.setPosition((int)positionx, (int)positiony);
if(dx > 0){
sprite.setAnimation(0, 7, 100); // Walk right.
}else if(dx < 0){
sprite.setAnimation(1, 7, 100); // Walk left.
}else{
if(lx > 0){
sprite.setAnimation(2, 3, 200); // Stand right.
}else if(lx < 0){
sprite.setAnimation(3, 3, 200); // Stand left.
}
}
lx = dx;
ly = dy;
}
}
我经常遇到的两个问题:
1# 游戏在 60FPS 和 500FPS 上的运行方式不同。
2# 游戏在 60FPS 和 500FPS 上运行相同,但是我的碰撞搞砸了,我不能移动到距离另一个对象超过 15px 的地方。我想我需要实现类似的东西:如果我不能靠近 10px,那么将它移近 10px,但我不知道如何实现它。
如何正确实施?那会有很大帮助!