【问题标题】:Keep Rotating sprite from going off screen, but bounce back.防止旋转精灵离开屏幕,但会反弹回来。
【发布时间】:2013-07-22 09:37:49
【问题描述】:

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

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

【问题讨论】:

    标签: xna sprite game-physics


    【解决方案1】:

    让我们看看我是否理解正确。首先,你旋转你的精灵。之后,您将其加速前进。在这种情况下:

    // 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。这是一种摩擦,所以它不能这样做:如果加速度

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

    如果你对此有任何问题,或者你有什么不明白的地方(有时我的英语不是很好^^"),说出来=)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多