【问题标题】:(C# Monogame) When adding objects to a list, keyboard input lags for a frame(C# Monogame) 将对象添加到列表时,键盘输入滞后一帧
【发布时间】:2017-05-03 12:01:52
【问题描述】:

基本上,我有一个使用gameTime.TotalGameTime.TotalSeconds 的敌人对象和定时事件列表。每 0.1 秒它会调用一个方法来检查是否有敌人生成,如果我们在 2.5 秒,我们会将一个敌人添加到敌人列表中。

现在发生的情况是键盘输入滞后一秒钟,例如,如果我连续向左移动,我的角色将在恢复移动之前停止一小段时间(我认为是 0.1 秒)。

我正在使用 gameTime 每毫秒检查一次键盘输入,但我也尝试过不使用它,但它仍然会发生。这也很奇怪,因为如果我像对待敌人一样按住 Z (通过将对象添加到列表中),我的代码每 0.5 秒创建一次子弹对象,但这不会使其滞后于输入

if (elapsedMs > oldElapsedMs + 0.001) //Millisecond update, for movement
        {
            oldElapsedMs = elapsedMs;

            //Keys to be held down.
            newState = Keyboard.GetState();
            Keys[] pressed_Key = Keyboard.GetState().GetPressedKeys();
            for (int i = 0; i < pressed_Key.Length; i++)
            {
                switch (pressed_Key[i])
                {
                    case Keys.Escape:
                        this.Exit();
                        break;
                    case Keys.Left:
                        player.tryMoveLeft();
                        break;
                    case Keys.Right:
                        player.tryMoveRight();
                        break;
                    case Keys.Up:
                        player.tryMoveUp();
                        break;
                    case Keys.Down:
                        player.tryMoveDown();
                        break;

                    default:
                        break;
                }
            }
        }

生成检查代码:

//0.1sec Update, spawning code
        if (elapsedSpawnTime > oldElapsedSpawnTime + 0.1)
        {
            oldElapsedSpawnTime = elapsedSpawnTime;
            spawnTimer += 1; //Every 0.1 sec add one to spawnTimer. The spawn timer int is what stage.Spawn() uses to check for spawns.
            stage.Spawn();


        }

我在舞台类中的生成方法:

public void Spawn()
    {
        switch (game.spawnTimer) //Each int is 0.1sec
        {
            //10 spawnTimer = 1 Second

            case 40:
            case 42:
            case 44:
            case 46:
                game.enemyList.Add(new Enemy(game.enemySprite, 500, 500, 1, true));
                break;

            default:
                break;
        }
    }

谢谢。如果您想帮助我但需要更多信息,可以添加我的 Skype @ emil1000123

【问题讨论】:

  • 请发布实际代码而不是截图。
  • 刚刚做了。对不起
  • 你的敌人类是引用类型还是值类型?避免在游戏循环中间的任何类上调用newblogs.msdn.microsoft.com/shawnhar/2007/07/02/…。摘录:不要在引用类型上调用 new。但是,可以使用新的值类型,例如 Matrix、Vector3 和 Color。每当您发现自己想要新的引用类型时,请改用对象池来重用现有实例。 creators.xna.com 上的粒子和音频 3D 样本使用了这种技术,并且 SwampThingTom 发布了关于可重复使用的池集合的博客。

标签: c# xna monogame


【解决方案1】:

截图中的代码说

( elapsedMs > oldElapsedMs + 0.001 )

变量名称表明这些值以毫秒为单位,那么您是否每 0.001 毫秒检查一次?

【讨论】:

  • 不,只是命名不当。 elapsedMs = gameTime.TotalGameTime.Seconds。基本上它是一个包含秒 + 毫秒的浮点数。它检查游戏时间是否比上一个 oldElapsedMs 多 1 毫秒
  • 您可以使用秒表来测量每帧的计算需要多长时间。这样你就可以知道,如果它的一段代码花费的时间比你预期的要长得多。顺便提一句。您是在每一帧上都使用 GC.Collect() 还是可以随时完成它的工作?
【解决方案2】:

看来问题出在毫秒更新上:

if (elapsedMs > oldElapsedMs + 0.001)

那么,如果它到达这个语句,但还没有超过 1 毫秒,会发生什么?

计算机以滴答声查看代码,这比毫秒快得多,因此它会完全忽略该语句,这可能会导致微小的延迟,具体取决于您 PC 的性能和文件大小(这将增加添加数组或列表)

现在,我不知道您在 TryMoveLeft() (等)方法中使用了什么。但我认为你最好我摆脱所说的 if 语句。并尝试重新设计玩家的行走方式。

如果我能看到 player.TryMoveRight 方法的样子,也许我可以提供一些提示。

【讨论】:

    猜你喜欢
    • 2020-06-22
    • 2019-03-20
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-01
    相关资源
    最近更新 更多