1

我想根据球击中桨的位置以一定角度偏转球。现在,我只改变 y 坐标,这会导致无意义的偏转。它会倾斜,但与桨的撞击位置无关。我想要更有趣的东西。速度、动量、质量和其他因素不需要考虑。只是角度取决于桨的撞击位置。我已经阅读过在 iphone 应用程序中进行碰撞检测的 Not a number error (NAN),但对于我正在寻找的内容来说似乎过于复杂。有没有更简单的方法来计算偏转?

对象是两个 UIImageViews。

4

3 回答 3

4

好吧,没有什么现实的,但你可以做一些事情,使出站角度仅取决于它击中桨的位置。

我从来没有做过任何 iPhone 或客观的 C 编码,所以我只会用伪/C 代码写一些东西。

首先我会计算速度,即速度向量的长度,或者:

double speed = sqrt(velX * velX + velY * velY); // trigonometry, a^2 + o^2 = h^2

然后我们想根据我们击球的位置来计算新的角度。我将假设您将 X 碰撞存储在 ImpactX 中,并将桨的长度存储在 paddleLength 中。这样我们就可以计算出外角。首先让我们弄清楚如何计算范围,以便我们得到一个介于 -1 和 1 之间的值。

double proportionOfPaddle = impactX / (double) paddleLength; // between 0 and 1
double impactRange = proportionOfPaddle * 2 - 1; // adjust to -1 and 1

假设我们不想将球完全偏向一边,或 90 度,因为这很难恢复。由于我将使用 ImpactRange 作为新的 velY,因此我将其缩小到 -0.9 到 0.9。

impactRange = impactRange * 0.9;

现在我们需要计算 velX 以使速度保持不变。

double newVelX = impactRange;
double newVelY = sqrt(speed * speed - newVelX * newVelX); // trigonometry again

现在你返回 newVelX 和 newVelY 并且你有一个影响和速度依赖的反弹。

祝你好运!

(很可能是这里的错误,我可能已经颠倒了 X 或 Y,但我希望你能得到大致的想法)。

编辑:添加一些关于获得 ImpactX 的想法。

假设你有 ball.center.x 和 paddle.center.x (不知道你怎么称呼它,但让我们假设 paddle.center.x 会给我们桨的中心)我们应该能够从中计算影响范围。

我们还需要球半径(我假设 ball.width 作为直径)和桨大小(paddle.width?)。

int ballPaddleDiff = paddle.center.x - ball.center.x;
int totalRange = paddle.width + ball.width;

ballPaddleDiff 的最小值是当球刚刚接触到球拍的一侧时。那 ballPaddleDiff 将是 paddle.width/2 + ball.width/2。因此,新的 ImpactRange 将是

double impactRange = ballPaddleDiff / (double) totalRange / 2;

您可能应该检查impactRange 以便它实际上在-1 和1 之间,这样球就不会射向星星或其他东西。

于 2009-06-18T15:56:40.587 回答
0

你不一定想要现实,你想要乐趣。这些并不总是相同的。如果你想要逼真,你不能丢掉速度、动量、质量等。在正常的乒乓球比赛中,击球点并不重要,没有网球拍上的甜蜜点.

开发一个数学函数,该函数将返回一个输出向量,或一个速度和一个单位向量,表示球的输出角度和速度,给出输入角度、速度、球拍上的撞击点和球拍的速度。

我们已经期望输出角度 = -1 * 输入角度。输出速度也应为 -1 * 输入速度。因此,如果您想混合使用,请调整它们。您可以增加与桨中心距离成比例的输出角度。您还可以增加与桨击中时的速度成比例的角度或速度。

有很多方法可以做到这一点,所以我不能准确地告诉你你会使用什么功能,你必须通过测试和玩来弄清楚。如果您仍需要更多信息,请为您的问题添加更多细节。

于 2009-06-18T15:43:06.617 回答
0

以下代码(C++,但很容易转换为 ObjC),采用传入的 2D 向量并根据表面法线(乒乓球的面)反射它。

您可以通过随机化一个偏移量来添加一些随机的“有趣因素”,该偏移量可以应用于“标量”——以改变速度,或应用于表面法线,以改变反射角。

我在我的 iPhone 项目中使用它,它工作正常 :)

void vec2ReflectScalar(vec2& vResult, const vec2& v1, const vec2& normal, float scalar)
{
    vec2  _2ndotvn;
    float dotVal = vec2DotProduct(v1, normal); 

    vec2Scale(_2ndotvn, normal, scalar * 2.f * dotVal);
    vec2Subtract(vResult, v1, _2ndotvn); 
}

void vec2Reflect(vec2& vResult, const vec2& v1, const vec2& normal)
{
    vec2ReflectScalar(vResult, v1, normal, 1.f);
}
于 2009-06-19T09:44:57.860 回答