不同框架上的帧更新速度

问题描述 投票:0回答:1

我用 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 类一样。

c# winforms monogame
1个回答
0
投票

我只能回答 Monogame:通常,Monogame 开箱即用的固定帧速率设置为 60 FPS。因此,如果您像以前那样测量时间,它将始终显示 16 毫秒。

要更改此设置,请在初始化中使用

IsFixedTimeStep = false;
,并且垂直同步必须关闭 (
DeviceManager.SynchronizeWithVerticalRetrace = false;
)。这样,您就可以使用可变的增量时间和最大可能的 FPS。

© www.soinside.com 2019 - 2024. All rights reserved.