Xna 向 2d 精灵添加重力
我正在尝试在我的第一个 xna 2d 游戏中模拟重力。我有以下内容
//Used for Jumping
double elapsedAirTime = 0.0;
double maxAirTime = 8.35;
//End Jumping
所以我试图在 elapsedAirTime < 的情况下将精灵向上移动一定的量。最长通话时间 然而,存在一些问题,我的代码似乎只在这段时间内将精灵向上移动一次,而不是多次。这是我的“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;
}
}
非常感谢任何帮助,请并谢谢!
I am trying to simulate gravity in my first xna 2d game. I have the following
//Used for Jumping
double elapsedAirTime = 0.0;
double maxAirTime = 8.35;
//End Jumping
So I am trying to move the sprite up by a certain amount while the elapsedAirTime < maxAirTime
However, there is some issue where my code only seems to move the sprite up once and not multiple times during this segment of time. here is the code in my "player.cs" class, or the update method of the class.
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;
}
}
Any help is much appreciated, please and thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了让你的精灵有重力感,你应该为你的精灵类添加速度和加速度。然后,为 Sprite 创建一个 Update 方法,并在每次更新时将加速度添加到速度中,并将速度添加到每次更新的位置中。位置不应基于飞行时间的长短。您可以将加速度设置为恒定的重力值,然后在每次跳跃时添加到精灵的速度。这将创建一个看起来不错的流畅抛物线跳跃。如果要包含计时,可以将 GameTime 传递到 Sprite 的 Update 方法中,并将其用作速度的修改器。以下是更新方法示例:
如果使用计时,这个方法有点复杂。您必须跟踪更新花费的时间,然后将其除以更新或帧应该花费的平均时间,以获得您应该调整速度的量。不用计时,方法很简单:
我建议使用更简单的方法,直到您准确理解计时的工作原理以及为什么需要实现它。
To give your sprite the feel of gravity, you should add velocity and acceleration to your Sprite class. Then, create an Update method for the Sprite, and have acceleration be added to your velocity every update, and velocity added to position every update. Position should not be based on the amount of elapsed air time. You can set the acceleration to a constant gravitational value, and then add to the velocity of the Sprite whenever you jump. This will create a flowing parabolic jump that looks nice. If you want to include timing, you can pass the GameTime into the Sprite's Update method, and use it as a modifier on the velocity. Here is an example Update method:
If you use timing, this method is a little complicated. You have to keep track of how much time the update took, then divide it by the average amount of time an update or frame should take to get the amount you should adjust your velocity by. Without timing, the method is very simple:
I would suggest using the simpler method until you understand exactly how timing works and why you need to implement it.
看起来这条线有问题:
我想你会发现这更新精灵位置的速度比你想象的要快,精灵将在 10 次更新中在屏幕上移动 330 像素(假设 Game.IsFixedTimeStep == true) 是实时的十分之一秒
这很可能只是更新得如此之快,以至于您没有看到它在
&& 之前上升的变化。位置。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 个更新),但公式仍然计算出正确的跳跃率。
It looks like this line is at fault:
I think you will find that this updates the sprites position quicker than you imagine, the sprite will move 330 pixels up the screen in 10 updates (assuming
Game.IsFixedTimeStep == true
) that is 1 tenth of a second realtimeIt is likely that this is just updating so quickly that you don't get a change to see it rise before the
&& position.Y < 3
condition kicks in and changes the playerState.It looks like you are trying to say - jump at a rate of x pixels per second for upto 8.5 seconds so long as space is held.
What you need for that is to change the calculation to
this.position.y -= (float) (30 * gameTime.ElapsedGameTime.TotalSeconds)
, this will give a very liner movement to the jump action but it will mean that the sprite jumps at exactly 30 pixels per second.If
Game.IsFixedTimeStep == true
- which is the default - the update gets called 60 times per second so gameTime.ElapsedGameTime.TotalSeconds is going to be about 0.1 every update. If something happens to cause an update to skip (rendering issues for example) then update will get delayed and gameTime.ElapsedGameTime.TotalSeconds may be 0.3 (the 2 updates skipped) but the formular still works out the correct jump rate.