Particle Emitters & Fixed Framerate


(TheHuckleberryWill) #1

For some reason, using a particle emitter with a fixed framerate doesnt work very well. It kinda flickers about.

Like this -

https://dl.dropboxusercontent.com/u/76160271/particles%26fixed.swf


Any problem with using fixed framerate?
(Ultima2876) #2

It’s beside the point I suppose, but I highly recommend using a variable framerate. It’s superior in almost every way. I did make a more detailed post about it recently but I can’t find it at the moment.


(TheHuckleberryWill) #3

Yeah, its because currently my jumping methods height relies on the game running at 60fps… I also like the predictability. But, I guess I could change it to a variable framerate without too much difficulty. ( Discourse on mobile really sucks.)


(Zachary Lewis) #4

Do you have the code for the particle system? Your time might not be set properly, causing it to update incorrectly.


(TheHuckleberryWill) #5

Yes I do! I noticed the problem in my project, then quickly coded something to ensure it wasn’t something else in my main project.

package  
{
	import flash.display.BitmapData;
	import net.flashpunk.Entity;
	import net.flashpunk.graphics.Emitter;
	import net.flashpunk.World;
	import net.flashpunk.utils.Ease;
	
	/**
	 * ...
	 * @author Will Huxtable
	 */
	public class GameWorld extends World 
	{
		
		private var emit:Emitter;
		private var ent:Entity
		
		public function GameWorld() 
		{
		
			ent = new Entity(100, 100);
			emit = new Emitter(new BitmapData(3, 3, false, 0xff0000), 3, 3);
			emit.newType("explosion", [0]);
			emit.setMotion("explosion", 0, 50, 2, 360, -40, 2, Ease.quadOut);
			emit.setAlpha("explosion", 1, 0, Ease.quadOut);
			
			ent.graphic = emit;
			add(ent);
		}
		
		override public function update():void 
		{
			emit.emit("explosion", 100, 100);
			
			super.update();
		}
		
	}

}

(Zachary Lewis) #6

I believe I see your problem. When you set your particle motion, you’re setting the duration to 2.

emit.setMotion("explosion", 0, 50, 2, 360, -40, 2, Ease.quadOut);

Since you’re on a fixed timestep, this means the duration of each particle is two frames, not two seconds.

Try setting your duration to 120 (for a two second particle).

Alternatively, if you plan on changing your frame rate, or want your times to be consistent, you might want to consider writing a helper function.

/**
 * Create a duration formatted for the current time mode.
 * @param	seconds The length of the duration in seconds.
 * @return	A properly calculated duration.
 */
function createGameDuration(seconds:Number):Number
{
	return FP.timeInframes ? Math.floor(seconds * FP.assignedFrameRate) : seconds;
}

This way, you can write your tweens and particles once for any frame rate or update mode.

emit.setMotion("explosion", 0, 50, 2, 360, -40, createGameDuration(2), Ease.quadOut);

(Ultima2876) #7

Would this be a useful addition in the FP class?


(Zachary Lewis) #8

I don’t think so. For the most part, fixed or variable frame rate is a design decision based on the kind of game you’re creating, so you don’t wind up switching back and forth very often when working on a planned game.


(Ultima2876) #9

That said, I know of a LOT of developers who assume ‘fixed’ to be the best mode, then realise half way through their project that they’d like to go variable.

It might actually be an idea to do everything in seconds in fixed mode as well, because most developers get tripped up by that. Perhaps all of them. I don’t really see the need for disparity there…


(Zachary Lewis) #10

The purpose of a fixed framerate is to create a deterministic system. With a fixed frame rate, you can ensure a player will always jump the exact same height, or that repeating the exact same input will always result in the exact same output. This is crucial for things like precision games (Mario, Super Meat Boy, Street Fighter, et cetera).

The problem is, with FlashPunk, rendering and updating are tied together. Variable framerate prevents jitter and lag by taking computer speed changes into consideration when calculating location and placement of objects, and this usually makes a game feel better; however, I’ve had times where my computer was lagging and I physically could not make a jump because the timestep wasn’t making my character jump as high as he normally would when my computer was running faster, and this is a problem.

Ranting aside, frame-based counting is (and should be) used for many games. For games that don’t require exact precision (like Bejeweled or card games), time-based counting provides a much more pleasing visual experience.


(Draknek) #11

@Ultima2876 Just for the record, I always say the opposite of you, that there’s no reason to ever use variable timestep mode. Perhaps this is an indication that both of us should start being slightly less dogmatic about the matter!

As Zach says, if you use variable timestep in a real-time game, the way things move will vary depending on the speed the game is running at. This is really bad. Now there are ways to make this not an issue, but the key thing here is that you need to know what you’re doing and understand some maths. If you use a fixed timestep, you get to just ignore this!

@zachwlewis, variable timestep only looks better when your game is running particularly slowly. If that is the case then you have bigger problems! Variable timestep is just a hack to hide poor performance. (And to be fair, there’s a time and a place for hacks: but on-by-default is not that place.)


(Ultima2876) #12

@Draknek @zachwlewis This is really useful information and may have changed my perspective on it :slight_smile: I will experiment some more with it for my next game whenever I get around to doing one. I’ve always found that the jitter problem (it has been mentioned in another topic) isn’t as obvious in variable mode which is why I’ve generally stuck to that (even on beastly computers), and on mobile even with stage3d enhancements it’s hard to get a solid framerate across the entire range of devices (some of the bottom-feeders will only just manage 30fps in most games, some games not even that). Variable works well in those circumstances because it’s not using loads of extra CPU to run the update loop multiple times - but you’re absolutely right, you need a lot of * FP.elapsed and Math.pow littered throughout the game for it to work consistently across varying framerates.

So I think I agree… I just need to find some time to run some tests and confirm!


(Draknek) #13

If you have acceleration anywhere (i.e. gravity), it’s more complicated than just multiplying by FP.elapsed or using Math.pow.

Instead of:

dy += gravity*FP.elapsed;
y += dy*FP.elapsed;

You need to do:

dy += gravity*FP.elapsed;
y += dy*FP.elapsed - 0.5*gravity*FP.elapsed*FP.elapsed;

Not exactly obvious!


(Ultima2876) #14

That’s weird. I’ve always heard that Math.pow for friction is the accurate method - something like value *= Math.pow(friction, FP.elapsed) - wouldn’t that work for gravity also?


(Draknek) #15

That’s a different problem, friction behaves differently to gravity.

The equivalent there is:

Fixed timestep:

speed *= 0.9;
x += speed;

Variable timestep:

speed *= Math.pow(0.9, FP.elapsed);
x += speed * FP.elapsed;

But that’s not actually a complete solution: speed is now framerate-independent but x is not. Not actually sure what the equation for x would need to be.

This stuff gets complicated!


(Ultima2876) #16

Very interesting indeed. Maybe there are problems in my games I didn’t pick up on during testing (I routinely test at 15, 30 and 60 fps to make sure it plays well). I will probably switch to fixed framerate in future then I guess :stuck_out_tongue:


(TheHuckleberryWill) #17

Thanks for clearing that up!

Sorry for the later reply, I was on holiday!