Slow down animation?

BlitzMax Forums/BlitzMax Beginners Area/Slow down animation?

I've been confused about this for awhile now. I've tried working with Milisecs() to slow down the animation, but never know where to start. Using Timers worked, but they slow down the entire program so there's no way I can actually use them.

Any examples/tips/ideas on how to slow down a sprite's animation?

Thanks.

Easy answer - don't change the frame number so often.

Timers will not slow the game down if you use Timer.Ticks() instead of WaitTimer().

Isn't Timer.Ticks() for Blitzplus?

BP?

Use a scaling factor in the timings to allow you to change the rate of an animation (one per animation).. here's something quickly put together to demonstrate :-

SuperStrict


Type TAnim
	Field frame:Int
	Field ms:Float
	Field image:TImage
	Field rate:Float
	
	Method Draw()
		DrawImage image,100,100,frame
	EndMethod
	
	Method Update()
		Local diff:Float = MilliSecs() - ms
		diff = diff * rate
		If( diff > 200 )
			frame = 1 - frame
			ms = MilliSecs()
		EndIf
	EndMethod
EndType	

Graphics 800,600


Global anim:TAnim = New TAnim
anim.frame = 0
anim.image = CreateImage(100,100,2, DYNAMICIMAGE)
anim.ms = MilliSecs()
anim.rate	= 1.0

Cls
DrawOval 0,0,100,100
GrabImage(anim.image,0,0,0)
Cls
DrawRect 0,0,100,100
GrabImage(anim.image,0,0,1)



While Not KeyHit(KEY_ESCAPE)
	Cls
	anim.Draw()
	anim.Update()

	DrawText "Press cursor left/right to change animation speed", 20, 10
	DrawText "Anim rate  = " + anim.rate, 20,30
	DrawText "Anim frame = " + anim.frame, 20,50
	
	Flip
	
	If KeyDown(KEY_LEFT) And anim.rate > 0.1
		anim.rate = anim.rate - 0.01
	EndIf
	
	If KeyDown(KEY_RIGHT) And anim.rate < 5.0
		anim.rate = anim.rate + 0.01
	EndIf

Wend


@ GFK: My bad.. meant to say Blitzplus.

I wouldn't use Millisecs() in this way unless you implement code for when Millisecs() changes from a positive to negative value. If you don't do this, then your game will almost certainly crash. Fair enough it'll only happen once every 25 days or so of uptime, but its still sloppy practice.

Um... as far as I'm aware, Timer.Ticks() isn't even correct syntax for Blitzplus. Rest assured it works in Blitzmax though.

You can also reset a timer's tick counter by using Timer._ticks = 0. (note the underscore).

Agreed. Sloppy use of millisecs was for demonstrating the scaling factor only - you need to handle the wraparound in a real-world app.

What is Timer.Ticks() from then? A module or something? It doesn't work when I use it and I can't find it anywhere in the BlitzMax wiki.

Edit: Nevermind lol. Just had to remove the "."

Didn't work anyway.

Hi,

maybe:

global yourTime%, yourDelay%=48
If MilliSecs() > yourTime + yourDelay
	yourTime = MilliSecs()
	YourFrame:+1
EndIf 


@IKG, timer.ticks() is a TTimer method rather than timerticks(timer) which is the function.
How did it not work?
Anyway, you might want to use Brendane's method.

use millisecs()&$7fffffff and there won't be a problem with the jumping counter from positive to negative values.

...the great thing about using a scaling factor is that you can easily apply it to audio rates, too...

Alright guys, I'm sorry but I really don't understand what most of you are saying. For something posted in the beginner section, you sure do use a lot of terms I'm not yet familiar with. Not to mention all the code examples I'm given which I can't understand. I feel like I should take another break from the forums and come back when I feel less stupid trying to fit in here.

@ Benyboy: I'll have to try that later when I get the chance. Thanks.

IKG, which terms are you unfamiliar with?
Anyway here is some commented code which displays a simple 3 cell animation (I use an animimage with 3 different coloured rectangles each 32*32 in size)
SuperStrict
Rem 
this is the animated_sprite type
End Rem
Type TAnim_Sprite
	Global list:Tlist=CreateList()  ' The list isn't used in this example.
	Field x:Int=100    ' sprite x position
	Field y:Int=100    ' sprite y position
	Field image:TImage ' sprite image taken from Loadanimimage command.
	Field frame:Int = 0 ' current_frame
	Field maxframe:Int ' maximum number of frames
	Field anim_time:Int=500  ' delay between changing the frame
	Field last_change:Int=0 ' the last time the frame was changed.
	Function create:TAnim_Sprite(image:TImage , startframe:Int , maxframe:Int)
		Rem
		Function which creates a TAnim_sprite and populates the frame information.
		End Rem
		Local my_anim:TAnim_Sprite = New TAnim_Sprite
		my_anim.image = image
		my_anim.frame=startframe
		my_anim.maxframe = maxframe - 1
		ListAddLast list,my_anim
		Return my_anim
	End Function
	Method change_speed(speed:Int)
		Rem
		Method used to change the delay between changing the frame.
		End Rem
		anim_time = anim_time + speed
		If anim_time < 0 anim_time = 0
		If anim_time > 1000 anim_time=1000 
	End Method
	Method get_speed:Int()
		Rem
			simply returns the time between frame changes.
		End Rem
		Return anim_time
	End Method	
	Method update()
		Rem
		Method called to check whether we need to change the frame for the tanim_sprite
		End Rem
		' If the current time - the last_changed is greater than the time between 
		' changes then it's time to change the frame.
		If MilliSecs() - last_change > anim_time   
			frame:+ 1
			If frame > 2 frame=0
			last_change = MilliSecs()
		EndIf
	End Method
	Method Draw()
		Rem
		Method which draws the image with the current frame.
		End Rem
		DrawImage image , x , y , frame
	End Method
End Type	
Graphics 640 , 480
' Load the animation.
Local image:TImage = LoadAnimImage("anim_timer.png" , 32 , 32 , 0 , 3) 
' Create an 'instance' of Tanim_sprite and save it's pointer in myplayer.
Local myplayer:TAnim_Sprite = TAnim_sprite.create(image,0,3)
While Not KeyHit(KEY_ESCAPE)
	Cls
	' if we press UP cursor or DOWN cursor, change the speed.
	If KeyDown(KEY_UP) myplayer.change_speed(-5)
	If KeyDown(KEY_DOWN) myplayer.change_speed(5)
	' call the update and draw method for our 'player' sprite.
	myplayer.update()
	myplayer.draw()
	DrawText myplayer.get_speed() , 0 , 0	
	Flip
Wend

Written quite a while ago so might be clunky but should give an idea.

Actually, I can't believe I didn't think of making those "fake" timers like I use to do in B3D. All I had to do is take a quick look at your example; thanks tony :)

And for the rest of you that also contributed, thanks also. Although I still think I should take a break and come back later when I know more.