我正在尝试创建我自己的基于原始 2D 图形的游戏引擎。游戏的核心组成部分是向敌人发射不同的弹丸。我需要先让这个组件工作,然后才能继续工作。
我现在所拥有的是沿着穿过起点 (x, y) 和目标点 (x1, x2) 的直线移动我的射弹。我使用线性函数 y = mx + b
。问题是我如何更新射弹的位置会导致速度不一致,具体取决于直线的斜率。 (更大的斜坡导致它移动得更快)。
这是我正在运行的游戏循环的核心结构:
private void executeGameLoop()
{
long nextFrameStart = System.nanoTime();
while(panel.getRunning())
{
do
{
panel.update();
nextFrameStart += FRAME_PERIOD;
} while(nextFrameStart < System.nanoTime());
long remaining = nextFrameStart - System.nanoTime();
panel.repaint();
if (remaining > 0)
{
try
{
Thread.sleep(remaining / 1000000);
}
catch(Throwable e)
{
System.out.println(e.getMessage());
}
}
}
}
这只是更新结构和图形的机制。每次调用 panel.update
时,弹丸都会在特定情况下更新其位置。以下是更新射弹的方法:
这会告诉射弹它有一个目标并设置有关该线的信息。
public void setHasTarget(boolean hasTargetIn)
{
if(hasTargetIn)
{
deltaX = getTargetX() - getX();
deltaY = getTargetY() - getY();
slope = deltaY / deltaX;
intercept = getY();
System.out.println("y = " + slope + "x + " + intercept); //line the projectile will follow
}
hasTarget = hasTargetIn;
}
此 next 方法将位置设置为该行的下一步。 (X由速度更新,y根据x更新)
public void setNext()
{
float temp = (slope) * (getX() + velocity) + intercept;
System.out.println("Slope: " + (slope) * (getX() + velocity));
System.out.println("Current: (" + getX() + ", " + getY() + ")");
System.out.println("Next: (" + (getX() + velocity) + ", " + (getY() + temp) + ")");
setX(getX() + velocity);
setY(temp);
}
最后一个方法调用 setNext()
并由主循环调用。
public void update()
{
if(hasTarget)
setNext();
}
正如我所说,根据我当前的代码,我运行的结果是一个弹丸,它在屏幕上以不一致的速度移动,具体速度取决于直线的斜率。我希望能够更改我的代码,以便弹丸在屏幕上以一致的速度在任何轨迹上移动。提前感谢您的帮助。
最佳答案
一般来说,处理定向运动的最佳方法是使用三角函数。 为此,您的射弹需要两件事:方向(以弧度为单位)和速度。
您需要的三个三角函数是 sin、cos 和 arctan
用于更新 X:setX(getX() + (speed * Math.cos(direction)));
用于更新 Y:setY(getY() + (speed * Math.sin(direction)));
用于计算方向:Math.atan(slope)
您应该将字段 direction
和 speed
添加到您的类中并将它们声明为 double 值。
public void setHasTarget(boolean hasTargetIn)
{
if (hasTargetIn)
{
deltaX = getTargetX() - getX();
deltaY = getTargetY() - getY();
direction = Math.atan(deltaY / deltaX); // Math.atan2(deltaY, deltaX) does the same thing but checks for deltaX being zero to prevent divide-by-zero exceptions
speed = 5.0;
}
hasTarget = hasTargetIn;
}
public void setNext()
{
setX(getX() + (speed * Math.cos(direction)));
setY(getY() + (speed * Math.sin(direction)));
}
关于java - 以一致的速度将物体从 A 点移动到 B 点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18732605/