Jump to content
Xtreme .Net Talk

Recommended Posts

Posted
If you use time-based algorithms (animations, physics, AI, etc) then they will run at the exact same speed regardless of framerate. This is the way almost all modern games operate.
Posted

Does anyone know what the article is talking about here:

 

For flipping sprites you would do the same. You would have to declare a float variable that keeps track of the current frame. Also, you would limit the frames drawn per second.

 

sprite.fcurrentframe+=sprite.framespersecond*frametime;

if(sprite.fcurrentframe>sprite.totalframes)

{

int isoverby=sprite.fcurrentframe/sprite.totalframes;

sprite.fcurrentframe-=mesprite.totalframes*isoverby;

}

sprite.icurrentframe=(int)sprite.fcurrentframe;

sprite_draw(&sprite);

 

 

This skips frames if you have a slow PC, and on a fast PC it will run every frame but no more than sprite.framespersecond.

 

It seems to be missing something....

 

I want to be able to skip the rendering stage of my game loop when the FPS limit is reached - I understood the first part of the article about how to limit the movement of game objects, but this second half has me baffled.

 

Ideas?

Posted

i HAVE to agree with Optikal here. I have to spoil everyones fun here even if this IS an OK way to do it the current "state-of-the-art" way is to do a deterministic game-loop using "time-frames" or should i call it "time-step-based" game-loop that allows for unlimited fps but same speed on all computers.

 

you basically every time the loop goes around you update the game-state in loops of X milliseconds. so on a slow computer 42 milliseconds passed since last loop, and you have physics and everything on 10ms, you loop while 10*X<42 and save the last 2 fot next loop.

 

i have read an article on this on gamasutra (have no link sorry, and you have to register) and i HIGHLY recommend people that are intreseted in this to read up on it.

 

thanks :) i love this topic it's very intreseting.

  • 1 month later...
Posted

Problems

 

i copied your class, adding

Imports System.Runtime.InteropServices

to the top and i get exceptions:

 

An unhandled exception of type 'System.InvalidProgramException' occurred in xfengine.dll

 

Additional information: Error: PInvoke item (field,method) must be Static.

 

The program '[1588] XF2.exe' has exited with code 0 (0x0).

 

 

xfengine.dll is my class library containing the high resolution timer and XF2.exe is the console app using xfengine.dll

 

any help much appreciated

Stephen

  • 2 weeks later...
Posted (edited)

Like everyone else, I programmed my own Performance Timer class. I used this in a game loop to test it, and it works perfectly. I found the others that were provided a little disjointing to use, which is why I programmed my own.

 

Maybe it'll help those who still don't fully understand how it's working *shrug*

 

A few reminders about how this all comes together:

To base game movements off pixels per second multiplied by the current ticks per second, and for animation multiply frames per second by the current ticks per second.

 

If you add up the ticks per second for a full second, the total will come out to 1. This is because TicksPerSecond will give you a fractional time based off of 1 second.

 

The current frames per second is the inverse of the ticks per second (1.0/timer.TicksPerSecond)

 

using System;
using System.Runtime.InteropServices;

namespace DDUtil
{
/// <summary>
/// A high performance timer.
/// </summary>
public class PerfTimer 
{
	#region Imported Methods

	/// <summary>
	/// The current system ticks (count).
	/// </summary>
	/// <param name="lpPerformanceCount">Current performance count of the system.</param>
	/// <returns>False on failure.</returns>
	[DllImport("Kernel32.dll")]
	private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);

	/// <summary>
	/// Ticks per second (frequency) that the high performance counter performs.
	/// </summary>
	/// <param name="lpFrequency">Frequency the higher performance counter performs.</param>
	/// <returns>False if the high performance counter is not supported.</returns>
	[DllImport("Kernel32.dll")]
	private static extern bool QueryPerformanceFrequency(out long lpFrequency);

	#endregion

	#region Member Variables

	private long _startTime = 0;
	private long _recordTime = 0;
	private double _ticksPerSecond = 0;

	#endregion

	#region Constructor

	/// <summary>
	/// Creates a new PerfTimer.
	/// </summary>
	public PerfTimer() 
	{
		// No need to do anything.
	}

	#endregion

	#region Methods

	/// <summary>
	/// Records stop time and ticks per second from when this PerfTimer was started.
	/// </summary>
	public void Record() 
	{
		// Record when the timer was recorded and the ticks per second.
		_recordTime = PerfTimer.Counter;
		_ticksPerSecond = (double) (_recordTime - _startTime) / (double) PerfTimer.Frequency;
	}

	/// <summary>
	/// Starts this PerfTimer at the specified tick count.
	/// </summary>
	/// <param name="ticks">Tick count to start at.</param>
	public void Start(long ticks) 
	{
		// Record when the timer was started.
		_startTime = ticks;
	}

	#endregion

	#region Properties

	/// <summary>
	/// Gets the number of ticks per second based off the current start and record times.
	/// </summary>
	public double TicksPerSecond 
	{
		get {
			return _ticksPerSecond;
		}
	}

	/// <summary>
	/// Gets the tick count of when this PerfTimer was started.
	/// </summary>
	public long StartTime 
	{
		get {
			return _startTime;
		}
	}

	/// <summary>
	/// Gets the tick count of when this PerfTimer was last recorded.
	/// </summary>
	public long RecordTime 
	{
		get {
			return _recordTime;
		}
	}

	/// <summary>
	/// Gets the frequency that this PerfTimer performs at.
	/// </summary>
	public static long Frequency 
	{
		get {
			long freq = 0;
			QueryPerformanceFrequency(out freq);

			return freq;
		}
	}

	/// <summary>
	/// Gets the current system ticks.
	/// </summary>
	public static long Counter 
	{
		get {
			long ticks = 0;
			QueryPerformanceCounter(out ticks);

			return ticks;
		}
	}

	#endregion
}
}

 

Sample on how to use it (it's almost too simple);

 

PerfTimer timer = new PerfTimer();
timer.Start(PerfTimer.Counter)

while (_playGame) {
  timer.Record();

  // ... update game objects with object.Update(timer.TicksPerSecond).
  // ... display fps with 1.0/timer.TicksPerSecond.

  timer.Start(timer.RecordTime);
}

Edited by wyrd
Gamer extraordinaire. Programmer wannabe.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...