2009-06-18 35 views
1

我想根據球擊中槳的位置以一定角度偏轉球。現在,我只改變y座標,這會導致無意義的偏轉。它將在角度上獨立於衝擊槳葉的位置。我想要更有趣的東西。不需要考慮速度,動量,質量和其他因素。根據槳的衝擊位置調整角度。我讀過這Not a number error (NAN) doing collision detection in an iphone app,但它看起來過於複雜,我正在尋找。有沒有更簡單的方法來計算偏轉?當球擊中槳時改變角度

對象是兩個UIImageViews。

回答

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.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之間,以使球不拍客到星星什麼的。

+0

非常好!這很容易啓動和運行。我不存儲impactX值。我只是檢查球是否在槳的矩形和反向ball.center.y。我嘗試使用ball.center.x來獲得impactX,但有時球會碰到邊緣並直線跳動。你如何計算impactX? – 4thSpace 2009-06-18 17:36:04

0

你不一定想現實,你想要的樂趣。這些並不總是一樣的。如果你想要逼真,你不能拋出速度,動量,質量等等。在一場普通的乒乓球比賽中,它撞擊槳的點並不重要,它們不是一個像網球拍那樣的甜蜜點。

開發一個數學函數,它將返回一個輸出矢量,或一個速度和一個單位矢量,表示球的輸出角度和速度,輸入角度,速度,槳上的衝擊點以及速度槳。

我們預計輸出角度= -1 *輸入角度。輸出速度也應該是-1 *輸入速度。所以如果你想混合起來,調整一下。您可以增加輸出角度,與槳葉中心距離成比例。您也可以增加角度或速度與槳的速度成正比時。

有很多方法可以做到這一點,所以我不能真正告訴你到底使用什麼函數,你將不得不通過測試和演奏來解決這個問題。如果您仍然需要更多信息,請在您的問題中添加更多細節。

+0

謝謝。我已經編輯了這個問題,以反映「有趣」而不是現實,你是對的。但是仍然希望得到一些關於設置代碼的建議。正如OP中所提到的那樣,我想在執行計算時遵循更簡單的路徑。 – 4thSpace 2009-06-18 15:53:52

0

下面的代碼(C++,但很容易轉換爲ObjC)需要一個傳入的2D矢量,並基於表面法線(pong bat的表面)反射它。

您可以隨機添加一個隨機的「趣味因子」,您可以將它應用於「標量」 - 改變速度或改變曲面法線以改變反射角度。

我在我的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); 
}