C# Xna向2d精灵添加重力

C# Xna向2d精灵添加重力,c#,xna,game-physics,C#,Xna,Game Physics,我正在尝试在我的第一个xna 2d游戏中模拟重力。我有以下几点 //Used for Jumping double elapsedAirTime = 0.0; double maxAirTime = 8.35; //End Jumping 所以我试图在elapsedAirTime

我正在尝试在我的第一个xna 2d游戏中模拟重力。我有以下几点

        //Used for Jumping
    double elapsedAirTime = 0.0;
    double maxAirTime = 8.35;
    //End Jumping
所以我试图在elapsedAirTime
if (newState.IsKeyDown(Keys.Space))
        {
            if(oldState.IsKeyUp(Keys.Space))
            {
                //if we are standing or jumping then change the velocity
                if (playerState == PlayerStates.Standing)
                {
                    playerState = PlayerStates.Jumping;
                    this.position.Y -= (float)(30.0 + ((1.2)*elapsedAirTime)*elapsedAirTime);
                }
            }
        }
        //if we are jumping give it some time
        if (playerState == PlayerStates.Jumping)
        {
            if ((elapsedAirTime < maxAirTime) && position.Y < 3)
            {
                this.position.Y -= (float)(30.0 + ((1.2) * elapsedAirTime)*elapsedAirTime);
                elapsedAirTime += gameTime.ElapsedGameTime.TotalSeconds;
            }
            //otherwise time to fall
            else
            {
                playerState = PlayerStates.Falling;
            }

        }

        //add gravity to falling objects
        if (playerState == PlayerStates.Falling || playerState == PlayerStates.Standing)
        {
            //if we are above the ground
            if (this.position.Y < windowBot - 110)
            {
                //chnage state to falling
                playerState = PlayerStates.Falling;
                this.position.Y += 3.0f + ((float)(gameTime.ElapsedGameTime.TotalSeconds));
            }
            else
            {
                playerState = PlayerStates.Standing;
                elapsedAirTime = 0.0f;
            }
        }
if(newState.IsKeyDown(Keys.Space))
{
if(oldState.IsKeyUp(Keys.Space))
{
//如果我们站着或跳跃,那么改变速度
if(playerState==PlayerStates.Standing)
{
玩家状态=玩家状态。跳跃;
此.position.Y-=(浮点)(30.0+((1.2)*elapsedAirTime)*elapsedAirTime);
}
}
}
//如果我们要跳,给点时间
if(playerState==PlayerStates.Jumping)
{
if((elapsedAirTime

非常感谢您的帮助,谢谢

这条线路似乎有故障:

this.position.Y -= (float)(30.0 + ((1.2) * elapsedAirTime)*elapsedAirTime);
我想你会发现,这会比你想象的更快地更新精灵的位置,精灵将在10次更新中向上移动330像素(假设
Game.isfixedtimestop==true
),即十分之一秒的实时更新

很可能这只是更新得太快了,以至于在
&&position.Y<3
条件生效并改变playerState之前,您不会看到它上升

看起来你想说的是,只要有空间,以每秒x像素的速度跳8.5秒

您需要将计算更改为
this.position.y-=(float)(30*gameTime.ElapsedGameTime.TotalSeconds)
,这将为跳跃动作提供非常线性的移动,但这将意味着精灵以每秒30像素的速度跳跃


如果
Game.IsFixedTimeStep==true
-这是默认值-更新每秒调用60次,因此每次更新gameTime.ElapsedGameTime.TotalSeconds大约为0.1。如果某个事件导致更新跳过(例如渲染问题),则更新将被延迟,gameTime.ElapsedGameTime.TotalSeconds可能为0.3(跳过了2次更新),但公式仍然计算出正确的跳转率

为了给你的精灵一种重力的感觉,你应该在你的精灵类中增加速度和加速度。然后,为精灵创建一个更新方法,并将加速度添加到每次更新的速度中,将速度添加到每次更新的位置中。位置不应基于经过的空气时间量。您可以将加速度设置为恒定的重力值,然后在每次跳跃时添加精灵的速度。这将创建一个流动的抛物线跳跃,看起来很不错。如果你想加入计时,你可以将游戏时间传递到精灵的更新方法中,并将其用作速度的修改器。以下是更新方法的示例:


无效更新(游戏时间gt)
{
int updateTime=gt.elapsedgametimes.totalmillizes-oldgt.elapsedgametimes.totalmillizes;
浮动时间刻度=更新时间/平均帧时间;
this.velocity+=this.加速度*时间刻度;
这个位置+=这个速度;
oldgt=gt;
}

如果你使用计时,这个方法有点复杂。您必须跟踪更新花费的时间,然后将其除以更新或帧应花费的平均时间,以获得您应调整速度的时间。无需计时,方法非常简单:


无效更新()
{
这个速度+=这个加速度;
这个位置+=这个速度;
}


我建议使用更简单的方法,直到您确切地了解计时是如何工作的以及为什么需要实现它

为什么要计算时间刻度并存储旧的游戏时间?如果每次游戏循环都调用此更新函数(应该如此),则gt.ElapsedGameTime已经为您完成了所有繁重的工作。使用时间刻度的原因是a)如果您想更改默认帧速率,或b)如果您的计算机速度太慢,无法跟上XNA尝试的默认60 UPS/FPS。在任何一种情况下,如果你落后于目标更新率,你的游戏将看起来像是没有时间刻度代码落后。 void Update(GameTime gt) { int updateTime = gt.ElapsedGameTime.TotalMilliseconds - oldgt.ElapsedGameTime.TotalMilliseconds; float timeScalar = updateTime / AVG_FRAME_TIME; this.velocity += this.acceleration * timeScalar; this.position += this.velocity; oldgt = gt; } void Update() { this.velocity += this.acceleration; this.position += this.velocity; }