我正试图在我的第一个xna 2d游戏中模拟引力。我有以下
//Used for Jumping
double elapsedAirTime = 0.0;
double maxAirTime = 8.35;
//End Jumping
所以我试图将精灵向上移动一定量,而elapsedAirTime< maxAirTime 但是,有一些问题,我的代码似乎只在这段时间内将精灵向上移动一次而不是多次。这是我的“player.cs”类中的代码,或类的更新方法。
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;
}
}
非常感谢任何帮助,谢谢!
答案 0 :(得分:11)
为了让您的精灵感受到引力,您应该为Sprite类添加速度和加速度。然后,为Sprite创建一个Update方法,并在每次更新时将加速度添加到您的力度中,并将速度添加到每次更新的位置。位置不应基于经过的空气时间量。您可以将加速度设置为恒定的重力值,然后在跳跃时添加到Sprite的速度。这将创造一个看起来不错的流动抛物线跳跃。如果要包括计时,可以将GameTime传递给Sprite的Update方法,并将其用作速度的修饰符。这是一个示例Update方法:
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;
}
我建议使用更简单的方法,直到您准确理解时序的工作原理以及为什么需要实现它。
答案 1 :(得分:2)
看起来这条线路有问题:
this.position.Y -= (float)(30.0 + ((1.2) * elapsedAirTime)*elapsedAirTime);
我认为你会发现这会比你想象的更快地更新精灵位置,精灵将在10次更新中假设移动330像素(假设为Game.IsFixedTimeStep == true
),即十分之一秒实时
这可能只是更新得如此之快,以至于在&& position.Y < 3
条件启动并更改播放器状态之前,您无法看到它上升。
看起来你试图说 - 只要保持空间,就可以以每秒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个更新),但公式仍然可以计算出正确的跳跃率。