Creating a Game Loop in C#
I posted a tutorial in the C# section about using Managed DIrectX. Well, I want to try and help those of you who can't use XNA because it requires Shader Model 1.1 or greater a chance to use C# to make a game. C# is a good choice for beginners because it takes a lot of the complexities out of windows programming and knowing the ins and outs of the Windows API.
Before you can get started there are a few things that you need to do. First you have to create a timer class. I know that C# ships with a Timer control. This timer is good but the class that I will show you will be able to be upgraded later.
Go head an create a new Windows application in Visual C#. (I use Visual C# 2008 Express Edition but any C# IDE should work, I'm not doing anything mystical.)
Once you have your application ready add a new class to your project and call it Timer. (I will be using this class in future tutorials so save your project and it will be added to as the tutorials continue.)
In this class you will be importing a method from the kernel32.dll so you will need to add a using statements to your class:
CSharp
using System.Runtime.InteropServices;
This class allows you to access native code in your program.
I will be using an attribute to import a native method into the program. I'm not going to go into how attributes work, I want to concentrate on making a game loop. If you are interested in learning how attributes work I suggest you go to the MSDN library, look up the C# Programming Guide and open the Attributes topic. For now all you need to know is that you can use the [DllImport("file.dll")] attribute to import a method form a native code dll. You will be using one native code method in this class. This is how you import the method:
CSharp
[DllImport("kernel32.dll")]
private static extern long GetTickCount();
The method is used to get the current tick count of your system.
You will need one private field for this class. It is used to store the current tick count:
CSharp
private long StartTick = 0;
Now it is time to create the Constructor for the class. The constuctor is simple, all it does is call the Reset method to reset the tick count to the current tick.
CSharp
public Timer()
{
Reset();
}
The Reset function is also simple. It just sets the StartTick variable to the current tick count. Here is the code:
CSharp
public void Reset()
{
StartTick = GetTickCount();
}
There is one more method to add to the Timer class. It is a method to get how many ticks have elapsed since the last Reset of the timer. This is the code:
CSharp
public long GetTicks()
{
long currentTick = 0;
currentTick = GetTickCount();
return currentTick - StartTick;
}
Now you have a more accurate timer you can add to your C# games. In future tutorials the timer will be updated to include more features and I plan on making it a class library that can be easily added to your projects.
With the Timer class finished it is time to turn to the Program.cs file. I will be making a few changes to this file. First you need to find this line and delete it:
CSharp
Application.Run(new Form1());
In it's place add this code:
CSharp
Form1 myForm = new Form1();
myForm.Show();
myForm.GameLoop();
This code creates a new form, displays it calls a methed that you going to write to make the game loop.
That just leaves the form to code. You need to add a variable to the code for the timer. This is the code:
CSharp
Timer timer = new Timer();
All that is left is to write three methods. One public method and two private methods. The private methods you will have to fill in when you are writing your games. The public method is the interesting method. This is the code for the methods:
CSharp
public void GameLoop()
{
while (this.Created)
{
timer.Reset();
GameLogic();
RenderScene();
Application.DoEvents();
while (timer.GetTicks() < 50) ;
}
}
private void RenderScene()
{
// TODO: Write the code to render your scene here
}
private void GameLogic()
{
//TODO: Write your game logic here
}
So, what does the GameLoop method do? It runs until the form is closed. In each loop, the Timer is reset. Your GameLogic and RenderScene methods are called in order. Any events for the form are processed. Then comes the interesting part. This is where you write the code for handling the timing of the program. In this case the program pauses if less than 50 ticks have passed by. For your games you will have to adjust this number to get the timing right.
This is what you could do to create a game loop in C#.
Here are the complete listing so the Timer.cs file, Program.cs file and Form1.cs files:
Timer.cs
CSharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace GameProject
{
class Timer
{
[DllImport("kernel32.dll")]
private static extern long GetTickCount();
private long StartTick = 0;
public Timer()
{
Reset();
}
public void Reset()
{
StartTick = GetTickCount();
}
public long GetTicks()
{
long currentTick = 0;
currentTick = GetTickCount();
return currentTick - StartTick;
}
}
}
Program.cs
CSharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace GameProject
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 myForm = new Form1();
myForm.Show();
myForm.GameLoop();
}
}
}
Form1.cs
CSharp
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace GameProject
{
public partial class Form1 : Form
{
Timer timer = new Timer();
public Form1()
{
InitializeComponent();
}
public void GameLoop()
{
while (this.Created)
{
timer.Reset();
GameLogic();
RenderScene();
Application.DoEvents();
while (timer.GetTicks() < 50) ;
}
}
private void RenderScene()
{
// TODO: Add code for rendering your scene here
}
private void GameLogic()
{
// TODO: Add code for your game logic here
}
}
}