更新:我上传了一个显示口吃的视频:http://intninety.co.uk/xnastutter.mp4如果你没有在1920x1080观看它,你可能需要仔细查看视频,但你会看到那里我每隔2秒左右移动一次是一个相当明显的口吃,我建议在Windows Media Player而不是你的网络浏览器中查看它,以确保视频本身没有波动,从而阻止你看到实际的口吃
我最近刚开始接受一个我刚刚开始的项目,但是我仍然在努力解决我留下的问题!
目前我有一个非常简单的应用程序,它只在屏幕上有一个精灵,并使用方向键移动.问题是每两秒左右,游戏口吃,精灵似乎向后跳,然后很快回来.
精灵本身是一个55x33位图,所以没有任何大的,并且使用的代码如下.希望这足以让人们了解可能出现问题的一些想法,如果要求视频确切地看到口吃的样子我可以把它放在一起并在需要时将其上传到某个地方.
正如你在代码中看到的那样,它确实可以弥补帧之间的时间损失,如果它发生了更大的移动,那么这种下降在时间上非常一致地发生,这让我相信我在某处做错了.
我已经尝试了几台不同的机器,但问题仍然存在于所有这些机器上,如果有人有任何想法或者可以看到它在哪里我搞砸了它会非常感激,如果你能指出它.
谢谢 :)
游戏的构造器设置图形设备管理器
graphics = new GraphicsDeviceManager(this);
graphics.IsFullScreen = true;
graphics.SynchronizeWithVerticalRetrace = false;
graphics.PreferredBackBufferWidth = 1920;
graphics.PreferredBackBufferHeight = 1080;
Content.RootDirectory = "Content";
this.IsFixedTimeStep = false;
Run Code Online (Sandbox Code Playgroud)
游戏更新方法中的代码
KeyboardState keyboard = Keyboard.GetState();
GamePadState gamePad = GamePad.GetState(PlayerIndex.One);
if (keyboard.IsKeyDown(Keys.Escape)) {
this.Exit();
}
if ((keyboard.IsKeyDown(Keys.Left)) || (gamePad.DPad.Left == ButtonState.Pressed))
{
this.player.MoveLeft((float)gameTime.ElapsedGameTime.TotalMilliseconds);
} else if ((keyboard.IsKeyDown(Keys.Right)) || (gamePad.DPad.Right == ButtonState.Pressed))
{
this.player.MoveRight((float)gameTime.ElapsedGameTime.TotalMilliseconds);
}
if ((keyboard.IsKeyDown(Keys.Up)) || (gamePad.DPad.Up == ButtonState.Pressed))
{
this.player.MoveUp((float)gameTime.ElapsedGameTime.TotalMilliseconds);
} else if ((keyboard.IsKeyDown(Keys.Down)) || (gamePad.DPad.Down == ButtonState.Pressed))
{
this.player.MoveDown((float)gameTime.ElapsedGameTime.TotalMilliseconds);
}
base.Update(gameTime);
Run Code Online (Sandbox Code Playgroud)
上面的更新方法中看到的"移动"方法
public void MoveLeft(float moveBy)
{
this.position.X -= (moveBy * this.velocity.X);
}
public void MoveRight(float moveBy)
{
this.position.X += (moveBy * this.velocity.X);
}
public void MoveUp(float moveBy)
{
this.position.Y -= (moveBy * this.velocity.Y);
}
public void MoveDown(float moveBy)
{
this.position.Y += (moveBy * this.velocity.Y);
}
Run Code Online (Sandbox Code Playgroud)
游戏的绘制方法
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(this.player.Texture, this.player.Position, null, Color.White, this.player.Rotation, this.player.Origin, 1.0f, SpriteEffects.None, 0.0f);
spriteBatch.End();
base.Draw(gameTime);
Run Code Online (Sandbox Code Playgroud)
编辑:忘了提一下,Move方法中使用的velocity对象是Vector2
我设法在一瞬间看到它发生一次,这让我发现了我认为的问题所在。由于您使用原始ElapsedGameTime.TotalMilliseconds值作为运动的一个因素,因此您的程序经历的所有计算机滞后都将直接应用于运动。例如,如果您的计算机 (OS) 在二十分之一秒内执行其他操作,则经过的时间值将累积到约 50 毫秒的值,而通常约为 0.3 毫秒。这将导致帧的运动量比正常帧多 150 倍。
要手动执行此操作,您可以执行以下操作:
// define a frame counter
private int mCounter;
...
protected override void Update(GameTime pGameTime)
{
// save the elapsed time value
float time = (float)pGameTime.ElapsedGameTime.TotalMilliseconds;
...
// force a long frame every 2500th frame (change depending on your framerate)
if (mCounter++ > 2500)
{
mCounter = 0;
time = 75; // about 225 times longer frame
}
...
// use the time value in your move calls
if ((keyboard.IsKeyDown(Keys.Left)) || (gamePad.DPad.Left == ButtonState.Pressed))
mPlayer.MoveLeft(time);
Run Code Online (Sandbox Code Playgroud)
为了防止这种情况发生,(除了设置IsFixedTimeStep = true;,这会立即修复它;但假设你想IsFixedTimeStep这样做false),你应该使用一个时间值,如上所述,但要限制它。由您决定运动所用时间的比例,并确定每帧允许通过的最佳时间量。前任:
protected override void Update(GameTime pGameTime)
{
// save the elapsed time value
float time = (float)pGameTime.ElapsedGameTime.TotalMilliseconds;
if (time > 1)
time = 1;
...
if ((keyboard.IsKeyDown(Keys.Left)) || (gamePad.DPad.Left == ButtonState.Pressed))
mPlayer.MoveLeft(time);
...
Run Code Online (Sandbox Code Playgroud)
虽然这可以解决当前程序的问题,但由于没有发生太多事情,因此每个帧只有 0.3 毫秒。一旦游戏内容增多,每帧就会花费更多时间,并且您会希望上限远高于 1 毫秒。
编辑:需要明确的是,这是 CPU/操作系统的“停机时间”。它不会消失*,只取决于您是否在发生这种情况时向前跳一大堆(例如,如果经过的时间达到 2000 毫秒,这可能会导致问题),或者限制这些峰值并让它们引起落后; 无论哪种方式,你的动作中都会有一个你无法填补的“漏洞”。这确实很正常,而且并不像看起来那么重要。一旦你的游戏中发生了更多的事情,它就会变得越来越不引人注目。它目前非常突出,特别是因为只有两个图形存在并且没有其他事情发生。
*(实际上,您可能会寻找可以关闭的其他应用程序和进程,以防止 CPU 被其他程序借用,但由于您使用的是多任务操作系统,因此永远无法保证您拥有 CPU给你自己。)
| 归档时间: |
|
| 查看次数: |
3107 次 |
| 最近记录: |