我想以某个角度偏转球,这取决于击球的位置。现在,我只是改变y坐标,导致无趣的偏转。它将与桨叶的冲击位置成角度但独立。我想要更有趣的东西。不需要考虑速度,动量,质量和其他因素。只是角度取决于桨的冲击位置。我已经阅读了这个Not a number error (NAN) doing collision detection in an iphone app但是对于我正在寻找的东西来说似乎过于复杂。有没有更简单的方法来计算偏差?
对象是两个UIImageViews。
答案 0 :(得分:4)
嗯,没有什么是现实的,但是你可以做一些事情,这样出境角度只取决于它击中桨的位置。
我从未做过任何iPhone或目标C编码所以我只会用伪/ C代码写一些东西。
首先我计算速度,即速度矢量的长度,或者:
double speed = sqrt(velX * velX + velY * velY); // trigonometry, a^2 + o^2 = h^2
然后我们想根据击中球拍的位置计算新角度。我将假设您在impactX中存储X碰撞,并在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 :(得分:0)
你不一定要现实,你想要有趣。那些并不总是一样的。如果你想要逼真,你就不能甩掉速度,动量,质量等等。在正常的乒乓球比赛中,击中球拍的地方并不重要,这不是网球拍上的甜蜜点。
开发一个数学函数,它将返回一个输出矢量,或一个速度和一个单位矢量,表示球的输出角度和速度,输入角度,速度,桨叶上的撞击点和桨叶的速度。
我们预计输出角度= -1 *输入角度。输出速度也预期为-1 *输入速度。因此,如果你想混淆它,调整它们。您可以增加与桨叶中心距离成比例的输出角度。您还可以在撞击时增加与桨叶速度成比例的角度或速度。
你有很多方法可以做到这一点,所以我无法确切地告诉你你将使用什么功能,你将不得不通过测试和播放来解决这个问题。如果您仍需要更多信息,请在问题中添加更多细节。
答案 2 :(得分: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);
}