sprite animation - use of timers

Blitz3D Forums/Blitz3D Beginners Area/sprite animation - use of timers

Hi, this may be an obvious question to ask but can I assume everyone is using a similar technique for the timing of sprite anaimations...

for axample, I have a car based 2D driving game (top down) and every time a car bumps into the perimeter wall it causes a little cloud to appear.

The cloud has 10 frames of animation, then disappears. I have lots of little animations like this that can crop up during the game. The game has 4 cars, each of which can generate a cloud so...

Would I be right to assume everyone would assign a timer variable to each of the 4 clouds? The thinking being that once a cloud animation is triggered, each cloud has a timer which updates the animation frame ever 500ms ?

In my main loop, I check all timers like this:

If MilliSecs() - cloud1_timer >= 500 ; timer reached 500ms?
cloud1_timer = 0 ; stop timer
End if

Or is there a better way ?

Hi Dax,
I would not use single variables, like cloud1_timer, cloud2_timer, and so on. If you have to deal with 100 different animations, it could be a frustrating task...

Instead, I would use a type structure, where to store all the needed animation infos, like anim speed, frame start, frame end, flags, and the like. Then, I just need one dedicated type loop (the for..each loop) to go through all the animations:

test = millisecs()
For anim.t_animations = each t_animations
if test - anim\start_time > 500 then
anim\running = false
endif


Hope it helps,
Sergio.

Sounds to me like you want a particle system.

Take a look at this:
Global particles = LoadAnimImage("gfx\particles\particles.png",32,32,0,16)
MaskImage particles,255,0,255
Global alienblood = LoadAnimImage("gfx\particles\splatfade.png",64,64,0,8)
MaskImage alienblood,255,0,255
Global barrelanim = LoadAnimImage("gfx\particles\barrel.png",64,64,0,8)
MaskImage barrelanim,255,0,255

Global small_blast_image=LoadAnimImage("gfx\particles\gunsplater.png",32,32,0,10)
Global large_blast_image=LoadAnimImage("gfx\particles\frag.png",32,32,0,7)
MaskImage small_blast_image,255,0,255
MaskImage large_blast_image,255,0,255

Type particle
	Field x#,y#,xs#,ys#
	Field firstframe,lastframe
	Field life
	Field totallife
	Field offset
	Field graphic
	Field order
	Field leave
	Field friction
End Type

Global maxparticle = 200
Global particlecount = 0

Function createparticle.particle(x#,y#,xs#,ys#,life,firstframe,lastframe,graphic,offset,order=1,leave=False,friction=True)

; x,y - the particle position
; xs,ys - the particle speed
; life - how long it will last
; graphic - what graphic to use
; offset - how much it should offset when drawing ie a 32x32 particle would have a 16 offset

; the animation will play from beginning to end over the life of the particle

	Local p.particle = New particle
	
	p\x = x
	p\y = y
	p\xs = xs
	p\ys = ys
	p\life = life
	p\totallife = life
	p\firstframe = firstframe
	p\lastframe = lastframe
	p\graphic = graphic
	p\offset = offset
	p\order = order
	p\leave = leave
	p\friction = friction
	
	Return p
End Function

Function UpdateParticles()

	If particlecount>maxparticle Then Delete First particle

	particlecount = 0
	
	Local p.particle
	
	For p = Each particle
		
		; move the particle
		p\x = p\x + p\xs
		p\y = p\y + p\ys
		
		If p\friction
			; dampen the speed
			p\xs = p\xs * .9
			p\ys = p\ys * .9
		EndIf

		; particle hits the wall
		result=gettile(p\x,p\y,LayerCollision)
		If result
			;p\life=-1 ; kill me
			; no, bounce back actually
			p\xs=-p\xs*0.2
			p\ys=-p\ys*0.2
		EndIf
		
		; reduce the life
		p\life = p\life - 1
		If p\life <= 0 
			; if the particle has a name add it to the death list
			If p\leave=True Then p\life = 1 Else Delete p
		Else
			particlecount=particlecount+1
		EndIf
	Next
End Function

Function drawparticles(order)
	
	Local p.particle
	
	For p = Each particle
	
		If p\order = order
			; work out what frame it should be displaying
			range = p\lastframe - p\firstframe
			life# = Float(p\totallife - p\life) / Float(p\totallife)
			frame = range * life
			frame = p\firstframe+frame
			
			DrawImage p\graphic,p\x-p\offset-ScreenX,p\y-p\offset-ScreenY,frame
		EndIf
		
	Next
End Function

It's taken from the Alien Breed code, this code isn't used any more at the particle system now uses 3D sprites. Have a look through the code and let us know what bits you don't understand.

This deals with animated sprites as a particle and you set how long you want it to live for.

You use the createparticle function to create one
Update particles to updated them
and Draw particles to draw them!

Pretty straight forward really.

There's probably loads of stuff in there that you don't really need but it keeps it flexible for any type of particle you care to shake a stick at.

Rob

no - don't need a partitcle system thanks - happy with the cloud anim frames I've drawn. This is my 1st game so want to keep it simple!

semar

Yes, all my timers are in structures - I wanted to leep my post simple so avoidedthe complicatin of describing my problems with structures!

so am I on the right track ? this is the solution I came up with personally - I'd like to know if Im doing anything wrong!

That's certainly the way I've always done it!

The main problem with not limiting the frame animation times is that on a faster/slower computer, the speed can vary immensely. Although providing the game runs smoothly enough, this shouldnt be too much of a consideration, more aesthetic.

Malice, can you elaborate ?

I thought the way I'm doing it shows I AM limiting frame animation times ?

I don't think Malice was saying you were doing it wrong, just pointing out what would happen if you didn't do what you're doing.

You are doing it right as you are imho.

I would argue that a particle system makes your life a lot easier as you don't worry about fx in your main game loop. Everything is self-contained so if you improve the particle code all instances improve. If you want to switch it off it's easy, if you want to have less particles for performance it easy. On top of this it can be used for many other uses like explosions, pick ups etc etc.

But hey, that's just me, I'm all for modular, portable code.

Rob, so are there any particle "engines" out there that will generate clouds, explosions and allow multiple instances on screen ?

The one I posted up there ^^ will.

I would suggest taking a look at the code and modifying it to suit your needs. That one works on cycles rather than time so you call the update N times per second, however, there's no reason why you couldn't modify it to take into account time rather than cycles although you'd have to deal with delta timing for the movement of the particles. This is why I deal with game cycles per second for timing code.

Lock your game core at say 120 updates per second then just render when you can. Assuming the computer has enough clout to update your game code without drawing anything 120 times per second the game will run smooth. The downside of course is you'll only ever get 120 fps max, however, I'm not sure how many people will lose sleep over that.

Simple code to lock your game core speed would be:

ups=120 ;updates per second
period=1000/ups
time=MilliSecs()-period

Repeat

Repeat
elapsed=MilliSecs()-time
Until elapsed
tic=elapsed/period
For k=1 To tic
	time=time+period
	ticks=ticks+1

*** Game logic ***

*** Update particles ***

next

** drawscreen and particles **

until keyhit(1)


thanks Rob, thats interesting


I don't think Malice was saying you were doing it wrong, just pointing out what would happen if you didn't do what you're doing.



Indeed I was. I was gonna post something similar to what Rob said, but then I read his post and just left in what is actually there!