0
\$\begingroup\$

I implemented a fixed time step loop for my C# game. All it does at the moment is make a square bounce around the screen. The problem I'm having is that when I execute the program, I can't close it from the window's close button and the cursor is stuck on the "busy" icon. I have to go into Visual Studio and stop the program manually.

Here's the loop at the moment:

public void run()
    {
        int updates = 0;
        int frames = 0;
        double msPerTick = 1000.0 / 60.0;
        double threshhold = 0;
        long lastTime = getCurrentTime();
        long lastTimer = getCurrentTime();


        while (true)
        {
            long currTime = getCurrentTime(); 
            threshhold += (currTime - lastTime) / msPerTick;
            lastTime = currTime;

            while (threshhold >= 1)
            {
                update();
                updates++;
                threshhold -= 1;                                     
            }

            this.Refresh();
            frames++;

            if ((getCurrentTime() - lastTimer) >= 1000)
            {          
                this.Text = updates + " updates and " + frames + " frames per second";
                updates = 0;
                frames = 0;
                lastTimer += 1000;
            }
        }
    }

Why is this happening?

\$\endgroup\$
2
  • \$\begingroup\$ Please, confirm: you can move the mouse cursor over the window and your game receives mouse events, only problem is that you cannot close the main window. If answer is "yes", then maybe you are not checking for an exit condition, I don't see such code in your main loop, but maybe that code is in the update method. \$\endgroup\$ Jul 1, 2013 at 23:28
  • 1
    \$\begingroup\$ You have an infinite loop. You're probably calling 'run' on the main thread, which means you never give Windows an opportunity to pump any messages, which means the OS thinks your process is not responding, thus the busy cursor. You can't use an infinite loop like that on the main thread. \$\endgroup\$
    – user1430
    Jul 2, 2013 at 0:19

3 Answers 3

3
\$\begingroup\$

You need to handle windows events in order to get things like the close button and mouse interaction to work.

Either set up an event poll in your game loop or a callback function to handle events.

\$\endgroup\$
4
  • \$\begingroup\$ Well it seemed to work correctly when I didn't implement the loop like that. At first the loop consisted of just a timer, I didn't have any problems then. Is there something wrong with my loop where the cursor will just stay on the busy state? \$\endgroup\$
    – Ben
    May 2, 2013 at 22:00
  • \$\begingroup\$ The only time that I have seen that is when there is no event handling. \$\endgroup\$ May 2, 2013 at 22:14
  • \$\begingroup\$ I don't think this is the problem (since its C# he probably uses WPF or WinForms which handles it for you). See my answer for another posibility. \$\endgroup\$
    – Roy T.
    May 2, 2013 at 22:23
  • \$\begingroup\$ @RoyT. I don't do much C# but this sounded like what I run into with SDL, so I would go with your answer. (also up-vote for ya) \$\endgroup\$ May 2, 2013 at 22:26
1
\$\begingroup\$

I think your window isn't responding because its message loop isn't handled. If that's the case and since you are using WinForms, adding Application.DoEvents(); somewhere inside your main loop should fix that. (The standard Application.Run() won't work because it's creating its own loop, so yours won't be executed until the window is closed.)

I expect your old Main method (when using timers) looked something like this (the VS standard template):

public static void Main(string[] args) {
    Form1 f = new Form1();
    Application.EnableVisualStyles();
    Application.Run(); // this handled the message loop for you
}

whereas your new Main method should look something like this:

public static void Main(string[] args) {
    Form1 f = new Form1();
    f.run(); // you need to handle the message loop on your own in there
}

Of course, replace Form1 with your corresponding Form class.

For more information, see the relevant documentation.

\$\endgroup\$
0
\$\begingroup\$

You are using C# so chances are that all the window message loops are already being handled by WinForms or WPF (if you are using one of those), so I don't think that is the problem. However since it did work when using a timer I think the problem is that you just don't give the application (or windows) time to handle the events since your loop is running as fast as possible because of while(true). Just add Thread.Sleep(0) to the bottom of your loop. This will cause the thread to yield so the rest of the application can do some processing until the Windows Thread Scheduler restarts the thread again.

\$\endgroup\$
8
  • \$\begingroup\$ I voted you down: sleep() is not a good thing to use while you try to control the framerate. gamedev.stackexchange.com/questions/18898/… \$\endgroup\$ May 2, 2013 at 22:35
  • \$\begingroup\$ Thread.Sleep(0) didn't work unfortunately. \$\endgroup\$
    – Ben
    May 2, 2013 at 22:40
  • 1
    \$\begingroup\$ @SethBattin ah that is a common discussion. However the answer on that question already explains that sleep(0) isn't a problem. The problem is sleep(some_time) to control your exact frame rate since it only guarantees a minimal sleep time. Fact of the matter is that the scheduler can always, and at any time, yield your thread, so doing it yourself isn't that much of a problem. As an example note that John Carmack uses sleep(0) in the Quake engine. (nanobit.net/doxy/quake3/win__main_8c-source.html line 689) \$\endgroup\$
    – Roy T.
    May 3, 2013 at 11:17
  • \$\begingroup\$ @Ben hmm that is unfortunate. I was sure it would be it. What frameworks do you use in C#? \$\endgroup\$
    – Roy T.
    May 3, 2013 at 11:18
  • \$\begingroup\$ It's just my own framework, to be honest. I'm just trying to port over a framework I implemented in Java. Even when I run the debug executable, clicking on the program results in an "not responding" error. I believe the loop is causing the program to never idle and therefore making the system think it's still loading. \$\endgroup\$
    – Ben
    May 3, 2013 at 13:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .