目前我有一些小行星游戏,可以在这里看到:
http://www.youtube.com/watch?v=rQV6H9kWkFE
但是当用户在船仍在移动时按下W时,它将采用船舶移动的速度而不管其旋转并加到它上面,导致船只出现生涩而不协调(难以解释,观看视频)。
以下是我正在使用的代码:
public void update(int delta) throws SlickException
{
float hip = speed * delta;
float rotation = image.getRotation();
for (Bullet b : bulletList)
{
b.update(delta);
}
Input input = gc.getInput();
if (input.isKeyDown(Input.KEY_A))
{
image.rotate(rotateLeftSpeed * delta);
if (rotateLeftSpeed > (ROTATE_LIMIT * -1))
{
rotateLeftSpeed -= rotateSpeed;
}
} else
{
if (rotateLeftSpeed < 0)
{
image.rotate(rotateLeftSpeed * delta);
rotateLeftSpeed += rotateSpeed;
}
}
if (input.isKeyDown(Input.KEY_D))
{
image.rotate(rotateRightSpeed * delta);
if (rotateRightSpeed < (ROTATE_LIMIT))
{
rotateRightSpeed += rotateSpeed;
}
}
else
{
if (rotateRightSpeed > 0)
{
image.rotate(rotateRightSpeed * delta);
rotateRightSpeed -= rotateSpeed;
}
}
if (input.isKeyDown(Input.KEY_W))
{
hip = speed * delta;
protation = image.getRotation();
rotation = image.getRotation();
x += hip * Math.sin(Math.toRadians(rotation));
y -= hip * Math.cos(Math.toRadians(rotation));
if (speed < SPEED_LIMIT)
speed += 0.005f;
} else
{
if (speed > 0)
{
System.out.println(offSpeed);
srotation = image.getRotation();
hip = speed * delta;
x += hip * Math.sin(Math.toRadians(protation));
y -= hip * Math.cos(Math.toRadians(protation));
speed -= 0.003f;
}
}
无论如何我可以在不引入dx和dy值的情况下完成此操作吗?尽可能少的修改?
答案 0 :(得分:3)
问题很明显,即使你面向一个方向,但这并不意味着当你打开推进器时,你会向这个方向移动。
你需要第二个内部方向向量,当你的推进器开启时,它会更新,最有可能是通过简单的向量加法和随后的标准化。然后使用那个方向来计算将力施加到船上的方向。
答案 1 :(得分:1)
最后,我使用了这个:
if (input.isKeyDown(Input.KEY_W))
{
dx += Math.sin(Math.toRadians(image.getRotation())) * delta * 0.01;
dy += -Math.cos(Math.toRadians(image.getRotation())) * delta * 0.01;
}
x += dx;
y += dy;
dx *= 0.98;
dy *= 0.98;
答案 2 :(得分:0)
根据dx
和dy
而不是速度和角度跟踪玩家的动作,并在按下W时添加到这些值。
答案 3 :(得分:0)
我认为问题在于你正在加入从W直接按X,Y坐标的冲动。你需要做的是有一个带X,Y坐标的速度矢量,并在用户推力时加上它。
在每个时间步上,将x速度和y速度分量添加到X,Y坐标。
基础物理学是你有位置(x,y),速度(dx / dt,dy / dt)和加速度(dx ^ 2 / dt,dy ^ 2 / dt)。推力提供了一个加速度,你必须随着时间的推移积分,以提供速度,然后随着时间的推移积分速度,以提供位置。
答案 4 :(得分:0)
您需要实现物理学中的两个“概念”: 速度和摩擦力。
这是2D中的一个简单示例。您还可以使用包装类将x / y变量组合到单个对象中,并提供方便的方法来更改其内容。
每个对象都需要有一个位置和一个速度变量。我们还需要摩擦,这是每种材料的常数(因为你的物体可能总是在相同的材料中运行,我们只是模拟摩擦力是恒定的)。在这个简单的模拟中,当摩擦力达到1时,摩擦力会变弱。这意味着在摩擦力= 1时你没有摩擦力,在摩擦力为0时你的物体会立即停止:
public class PhysicsObject{
public static final double FRICTION = 0.99;
private double posX;
private double posY;
private double speedX = 0;
private double speedY = 0;
public PhysicsObject(double posX, double posY){
this.posX = posX;
this.posY = posY;
}
public void accelerate(double accelerationX, double accelerationY){
speedX += accelerationX;
speedY += accelerationY;
}
public void update(){
posX += speedX;
posY += speedY;
speedX *= FRICTION;
speedY *= FRICTION;
}
public double getPosX(){
return posX;
}
public double getPosY(){
return posY;
}
}
请注意,您的对象有一个更新方法。需要定期在场景中的所有对象上调用此方法,以应用移动。在这种方法中你也可以处理碰撞检测,敌人可以做他们的AI逻辑。