我想根据球击中桨的位置以一定角度偏转球。现在,我只改变 y 坐标,这会导致无意义的偏转。它会倾斜,但与桨的撞击位置无关。我想要更有趣的东西。速度、动量、质量和其他因素不需要考虑。只是角度取决于桨的撞击位置。我已经阅读过在 iphone 应用程序中进行碰撞检测的 Not a number error (NAN),但对于我正在寻找的内容来说似乎过于复杂。有没有更简单的方法来计算偏转?
对象是两个 UIImageViews。
我想根据球击中桨的位置以一定角度偏转球。现在,我只改变 y 坐标,这会导致无意义的偏转。它会倾斜,但与桨的撞击位置无关。我想要更有趣的东西。速度、动量、质量和其他因素不需要考虑。只是角度取决于桨的撞击位置。我已经阅读过在 iphone 应用程序中进行碰撞检测的 Not a number error (NAN),但对于我正在寻找的内容来说似乎过于复杂。有没有更简单的方法来计算偏转?
对象是两个 UIImageViews。
好吧,没有什么现实的,但你可以做一些事情,使出站角度仅取决于它击中桨的位置。
我从来没有做过任何 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 之间,这样球就不会射向星星或其他东西。
你不一定想要现实,你想要乐趣。这些并不总是相同的。如果你想要逼真,你不能丢掉速度、动量、质量等。在正常的乒乓球比赛中,击球点并不重要,没有网球拍上的甜蜜点.
开发一个数学函数,该函数将返回一个输出向量,或一个速度和一个单位向量,表示球的输出角度和速度,给出输入角度、速度、球拍上的撞击点和球拍的速度。
我们已经期望输出角度 = -1 * 输入角度。输出速度也应为 -1 * 输入速度。因此,如果您想混合使用,请调整它们。您可以增加与桨中心距离成比例的输出角度。您还可以增加与桨击中时的速度成比例的角度或速度。
有很多方法可以做到这一点,所以我不能准确地告诉你你会使用什么功能,你必须通过测试和玩来弄清楚。如果您仍需要更多信息,请为您的问题添加更多细节。
以下代码(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);
}