I've made a game in GDI and I want to make a fps counter. To do this I use a System.Windows.Forms.Timer with an interval of 1000ms. In the Form1_Paint() I increment the fps variable, I draw a text showing the fps and call the this.Invalidate() at the end. In the Timer_Tick() I put fps = 0. In the Form1_Load() I enable the timer and start it. But the timer doesn't start and the fps variable doesn't come back to 0. Why the timer doesn't start?
I think the problem is from the this.Invalidate(), I think that it doesn't let the timer to call the Timer_Tick(). How can I make the timer call it if this is the problem?
System.Windows.Forms.Timer is a synchronous timer. It's running on the same thread like the GUI, which means that if the GUI is busy with some heavy logic/calculations, the Timer won't run.
You're most likely looking for an asynchronous Timer, which runs on it's own thread, like System.Timers.Timer and System.Threading.Timer. But watch-out for cross-thread-calls.
Use a System.Diagnostics.Stopwatch to measure the time between paints.
Then calculate the frame rate with ((double)1 / Stopwatch.ElapsedMilliseconds) * 1000.
From ElapsedMilliseconds we get "milliseconds per frame", inverting the number gives us "frames per milliseconds" and finally multiplying with 1000 we get the sought after frames per second.
private void Form1_Paint(object sender, PaintEventArgs e)
{
long msec = watch.ElapsedMilliseconds;
watch.Reset();
watch.Start();
label1.Text = ((1d / msec) * 1000).ToString("F") + " FPS";
}
First you'll want to make sure that the timer is actually working. I suspect that it is, but you'll have to write some debugging code to find out for sure. One way is to put a label on your form and have the timer update the label with a tick count (i.e. increments the count each time the timer fires). If the timer is working, then that label should update once per second (approximately).
For your FPS counter, I would suggest that rather than having the timer update the UI, it should just compute the FPS and let the normal game update logic display the FPS when you want it. That way you're not updating the display in multiple places, and you're not wasting time updating the screen just to show the FPS.
Related
I'm using the Geolocator class from WP8 to built a small app that displays the current speed. I have set the Accuracy to High and MovementThreshold to 0.1 meters. At the moment, I'm using the PositionChanged event of the geolocator to get the speed while moving.
The problem is, that when I stop moving, there is no PositionChanged event fired, and thus the speed is most of the time not 0 when it should be 0. Sometimes it works, sometimes not, I guess it has something to do with stopping somewhere in between the threshold.
Another posibility I tried, is not using PositionChanged and polling the current position with GetGeopositionAsync every second using a timer to update the speed. This seems to work better but I guess that this is the more power consumptional method as I am getting the position no matter if it's neccessary or not.
So what is the best way to get the current speed, no matter if moving or not? Can it even be done with PositionChanged?
I guess there is no ideal solution for you.
In your case, I would go with a DispatcherTimer that would fire every second (for example).
You could use a timer as you mentioned, but instead of calling GetGeopositionAsync everytime, you can use the Geolocator instance to get current speed.
I guess speed doesn't only update when PositionChanged is fired so, that way, you could get an updated speed without consuming resources with GetGeopositionAsync.
I have a timer. When it ticks , by calculating based on formulas, the position of 12 panels changes.
The problem is, although timer's interval is 1 milisecond, the moves are very slow.There are many calculations. What can be done for improving speed, using drawing class or something else?
The gui shows positions, I can move the panels by clicking, so the values. If the correct way is drawing class, do I have a chance to move the rectangles by clicking and take the values of them?
although timer's interval is 1 milisecond
That's the core problem, a Timer cannot tick that fast. Actual timer resolution is constrained by the operating system's clock interrupt rate. Which ticks 64 times per second on most Windows machines. Or once every 15.625 millsecond. The smallest interval you can hope to get is therefore 16 msec. So these panels probably now move 16 times slower than you hoped they would.
Keep in mind how this is observed, you only need to keep human eyes happy. They can't perceive anything that changes at 1 msec, anything that updates faster than 25 times per second just looks like a blur. Something that's taken advantage of in TV and the cinema, a movie updates at 24 frames per second. Once ever 42 milliseconds.
So a sane setting for the Timer.Interval is a hair below three times the clock interrupt rate, 46 milliseconds. The actual tick interval will be 3 x 15.625 = 46.875 msec on a regular machine. And still close to 46 msec if the machine runs with a higher clock interrupt rate. You'll get an equivalent frame rate of 21 fps. Right on the edge of a blur to human eyes. The next lower sane rate is two times the interrupt rate or 31 msec for 32 fps. Making it any smaller doesn't make sense, it isn't observable and just burns cpu time for no benefit.
And, important, the rate at which the panel moves is now determined by how much you change its Location property in the Tick event handler. The interval is fixed so the amount of motion you get is determined by the increment in the position. Which will not be one pixel, probably what you are using now.
I am making the character run but the animation is extremely quick as I am doing:
_frameIndex++;
_frameIndex; is the value which points to the image in the SpriteSheet. Does anyone know how I can use gameTime.ElapsedGameTime.TotalMilliseconds to slow the animation down?
I saw that you've asked a couple of questions tonight concerning animation and spritesheets, so here's an example from Aaron Reed's "Learning XNA 4.0," from Chapter 3 under the "Adjusting the Animation Speed" heading.
First, create two class-level variables to track time between animation frames:
int timeSinceLastFrame = 0;
int millisecondsPerFrame = 50;
The first variable tracks time passed since the animation frame was changed, and the second is an arbitrary amount of time that you specify to wait before moving the frame index again. So making millisecondsPerFrame smaller will increase the animation speed, and making it larger will decrease the animation speed.
Now, in your update method, you can take advantage of game.ElapsedGameTime to check time passed since the last frame change, and change the frame when when that value greater than millisecondsPerFrame, you can do work:
timeSinceLastFrame += gameTime.ElapsedGameTime.Milliseconds;
if (timeSinceLastFrame > millisecondsPerFrame){
timeSinceLastFrame -= millisecondsPerFrame;
// Increment Current Frame here (See link for implementation)
}
This sort of solution is similar to what you've found works, except that you can take an extra step to specify exactly how often you want the animation to update, or even change that duration later on in your code if you like. For example, if have some condition that would "speed up" the sprite (like a power-up) or likewise slow it down, you could do so by changing millisecondsPerFrame.
I removed the code that actually updates the current frame, since you should already have something that does that since you have a working animation. If you'd like to see the example in-full, you can download it from the textbook's website.
I debugged the code and noticed that the gameTime.ElapsedGameTime.TotalMilliseconds always equated to 33. So I did the following:
milliSeconds += gameTime.ElapsedGameTime.Milliseconds;
if (milliSeconds > 99)
{
_frameIndex++;
milliSeconds = 0;
}
Which basically means that if this is the THIRD frame of the game, then make he _frameIndex go up. Reset the milliseconds to start over.
I am trying to run an evolutionary algorithm using xna
i would like only to run the logical side of the game
and after a long caculation time add the animation.
Does anybody know how to accelerate calculation time and disable the
Draw() call.
Thanks
Just don't draw in your Draw method. You can keep a counter or a time stamp as reference, and only draw once out of 100 times or once per second.
However, your problem is not the number of times Draw is called, but the number of times Update is called. By default, XNA will never call Update more than 30/60 times per second. You can change the frame rate XNA tries to achieve as explained in this post. To call Update 100 times per second, just change the target elapsed time in your game to:
this.TargetElapsedTime = TimeSpan.FromSeconds(1.0f / 100.0f);
I want to create a simple game like tic tac toe where the human user is playing against the computer. The computer function takes a couple of milliseconds to run but I would like to give the perception of the computer taking 5 seconds to make a move. Which method should I use?
1) Create two memory threads. One for the computer and one for the human user. When the computer is taking 5 seconds to imitate thinking, the human user thread is paused for 5 seconds.
2) Disable input devices for 5 seconds using timer or dispatchertimer
3) Any better methods you can think of..
Thanks!
Edit - The question is about the how and now the why. 5 seconds is just an example. I prefer 1-2 seconds but for example purposes I just chose 5. So please focus on what is the best way to do this and not on the 5 seconds. Thanks again.
Noise and Blinking lights = digital thought.
Rev up the CPU to 100% with an infinite loop to generate heat.
Start looping through all the files to get the hard drive light blinking and making spinning noises.
Run a shell command to change directory to the optical drive to make the optical drive spin.
Set caps lock, numlock and scroll lock on and off, some keyboards have lights for that.
Check to see if your motherboard supports any additional blinking lights.
Ah! Good point. Many fans have API access, so turning the fans on to 100% is cool. The revert to normal could be dangerous though, because if you accidentally turn off the fans for good, it could be serious damage.
you could just make the cursor into an hourglass and disable the main form (which will stop the user from inputting anything), start a timer for 5 secs (i'd make this time configurable), when the timer fires enable the main form and set the cursor back to normal again. Something like this:
Call this method when the user has made their move:
private void UserHasMoved()
{
Enabled = false;
timer1.Interval = 5000;
timer1.Start ();
}
then the event for the timer:
private void timer1_Tick(object sender, EventArgs e)
{
Enabled = true;
timer1.Stop ();
}
wouldn't this be annoying to the faster players? Maybe a second for the turn, but you'll soon find out that 5 seconds is too much.
Either way, do not pause the UI thread, because the interface would 'freeze'.
Because the human is using the GUI as its interface, you can't pause its thread. Pausing the GUI thread would disable your form from repainting, thus not showing the computer's move.
I'd just disable all game related input, and show an animation of the computer working its brain.
Two very important usability principles:
Don't block the UI thread! Only disable the game control so that the player cannot perform a step during the thinking.
Show a visual feedback to the user indicating the thinking and that he can't perform the step for a while.
And of course, balance the exact duration of thinking carefully. Treat the players' time as very precious.
From your question it seems you do not want the computer play to be so lightning fast that the human player can't see it. For that effect, why don't you display some random animation showing possible plays, and ultimately animating the chosen move.
Edit: I have to agree that disabling input devices is a bit harsh. Maybe switch the application to a state in which any input by the user cannot affect the board, but can affect other commands, such as save, restart or quit.