即使我有一些c#的经验,这是我在C#中的第一场比赛。我正在尝试设置游戏的最小骨架。我听说Tick Event
是创建主游戏循环的糟糕方法。
这是我想要实现的主要概念:
Program.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。
答案 0 :(得分:6)
帧速率与平滑度无关。即使你达到500帧/秒,运动也会变得不稳定或更糟。诀窍是与您的显示器刷新率同步。因此,对于60Hz的显示器,您需要60帧/秒不超过。你不能通过在C#中使用循环来做到这一点。您需要DirectX或XNA。这些框架可以使您的绘图与显示器的垂直扫描同步。
答案 1 :(得分:0)
您需要针对while(true)-loop建立自己的线程:
Flutter SDK path
查看此博客文章以获得更多的编码直觉: https://praybook2.blogspot.com/2020/04/this-now-advanced-stuff.html
坚韧的循环很快。使用线程有很多缺点,请考虑使用一些现成的游戏引擎,例如Godot;事先解决了所有这些小问题的地方,请仅在需要时使用线程。