2011-12-27 108 views
0

我正在開發AIR(as3)中的手機遊戲。我爲這款遊戲創建了一些機器人,最初只是漫遊。但是當獎金進入舞臺時,他們必須轉向獎金。使用餘弦定律計算角度,給出2分並計算1分

檢測到一個新的獎金和移動的機器人工作正常,但是當新的獎金進入舞臺時操作出現問題。

基本上,這是它是如何工作(或我嘗試,使其工作):

我的機器人移動與他作爲一個參數一起旋轉。 (正常工作)

private function moveToNextLocation():void 
{ 
    var angle:Number = _rotation * 0.0174532925; // 1 degree = 0.0174532925 radians 
    var speedX:Number = Math.sin(angle) * _speed; 
    var speedY:Number = -Math.cos(angle) * _speed; 

    if (_turnLeft && !_moveToBonus){ 
     _rotation -= _rotationStep * (_speed/_maxSpeed); 
    } 
    else if (_turnRight && !_moveToBonus){ 
     _rotation += _rotationStep * (_speed/_maxSpeed); 
    } 

    this.x += speedX; this.y += speedY; 
} 

所以,要做知道,如果一個新的獎金出現我抓住一個事件第一:

protected function onNewBonusAppeared(event:BonusEvent):void 
{ 
    trace("new bonus appeared!"); 
    _moveToBonus = true; 
    _rotation = getRotation(new Point(event.bonus.x, event.bonus.y)); 
    trace("Heading to " + event.bonus.type + " with new rotation: " + _rotation); 
} 

我的機器人現在是在A點和通常會走到B點(normalNextLocation )。 然後,新的獎金出現在C點(nextLocation)。 我想解決這個問題的餘弦定律,因爲我需要A的角度來知道我的機器人的新旋轉。 這是我試圖計算此:

// calculate new rotation 
private function getRotation(nextLocation:Point):Number 
{ 
    //sources: 
    //http://www.teacherschoice.com.au/maths_library/trigonometry/triangle_given_3_points.htm 
    //http://en.wikipedia.org/wiki/Law_of_cosines 
    //http://stackoverflow.com/questions/1211212/how-to-calculate-an-angle-from-three-points 

    //Calculate current angle and corners 
    var angle:Number = _rotation * 0.0174532925; 
    var currentLocation:Point = new Point(this.x, this.y); 
    var normalNextLocation:Point = new Point(Math.sin(angle) * _speed, -Math.cos(angle) * _speed); 

    //Calculate lengths of the 3 sides of the triangle 
    var lengthA:Number = calculateLength(normalNextLocation, nextLocation); 
    var lengthB:Number = calculateLength(currentLocation, nextLocation); 
    var lengthC:Number = calculateLength(currentLocation, normalNextLocation); 

    //Calculate the difference in rotation 
    //-------------THIS IS WHERE IT GOES WRONG----------- 
    var deltaRotation:Number = calculateAndInverseCosineRule(lengthA, lengthB, lengthC); 

    //positive or negative rotation difference 
    if (normalNextLocation.y < nextLocation.y) 
     return _rotation - deltaRotation; 
    else 
     return _rotation + deltaRotation; 
} 
private function calculateLength(a:Point, b:Point):Number 
{ 
    //SQRT((x2 - x1)² + (y2 - y1)²) 
    return Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2)); 
} 
private function calculateAndInverseCosineRule(lengthA:Number, lengthB:Number, lengthC:Number):Number 
{ 
    //a² = b² + c² - 2*b*c*cos(alpha) 
    //cos(alpha) = (b² + c ² - a²)/(2 * b * c) 
    //alpha = cos^-1(cos(alpha)) 
    var cos:Number = (Math.pow(lengthB, 2) + Math.pow(lengthC, 2) - Math.pow(lengthA, 2)) 
         /(2 * lengthB * lengthC); 
    trace("cos: ", cos); //returns NAN at some point... don't know why 
    return Math.acos(cos); 
} 

我搜索關於這個問題相當長的一段時間了,但無法找到答案...是否有人看到我在做什麼錯? - [修正]

+0

你可能會發佈一個正在發生的事情的演示,或者說明期望的行爲是什麼?我不確定我瞭解你想要做什麼。我似乎很奇怪爲什麼如果bot不再朝向它,爲什麼需要使用「normalNextLocation」。如果你只需要兩點之間的角度,使用'Math.atan2(target.y-bot.y,target.x-bot.x)' – 2011-12-27 23:37:15

+0

我需要2條線之間的角度,我有2個點,估計第3點 – 2011-12-28 02:14:35

+0

由於我沒有超過10代表,所以你去:http://imgur.com/Bkl27 – 2011-12-28 02:25:40

回答

1

您在這裏有一個錯字:

var cos:Number = (Math.pow(lengthB, 2) + Math.pow(lengthC, 2) - Math.pow(lengthC, 2)) 

數量減去應Math.pow(lengthA, 2)。就像你計算(模浮點不準確)lengthB^2/(2*lengthB*lengthC)。這將產生一個NaN如果lengthB == 0,我懷疑是發生了什麼。這意味着nextLocation是相同的或至少非常接近currentLocation

另一方面,不應該normalNextLocationcurrentLocation + timeStep*velocity?據我所知,您將它設置爲velocity

+0

謝謝,NaN解決了!將看看normalNextLocation thingie,因爲它還不能正常工作......感謝您注意! :-) – 2011-12-28 02:13:27