10

I am beginner with programming in c# and i am just doing a pingpong game. I am using threads - one for collision, one for move, one for painting.

My question is why the program run faster, when i open steam :D to me it seems like a nonsense.Witch slower i mean - ball is slower and the pads too. It looks like the processor is lazy to do the work or something like that. It is happening in real time - i open the game, it is slow, i open steam, it is faster and then i close steam and it is slow again.

My first thought was that it is because dual graphics card but making it to use nvidia card don´t help.

Another situation: i open game - slow, open skype - game is faster, skype is loaded - game is slow, closing skype - game is fast, closed skype - game is slow..

How to make the game to use processor always same?

my code i move method is

    public void move()
    {
        DelegateSetScore d = new DelegateSetScore(SetScore);

        while (!isDisposing)
        {
            pad1.Y = pad1.Y + 4 * pad1Down + 4 * pad1Up;
            if (pad1.Y < 0) { pad1.Y = 0; }
            if (pad1.Y + pad1.Height > HEIGHT) { pad1.Y = HEIGHT - pad1.Height; }

            pad2.Y = pad2.Y + 4 * pad2Down + 4 * pad2Up;
            if (pad2.Y < 0) { pad2.Y = 0; }
            if (pad2.Y + pad2.Height > HEIGHT) { pad2.Y = HEIGHT - pad2.Height; }

            ball.X = ball.X + 6 * ballXDirection;
            ball.Y = ball.Y + 2 * ballYDirection;

Here is some more code about collision with borders and score counting... and it and with waitevent.

            waitevent.WaitOne(5);

I guess it is because the automatic overclocking of the processor but i am a newbie.. :D

Here is the whole thing in one thread

    public void bigthread()
    {

        DelegateSetScore d = new DelegateSetScore(SetScore);

        while (!isDisposing)
        {
            //move

            pad1.Y = pad1.Y + 4 * pad1Down + 4 * pad1Up;
            if (pad1.Y < 0) { pad1.Y = 0; }
            if (pad1.Y + pad1.Height > HEIGHT) { pad1.Y = HEIGHT - pad1.Height; }

            pad2.Y = pad2.Y + 4 * pad2Down + 4 * pad2Up;
            if (pad2.Y < 0) { pad2.Y = 0; }
            if (pad2.Y + pad2.Height > HEIGHT) { pad2.Y = HEIGHT - pad2.Height; }

            ball.X = ball.X + 6 * ballXDirection;
            ball.Y = ball.Y + 2 * ballYDirection;

            if (ball.X < 0)
            {
                ballXDirection = 1;
                intScorePlayer2++;
                this.BeginInvoke(d, intScorePlayer2, 2);
            }

            if (ball.X + ball.Width > WIDTH)
            {
                ballXDirection = -1;
                intScorePlayer1++;
                this.BeginInvoke(d, intScorePlayer1, 1);
            }

            if (ball.Y < 0)
            {
                ballYDirection = 1;
            }

            if (ball.Y + ball.Height > HEIGHT)
            {
                ballYDirection = -1;
            }

            //collision

            if ((pad1.X + pad1.Width > ball.X) && (ball.X + ball.Width > pad1.X))
                if ((pad1.Y + pad1.Height > ball.Y) && (ball.Y + ball.Height > pad1.Y))
                {
                    ballXDirection = 1;
                    if (pad1Down == 1) { ballYDirection = 1; }
                    if (pad1Up == -1) { ballYDirection = -1; }
                }

            if ((pad2.X + pad2.Width > ball.X) && (ball.X + ball.Width > pad2.X))
                if ((pad2.Y + pad2.Height > ball.Y) && (ball.Y + ball.Height > pad2.Y))
                {
                    ballXDirection = -1;
                    if (pad2Down == 1) { ballYDirection = 1; }
                    if (pad2Up == -1) { ballYDirection = -1; }
                }

            //paint - platno is graphics from picturebox
            Platno.Clear(Color.Black);
            Platno.FillRectangle(Brushes.Orange, pad1);
            Platno.FillRectangle(Brushes.Orange, pad2);
            Platno.FillRectangle(Brushes.Green, ball);

            waitevent.WaitOne(10);
        }
    }

3 Answers3

3

To make sure a game/simulation feel doesn't change with CPU/GPU availability, render speed, etc, you need to use elapsed time to control things, not the loop itself. In the code sample you have, I don't see you taking into account the time elapsed since last execution. So you want your speed a function of time, e.g. 5 pixels(a distance units of sort)/second. Then in every execution, you calculate how much time has elapsed since last time the loop executed, and include that in the distance you need to move by multiplying it with your speed.

Another thing you should do is limit the number of refreshes your game performs. i.e. if a render has happened less than X milliseconds ago, then you don't render until a certain amount of time passes. You can use a target FPS and calculate the time required from that. E.g. if you want to limit your app to 40 FPS, then if your render loop executed in less than 25ms since the last render, you simply sleep until 25ms passes.

Using time as your guide rather than loop executions or fixed waits should prevent your game from rendering faster or slower regardless of what's happening on your system. Of course if you're totally out of CPU/GPU and rendering takes too long, then your FPS will drop to the point you can see the slowness but with a pong-clone game, you really shouldn't get to that point. :)

Tombala
  • 1,660
  • 9
  • 11
  • I have tried once to do this. I measured loop time with stopwatch - start it at start and stop at the end. Then i wait (period- measured time). Every lopp + "wait after" should then use the same amount of time. But - stopwatch almost everything counted 0 ms for the loop.. so it was pointless. – Jan Luxemburk May 10 '13 at 19:58
  • And also - this would be mainyl done to slowdown the loop to make everyone same long. But i firstly need to make it faster as if "steam was running" – Jan Luxemburk May 10 '13 at 20:02
  • You can't use stopwatch. It doesn't have high enough resolution to measure time the way you need to. Look [here](http://stackoverflow.com/questions/1825720/c-high-precision-time-measurement-in-windows) for a discussion of the topic. – Tombala May 10 '13 at 20:03
  • Thanks,It isfor C++, that doesn´t matter? – Jan Luxemburk May 10 '13 at 20:06
  • The problem of speeding up is probably related to how you're synchronizing threads. Hard to pinpoint that problem but an option is for you to render the thread's executions to the screen, especially how much threads are waiting. Specifically, I would look at how often that WaitOne(5) is being called when it's running fast vs. slow. It is hard to tell from the amount of code you have posted to see the thread dynamics. – Tombala May 10 '13 at 20:06
  • I don´t how to synchronize threads. I just create 4 treads with new Thread(new ThreadStart(method)) and Start() them. What i tried is to put everything into one thread - i will post it here.. – Jan Luxemburk May 10 '13 at 20:09
  • @Tombala *"You can't use stopwatch. It doesn't have high enough resolution to measure time the way you need to"* That's completely untrue. The .Net [`Stopwatch`](http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx) class uses the processor's Performance Counters - which is exactly same as is used by the code in the link you gave. Perhaps you were thinking of the `DateTime` class? – Matthew Watson May 10 '13 at 20:09
  • @MatthewWatson You are correct. I misstated that it doesn't have high enough resolution. I was thinking of Timer, not stopwatch. Even then though, StopWatch is not a guaranteed resolution so you might consider using DirectX timer, which is, I believe, more reliable. I haven't touched this stuff in a while so my knowledge is getting outdated. :D – Tombala May 10 '13 at 20:17
  • i added whole thread to the first post - it is still faster with team running, nothing changed. – Jan Luxemburk May 10 '13 at 20:19
  • When you say "faster" does it render more FPS? Or does everything simply move faster? – Tombala May 10 '13 at 20:22
  • Everythinkg simply move faster - faster movement and less flicker when painting. And when it is in "slow mode" i doesnt see difrence if i set waitOne(1) or waitOne(10) it is just the same. Diffrence become visible at like 25ms waittime – Jan Luxemburk May 10 '13 at 20:30
3

That is almost certainly because those apps reprogram the timer interrupt to occur more frequently. By default, Sleep, the waits, and context switch checking happen in 10 or 15 millisecond intervals, depending on the Windows edition, but that can be changed by calling the timeBeginPeriod API function with an argument of 1 (one), say.

See this question for how to do that in your application.

Community
  • 1
  • 1
  • Thanks a lot! By default i have 15ms. Can it do some harm to other programms or computer by settin it to 1 ms? Because it is the only way how to make my programm unchangable by others. – Jan Luxemburk May 10 '13 at 21:24
  • @Zail It sounds like your program will then change the behavior of other programs (like other pingpong games...) in exactly the same way as STEAM changes the behavior of other programs. – Jeppe Stig Nielsen May 10 '13 at 22:02
  • This will cause no harm whatsoever. There will be a tiny bit more O/S overhead and the power consumption will go up slightly, which is more of an issue if running on a laptop. – 500 - Internal Server Error May 10 '13 at 22:02
2

This might be because your processor switches power states. Try keeping CPU-Z open while you open and close your app and Skype/Steam and observe what happens to your processor.

Ani
  • 10,826
  • 3
  • 27
  • 46
  • 1
    This is a good guess, but it's enough of a guess that I don't want to upvote it just yet. But if he confirms this is the issue, @ me a comment and I'll upvote this one and find a worthy 9-vote answer to also upvote and give you a badge for this. – Joel Coehoorn May 10 '13 at 19:37
  • I tried to set my laptop to powersaving mode - the frequncy of proccesor was always 1100 and still with open steam it run faste. Where i can find processor power state in CPU Z? – Jan Luxemburk May 10 '13 at 19:45
  • @Zail: turn off powersaving mode on the machine. Steam, to my knowledge, actually does this when launched. – NotMe May 10 '13 at 20:04
  • I am not that stupid :D i have hight performce mode all time testing this – Jan Luxemburk May 10 '13 at 20:04