我使用一种技术通过向左/向右旋转然后向前加速来控制精灵。我有2个问题。 (由于多态性,它从不同的类中粘贴在一起的代码。如果它没有意义,请告诉我。运动效果很好,屏幕外检测也是如此。)
当玩家离开屏幕时,我会调用Bounce方法。我希望玩家不能离开屏幕,而是改变方向然后回去。这适用于顶部和底部,但左右边缘很少。它主要是一个奇怪的弹跳并离开屏幕。
- 醇>
我想修改加速算法,以便设置最大速度和加速度。 Atm TangentalVelocity同时做到了。
float TangentalVelocity = 8f;
//Called when up arrow is down
private void Accelerate()
{
Velocity.X = (float)Math.Cos(Rotation) * TangentalVelocity;
Velocity.Y = (float)Math.Sin(Rotation) * TangentalVelocity;
}
//Called once per update
private void Deccelerate()
{
Velocity.X = Velocity.X -= Friction * Velocity.X;
Velocity.Y = Velocity.Y -= Friction * Velocity.Y;
}
// Called when player hits screen edge
private void Bounce()
{
Rotation = Rotation * -1;
Velocity = Velocity * -1;
SoundManager.Vulture.Play();
}
//screen edge detection
public void CheckForOutOfScreen()
{
//Check if ABOVE screen
if (Position.Y - Origin.Y / 2 < GameEngine.Viewport.Y) { OnExitScreen(); }
else
//Check if BELOW screen
if (Position.Y + Origin.Y / 2 > GameEngine.Viewport.Height) { OnExitScreen(); }
else
//Check if RIGHT of screen
if (this.Position.X + Origin.X / 2 > GameEngine.Viewport.Width) { OnExitScreen(); }
else
//Check if LEFT of screen
if (this.Position.X - Origin.X / 2 < GameEngine.Viewport.X) { OnExitScreen(); }
else
{
if (OnScreen == false)
OnScreen = true;
}
}
virtual public void OnExitScreen()
{
OnScreen = false;
Bounce();
}
答案 0 :(得分:0)
让我们看看我是否理解正确。首先,你旋转你的精灵。在那之后,你加速前进。在那种情况下:
// Called when player hits screen edge
private void Bounce()
{
Rotation = Rotation * -1;
Velocity = Velocity * -1; //I THINK THIS IS THE PROBLEM
SoundManager.Vulture.Play();
}
让我们看看你的精灵在查找时没有旋转。在这种情况下,如果看起来正确,它旋转了90º,其速度为v =(x,0),x> 0。 0.当它离开屏幕时,其旋转变为-90º,速度v =( - x,0)。 但是你按下向上键并且调用了Accelerate方法,因此速度立即变为v =(x,0)。精灵再次离开屏幕,将其速度改为v =( -x,0)等产生奇怪的反弹。 我会尝试这样做:
private void Bounce()
{
Rotation = Rotation * -1;
SoundManager.Vulture.Play();
}
并检查它是否也起作用。我认为它会起作用。如果没有,请使用两种不同的Bounce方法,一种用于顶部/底部,另一种用于左/右。
你的第二个问题......这有点困难。在物理学中,事物达到最大速度,因为空气摩擦力(或其他力)速度依赖。因此,如果你提高你的速度,力也会增加......最后,那个力将会平衡另一个,速度将是恒定的。我认为模拟终端速度的最佳方法是使用这个概念。如果您想了解有关终端速度的更多信息,请查看维基百科:http://en.wikipedia.org/wiki/Terminal_velocity
private void Accelerate()
{
Acceleration.X = Math.abs(MotorForce - airFriction.X);
Acceleration.Y = Math.abs(MotorForce - airFriction.Y);
if (Acceleration.X < 0)
{
Acceleration.X = 0;
}
if (Acceleration.Y < 0)
{
Acceleration.Y = 0;
}
Velocity.X += (float)Math.Cos(Rotation) * Acceleration.X
Velocity.Y += (float)Math.Sin(Rotation) * Acceleration.Y
airFriction.X = Math.abs(airFrictionConstant * Velocity.X);
airFriction.Y = Math.abs(airFrictionConstant * Velocity.Y);
}
首先,我们使用“MotorForce”和空气摩擦来计算加速度。 MotorForce是我们用来移动精灵的力量。空气摩擦总是试图“消除”运动,所以总是积极的。我们最终得到绝对值,因为旋转给出了向量的方向。如果加速度低于0,则意味着空气摩擦力大于我们的MotorForce。这是摩擦,所以不能这样做:如果加速度&lt; 0,我们将其设为0-空气力达到我们的马达力并且速度变得恒定。 之后,使用加速度将增加速度。最后,我们更新空气摩擦值。
还有一件事:你可以在Deccelarate方法中更新airFriction的值,即使你不在那个方法中考虑它。
如果您对此有任何疑问,或者您不明白(有时我的英语不是很好^^“),请说=)