我正在进行一场乒乓球比赛。
当球击中任一桨时,它会触发声音效果。但问题是,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();
}
........
}
答案 0 :(得分: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;
}
}
}
答案 1 :(得分:1)
你可以有一个布尔变量来指示先前的碰撞状态。
如果myPreviousCollisionState =
false
,myCurrentCollisionState =true
- &gt; 播放声音,改变方向等...
在更新通话结束时,您可以设置
myPreviousCollisionState = myCurrentCollisionState
显然,在游戏开始时,myPreviousCollisionState = false
使用该代码,您的声音将仅在碰撞的第一帧播放。
希望这有帮助!