2012-09-26 33 views
0

我在做一個pong遊戲。停止發生不止一次的更新,連續發生

當球撞擊任何一個槳時,它會觸發聲音效果。然而,問題在於XNA更新了60 fps。因此,有時我會聽到剛開始碰撞時剛剛開始熄滅的sfx觸發器的微弱聲音。

我想使得SFX觸發一次熄滅,使它,然後不再次發生,直到: A)球得分 或 B)球與相對的球棒碰撞。

我可以採取什麼措施來做這樣的事情?

這裏是我的觸發目前的樣子,在我的球類:

 /// <summary> 
    /// Draws a rectangle where the ball and bat collide. Also triggers the SFX for when they collide 
    /// </summary> 
    private void BatCollisionRectLeft() 
    { 
     // For the left bat 
     if (ballRect.Intersects(leftBat.batRect)) 
     { 
      rectangle3 = Rectangle.Intersect(ballRect, leftBat.batRect); 
      hasHitLeftBat = true; 
      lastHitLeftBat = true; 
      lasthitRightBat = false; 
      AudioManager.Instance.PlaySoundEffect("hit2"); 
      Speed += .2f;   // Gradually increases the ball's speed each time it connects with the bat 
     } 
    } 

這個函數,然後我的球的更新功能,這是由XNA的主要的遊戲類調用內調用。

 /// <summary> 
    /// Updates position of the ball. Used in Update() for GameplayScreen. 
    /// </summary> 
    public void UpdatePosition(GameTime gameTime) 
    { 
       ....... 

    // As long as the ball is to the right of the back, check for an update 
     if (ballPosition.X > leftBat.BatPosition.X) 
     { 
      // When the ball and bat collide, draw the rectangle where they intersect 
      BatCollisionRectLeft(); 
     } 

     // As long as the ball is to the left of the back, check for an update 
     if (ballPosition.X < rightBat.BatPosition.X) 

     { // When the ball and bat collide, draw the rectangle where they intersect 
      BatCollisionRectRight(); 
     } 
        ........ 
       } 

回答

1

您可以有一個布爾變量指示以前的碰撞狀態。

如果myPreviousCollisionState = false,並且myCurrentCollisionState = true - > 播放聲音,改變方向,等等

在您的更新通話結束時,您可以設置

myPreviousCollisionState = myCurrentCollisionState

顯然,在比賽開始時,myPreviousCollisionState = false

使用該代碼,您的聲音將僅在碰撞的第一幀中播放。

希望這會有所幫助!

+0

謝謝!清晰簡潔。今晚我會試一試,讓你知道它是如何發生的,並且一旦我開始行動就批准作爲答案! –

1

解決方案看起來像這樣。這段代碼沒有經過測試也沒有功能,只是在這裏爲了這個想法。低音上你有一個計時器,等待一段時間(毫秒),然後再播放聲音;要再次播放聲音,您的碰撞檢測請求必須符合。這是簡單的延遲計時器。

float timer = 0, timerInterval = 100; 
bool canDoSoundEffect = true; 
... 
void Update(GameTime gt) { 
    float delta = (float)gt.ElapsedTime.TotalMilliseconds; 

    // Check if we can play soundeffect again 
    if (canDoSoundEffect) { 
     // Play soundeffect if collided and set flag to false 
     if (ballRect.Intersects(leftBat.batRect)) { 

      ... Collision logic here... 

      AudioManager.Instance.PlaySoundEffect("hit2"); 
      canDoSoundEffect = false; 
     } 
    } 
    // So we can't play soundeffect - it means that not enough time has passed 
    // from last play so we need to increase timer and when enough time passes, 
    // we set flag to true and reset timer 
    else { 
     timer += delta; 
     if (timer >= timerInterval) { 
      timer -= timerInterval; 
      canDoSoundEffect = true; 
     } 
    } 
} 
+0

我喜歡你這樣做的方式。我今晚也會試試這個,並且讓你知道它是如何工作的。 再次感謝您! –