gpt4 book ai didi

Java 2d 游戏 - 增量时间和碰撞问题

转载 作者:行者123 更新时间:2023-11-30 09:19:02 25 4
gpt4 key购买 nike

我正在尝试制作一款 Java 2d 游戏,总体来说似乎运行良好。唯一的问题是,我无法弄清楚如何放置我的“delta”时间,使运动在 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 下的运行速度相同,但我的碰撞搞砸了,我不能移动到离另一个物体 15 像素以内。我想我需要实现类似的东西:如果我不能靠近 10px,那么将它移动 10px,但我不知道如何实现它。

如何正确实现?那会有很大帮助!

最佳答案

最简单的方法是考虑如果你想要一个恒定的位移和恒定的速度,你可以像这样缩放相对于 30 FPS 的增量的所有增量:

enter image description here

因此,如果您以 60 FPS 运行但想要与 30FPS 相同的位移,alpha 将是 (1/30)/(1/60) = 2

所以删除 vx = vx*delta;
vy = vy*delta;

并将您的位置更新更改为

alpha = (1.0/30)*delta;
positionx += alpha*vx*speed;
positiony += alpha*vy*speed;

这只是一个粗略的解决方案,让我知道它是如何工作的,我会稍后访问并更新更正确的解决方案(考虑到由于渲染和计算需要一些时间,delta 并不总是 1/FPS) .

编辑:变量 delta 稍后会出现。但是一些优化:

  1. 您不需要在 Y 轴和 X 轴上都构造一个矩形来进行碰撞检测,尝试绘制两个矩形,如果它们在两个轴上相交。只需从 vx + posx, vy+posy 创建一个矩形并检查与它的交集。
  2. 以上应该是你碰撞检查的一半。为了进一步优化考虑使用 QuadTree,可以找到一个实现 here .

  3. 关于“ block 状”碰撞测试的问题(您从阻挡对象停止 X 像素)。您可以使用伪代码执行以下操作:

     if(new position will make this colide)
    while(this.position is more than one pixel away from blocking object)
    keep moving one pixel

这将使您在距目标 1 像素处停止。

关于Java 2d 游戏 - 增量时间和碰撞问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18147880/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com