如何间隔计算直线上的点

时间:2018-12-19 19:48:48

标签: java math points

我正在编写游戏,希望射弹每帧间隔从一个位置移动到下一个位置。

我一直在使用确定物体的斜率拦截方法,但是我接近了,但是我被困住了。

到目前为止,这是我的代码:

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

点击每个目标以其为目标

2 个答案:

答案 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和全局静态事物很多。例如,要在此代码中实现两个子弹飞行并不容易。

动画代码中也存在一些真正的错误。一些明显的错误是:

  1. xPerF的计算错误。您可以将欧几里得距离除以X坐标上的差值。

  2. 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);