Xna 向 2d 精灵添加重力

发布于 2024-10-16 06:51:44 字数 1917 浏览 9 评论 0原文

我正在尝试在我的第一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ㄖ落Θ余辉 2024-10-23 06:51:44

为了让你的精灵有重力感,你应该为你的精灵类添加速度和加速度。然后,为 Sprite 创建一个 Update 方法,并在每次更新时将加速度添加到速度中,并将速度添加到每次更新的位置中。位置不应基于飞行时间的长短。您可以将加速度设置为恒定的重力值,然后在每次跳跃时添加到精灵的速度。这将创建一个看起来不错的流畅抛物线跳跃。如果要包含计时,可以将 GameTime 传递到 Sprite 的 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;
}

我建议使用更简单的方法,直到您准确理解计时的工作原理以及为什么需要实现它。

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:

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

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:

void Update()
{
    this.velocity += this.acceleration;
    this.position += this.velocity;
}

I would suggest using the simpler method until you understand exactly how timing works and why you need to implement it.

才能让你更想念 2024-10-23 06:51:44

看起来这条线有问题:

this.position.Y -= (float)(30.0 + ((1.2) * elapsedAirTime)*elapsedAirTime);

我想你会发现这更新精灵位置的速度比你想象的要快,精灵将在 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:

this.position.Y -= (float)(30.0 + ((1.2) * elapsedAirTime)*elapsedAirTime);

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 realtime

It 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文