0

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

  1. 当玩家离开屏幕时,我调用 Bounce 方法。我希望玩家不能离开屏幕,而是改变方向并返回。这适用于顶部和底部,但很少见左右边缘。大多数情况下,它会发生奇怪的反弹并离开屏幕。

  2. 我想修改加速算法,以便我可以设置最大速度和加速速度。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();
    }
4

1 回答 1

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。当它离开屏幕时,它的旋转变为 -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。这是一种摩擦,所以它不能这样做:如果加速度 < 0,我们将其设为 0 - 空气力达到我们的马达力并且速度变得恒定。之后,速度将使用加速度增加。最后,我们更新空气摩擦值。

还有一件事:您也可以在 Deccelarate 方法中更新 airFriction 的值,即使您在该方法中不考虑它。

如果你对此有任何问题,或者你不明白某些东西(有时我的英语不是很好^^“),说出来=)

于 2013-08-01T13:16:51.660 回答