我正在编写游戏,希望射弹每帧间隔从一个位置移动到下一个位置。
我一直在使用确定物体的斜率拦截方法,但是我接近了,但是我被困住了。
到目前为止,这是我的代码:
animationFrame = refresh;
double x, y, xPerF; //Values for drawing
double m, b; //Value for slope and y-intercept
double x1, x2, y1, y2; //Values for the targets
x1 = getCenterX();
x2 = Canvas.target[shotTarget].getCenterX();
y1 = getCenterY();
y2 = Canvas.target[shotTarget].getCenterY();
xPerF = Point2D.distance(x1, y1, x2, y2)/animationSpeed;
//Calculate slope
if(x2>x1) m = (y2-y1)/(x2-x1);
else if(x2<x1) m = (y1-y2)/(x1-x2);
else m = 0;
//Calculate the y-intercept
b = m * x1 - y1;
if(b<0) b = -b + Canvas.myHeight;
else {
b -= Canvas.myHeight;
if(b<0) b = -b;
}
//Calculate the x value
if(x1>x2) x = x1 - (xPerF * animationFrame);
else if(x1<x2) x = x1 + (xPerF * animationFrame);
else x = x1;
//Calculate the y value
if(m!=0) y = (m * x + b) - Canvas.myHeight;
else {
if(y1>y2) y = y1 - (xPerF * animationFrame);
else y = y1 + (xPerF * animationFrame);
}
g.fillOval((int) x - 15, (int) y - 15, 30, 30);
//Debugging
System.out.println("Frame " + animationFrame + " of " + animationSpeed + " | " + y + " = " + m + " * " + x + " + " + b + " | at speed of " + xPerF);
我希望动画在目标位置结束,但是它总是过冲或正好对准目标。当目标在塔的上方很直时,主要是过冲,给出或获取几个x坐标。我已经将其确定为1 x-y象限平面,并且我认为现在存在的问题在于如何计算坡度。谢谢!
这是一个演示以下内容的小应用程序:https://drive.google.com/file/d/1fCTFJzulY1fcBUmdV6AXOd7Ol1g9B3lo/view?usp=sharing
点击每个目标以其为目标
答案 0 :(得分:0)
我相信您的方法从根本上来说是有缺陷的。容易产生舍入错误,这可能是过冲的根源。在并非您的应用程序不是唯一应用程序的现实世界中,也很难使它正常工作,因此可能对CPU的需求很高,并且可能会跳过某些帧,依此类推。更好的方法是使用时间而不是帧作为事件的主要驱动因素。您的主要方法drawScene
接受当前时间作为其参数之一。当任何动画开始时,您可以节省启动时间。然后,工作变得容易得多。例如,对于线性动画,它将是这样的:
double animationPart = (currentTime - animationStartTime) / totalAnimationDuration;
// fix rounding error
if (animationPart > 1.0)
animationPart = 1.0;
double xCur = xStart * (1.0 - animationPart) + xEnd * animationPart;
double yCur = yStart * (1.0 - animationPart) + yEnd * animationPart;
P.S。 “时间”不一定是实时的,如果它在某种程度上更有意义,则可能是其他“游戏时间”,但是恕我直言,这种方法更容易正确实施。
我会说总体代码质量很差。顾虑严重分离,magic numbers和全局静态事物很多。例如,要在此代码中实现两个子弹飞行并不容易。
动画代码中也存在一些真正的错误。一些明显的错误是:
xPerF
的计算错误。您可以将欧几里得距离除以X坐标上的差值。
y
的逻辑有缺陷。至少您应该添加m * (x - x1)
而不是m * x
。但这仍然无法涵盖垂直拍摄的情况(即X坐标完全不变的情况)。如果要采用这种方式,则应使用xPerF
和 yPerF
,并摆脱m
和相关的{ {1}}。
这可能会或可能不会解决动画问题(在列表中,您仍然可能会舍入错误)。我仍然会说,将您的if
更改为
shoot
然后使用
public void shootTarget(int target) {
shotTarget = target;
shotTime = animationFrame;
}
如上所述,是更好的方法。注意:这只是一个存根,因为在您的真实代码中,您出于某种原因会定期将double animationPart = ((double) (animationFrame - shotTime)) / animationSpeed;
分配给0
并因此分配给refresh
,这样就不会那么容易。
答案 1 :(得分:0)
我知道了。我没有使用斜率截距法计算坐标,而是简单地计算了间隔,我将不得不每帧增加y和x并根据动画的帧来增加它们。
double x, y, xPerF, yPerF; //Values for drawing
double x1, x2, y1, y2; //Values for the targets
x1 = getCenterX();
x2 = Canvas.target[shotTarget].getCenterX();
y1 = getCenterY();
y2 = Canvas.target[shotTarget].getCenterY();
xPerF = (Math.max(x1, x2) - Math.min(x1, x2))/animationSpeed;
yPerF = (Math.max(y1, y2) - Math.min(y1, y2))/animationSpeed;
if(x1>x2) x = x1 - xPerF * animationFrame;
else if(x1<x2) x = x1 + xPerF * animationFrame;
else x = x1;
if(y1>y2) y = y1 - yPerF * animationFrame;
else if(y1<y2) y = y1 + yPerF * animationFrame;
else y = y1;
g.fillOval((int) x - 15, (int) y - 15, 30, 30);