0

ポンゲームを作っています。

ボールがいずれかのパドルに当たると、効果音が鳴ります。ただし、問題はXNAが60fpsを更新することです。そのため、最初の衝突時に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();
        }
                     ........
              }
4

2 に答える 2

1

解決策は次のようになります。このコードはテストも機能もしていません。アイデアのためだけにあります。基本的に、サウンドが再び再生されるまでしばらく(ms)待機するタイマーがあります。サウンドを再度再生するには、衝突検出要求が満たされている必要があります。シンプルなディレイタイマーです。

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;
        }
    }
}
于 2012-09-26T11:05:38.950 に答える
1

以前の衝突状態を示すブール変数を持つことができます。

myPreviousCollisionState = false、およびmyCurrentCollisionState = true->サウンドの再生、方向の変更などの場合...

更新呼び出しの最後に、設定できます

myPreviousCollisionState = myCurrentCollisionState

明らかに、ゲームの開始時に、myPreviousCollisionState = false

そのコードを使用すると、サウンドは衝突の最初のフレームでのみ再生されます。

お役に立てれば!

于 2012-09-26T15:26:52.007 に答える