保持旋转精灵不会离开屏幕,但会反弹。

时间:2013-07-22 09:37:50

标签: xna sprite game-physics

我使用一种技术通过向左/向右旋转然后向前加速来控制精灵。我有2个问题。 (由于多态性,它从不同的类中粘贴在一起的代码。如果它没有意义,请告诉我。运动效果很好,屏幕外检测也是如此。)

  
      
  1. 当玩家离开屏幕时,我会调用Bounce方法。我希望玩家不能离开屏幕,而是改变方向然后回去。这适用于顶部和底部,但左右边缘很少。它主要是一个奇怪的弹跳并离开屏幕。

  2.   
  3. 我想修改加速算法,以便设置最大速度和加速度。 Atm TangentalVelocity同时做到了。

  4.   
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();
    }

1 个答案:

答案 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的值,即使你不在那个方法中考虑它。

如果您对此有任何疑问,或者您不明白(有时我的英语不是很好^^“),请说=)