C#简单的2d游戏-使基本的游戏循环

本文关键字:游戏 循环 2d 简单 | 更新日期: 2023-09-27 18:28:53

尽管我在c#方面有一些经验,但这是我在c#中的第一个游戏。我正在尝试设置游戏的最小骨架。我听说Tick Event是创建主游戏循环的糟糕方法。

这是我试图实现的主要概念:

程序.cs

//Program.cs calls the Game Form.
Application.Run(new Game());

Game.cs

public partial class Game : Form
{
    int TotalFramesCount = 0;
    int TotalTimeElapsedInSeconds = 0;
    public Game()
    {
        InitializeComponent();
        GameStart();
    }
    public void GameStart()
    {
        GameInitialize();
        while(true)
        {                
            GameUpdate();                
            TotalFramesCount++;
            CalculateTotalTimeElapsedInSeconds();
            //Have a label to display FPS            
            label1.text = TotalFramesCount/TotalTimeElapsedInSeconds;
        }
    }
    private void GameInitialize()
    {
        //Initializes variables to create the First frame.
    } 
    private void GameUpdate()
    {
        // Creates the Next frame by making changes to the Previous frame 
        // depending on users inputs.           
    }     
    private void CalculateTotalTimeElapsedInSeconds()
    {
        // Calculates total time elapsed since program started
        // so that i can calculate the FPS.            
    }  
}

现在,这将不起作用,因为while(true)循环阻止了游戏窗体的初始化。通过使用System.Threading.Thread.Sleep(10);Application.DoEvents();,我找到了一些解决方案,但我没能成功。

为了解释为什么我要在这里实现此代码,请参见正在使用的上述代码的示例
假设我希望我的游戏执行以下操作:
平滑地在循环中将100x100 Black colored Square从点(x1,y1)移动到(x2,y2)并向后移动,并在上述代码的label1中显示FPS。考虑到以上代码,我可以使用TotalTimeElapsedInSeconds变量来设置与Time而非Frames相关的移动速度,因为每台机器的Frames都不同。

// Example of fake code that moves a sqare on x axis with 20 pixels per second speed
private void GameUpdate()
{
int speed = 20;
MySquare.X = speed * TotalTimeElapsedInSeconds;
}

我之所以使用while(true)循环,是因为我会在每台机器上获得最好的FPS。

  • 如何在实际代码中实现我的想法?(我要找的只是基本骨架)
  • 我如何设置最大值,比方说500 FPS,以使代码运行起来"更轻松"?而不是试图产生尽可能多的帧,我怀疑这会不必要地过度使用CPU(?)

C#简单的2d游戏-使基本的游戏循环

帧速率与平滑度无关。即使你达到500帧/秒,运动也会有起伏甚至更糟。诀窍是与显示器的刷新率同步。因此,对于60Hz的显示器,您需要60帧/秒。在C#中使用循环是不能做到这一点的。您需要DirectX或XNA。这些框架可以使您的绘图与显示器的垂直扫描同步。

您需要为while(true)-loop:创建自己的线程

Thread thread = new Thread(new ThreadStart(GameStart));
thread.Priority = ThreadPriority.Lowest;
InitializeComponent();
thread.Start();

查看此博客文章以获得更多编码直觉:https://praybook2.blogspot.com/2020/04/this-now-advanced-stuff.html

艰难的循环很快。使用线程有很多缺点,可以考虑使用一些现成的游戏引擎,比如Godot;如果所有这些小问题都是事先解决的,那么只在需要的时候使用线程。