我用 Python 和 C#、Pygame、Monogame 和 Windows Forms 实现了一个非常小的程序。我想看看更改背景颜色所需的时间差异(以毫秒为单位)。
这些是各自的代码:
Pygame
import sys,time
from pygame.locals import *
import pygame
def g():
table = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
swap = -1
counter = 0
cl = pygame.time.Clock()
sta = time.time()
while counter<2000:
for event in pygame.event.get():
if event.type== QUIT or (event.type ==pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
pygame.quit()
sys.exit()
if swap>0 :
table.fill((255,0,0))
swap = -1
else:
table.fill((0,0,255))
swap = 1
pygame.display.update()
counter+=1
cl.tick()
print((time.time()-sta)*1000/counter)
g()
单一游戏
using System;
using System.Diagnostics;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace MonoGameProject;
public class Game1 : Game
{
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
Texture2D texture;
int sw = 1;
Stopwatch stp = new Stopwatch();
double counter = 0d;
Color color;
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
protected override void Initialize()
{
_graphics.PreferredBackBufferWidth = 1200;
_graphics.PreferredBackBufferHeight = 900;
_graphics.SynchronizeWithVerticalRetrace = false;
_graphics.ApplyChanges();
stp.Start();
base.Initialize();
}
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
texture = new Texture2D(GraphicsDevice,
GraphicsDevice.Viewport.Width,
GraphicsDevice.Viewport.Height);
Color[] colorData = new Color[texture.Width * texture.Height];
for (int i = 0; i < colorData.Length; i++)
{
colorData[i] = Color.Red;
}
texture.SetData(colorData);
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back ==
ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
if (sw > 0) {
color = Color.Red;
sw = -1;
} else {
color = Color.Blue;
sw = 1;
}
Color[] colorData = new Color[texture.Width * texture.Height];
for (int i = 0; i < colorData.Length; i++)
{
colorData[i] = color;
}
texture.SetData(colorData);
_spriteBatch.Begin();
_spriteBatch.Draw(texture, Vector2.Zero, Color.White);
_spriteBatch.End();
base.Draw(gameTime);
counter += 1;
if (counter>2000)
{
Debug.WriteLine($"Ms per frame " +
$"{stp.ElapsedMilliseconds / counter}");
Thread.Sleep(5000);
Environment.Exit(0);
}
}
}
Windows 窗体
using System.Diagnostics;
using System.Globalization;
namespace reaction;
public partial class Form1 : Form {
double timeDiff = 0;
int switchIndex = 1;
double acum = 0d;
private Stopwatch _globalStopwatch = new Stopwatch();
private System.Windows.Forms.Timer colorChangeTimer;
public Form1()
{
colorChangeTimer = new System.Windows.Forms.Timer();
colorChangeTimer.Interval = 1;
colorChangeTimer.Tick += new EventHandler(colorChangeTimer_Tick);
colorChangeTimer.Start();
_globalStopwatch.Start();
}
private void colorChangeTimer_Tick(object sender, EventArgs e)
{
if (switchIndex > 0) {
BackColor = Color.Red;
switchIndex = -1;
} else {
BackColor = Color.Blue;
switchIndex = 1;
};
acum += 1;
if (acum > 2000) {
Debug.WriteLine($"Ms per frame " +
$"{_globalStopwatch.ElapsedMilliseconds / acum}");
Thread.Sleep( 5000 );
this.Close();
}
}
}
Pygame 报告平均每帧大约 1 毫秒,而 Windows Forms 和 Monogame 为 16 毫秒。有没有办法让 Windows Forms 或 Monogame 更新得更快? Pygame 指标正确吗?如果我想要最快的更新频率,你会推荐什么库/语言/框架?如果我还想通过一些操作以编程方式对显示进行复杂的更改,因此代码执行也必须很快?我还想要高分辨率计时监控,就像 C# 中的 Stopwatch 类一样。
我只能回答 Monogame:通常,Monogame 开箱即用的固定帧速率设置为 60 FPS。因此,如果您像以前那样测量时间,它将始终显示 16 毫秒。
要更改此设置,请在初始化中使用
IsFixedTimeStep = false;
,并且垂直同步必须关闭 (DeviceManager.SynchronizeWithVerticalRetrace = false;
)。这样,您就可以使用可变的增量时间和最大可能的 FPS。