Displaying an AnimImage

BlitzMax Forums/BlitzMax Beginners Area/Displaying an AnimImage

Arabia(Posted 2011) [#1]
Hope this isn't a dumb question.

I've got an AnimImage I want to display - it's just a converted Animated GIF - so it just loops over an over. I know how to do this fine.

The question is, how do I have this animimage continue to display while my other parts of the program are working? e.g. I'm going to be displaying the image on the screen while the use does other things with the mouse etc.

I can see a couple of problems. The animimage code I've written has a delay of 70 millsecs between frames - this will slow down everything else won't it?

I know I can put the code to animate the image in the main loop for what I'm doing, I just think that maybe this is not the right way to go about it.

I've asked a similar sort of question before, and was pointed towards Delta timing but I don't think this applies to what I'm doing here.


degac(Posted 2011) [#2]
If I understood correctly your question.. here a pseudo base code about a main loop (the While..Wend block) and the animation

'pseudo code


Global myImge:TImage=LoadAnimImage("animation.png",32,32,0,15)
Global frame_timer:Int,frame_start:Int=0, frame_finish:Int=15, frame_duration:Int=125,frame_current:Int=0

Const GAME_RUN:Int=1	

While GAME_RUN=1

	DrawAnim()
	DoSomethingElse()

Wend

Function DrawAnim()

	DrawImage myImage,10,10,frame_current
	
	If MilliSecs()>frame_timer+frame_duration
		frame_current:+1	
		If frame_current>frame_finish frame_current=frame_start
		frame_timer=MilliSecs()
	End If

End Function



You could use a timer to 'share' what work the program should do, but this depens on what you are writing.
Of course the function DoSomethingElse() is generic: I dont' know what else you want to do in the main loop.

Cheers

Last edited 2011


xlsior(Posted 2011) [#3]
The animimage code I've written has a delay of 70 millsecs between frames - this will slow down everything else won't it?


Yup, it will.

In order for the image to remain animated, you're drawimage routines need to be inside of your main program loop. Then each loop you determine which frame to draw, before you take off and do other things.

You don't need delay to draw images at the proper speed, though -- I've used something like this myself:

DrawImage (sprite,x,y,int((MilliSecs()/(refreshrate*speedadjust)) Mod 4))


- Millisecs() is a blitzmax function that contains an ever increasing timer.
- Refreshrate is a variable that I used to store the current refreshrate, to help keep the animation speed constant. In most cases it will contain '60'.
- speedadjust is a floating point variable that is used as a modifier to adjust the speed of the animation (speed it up or slow it down). I use 1.2 in my current game.
- the 'Mod 4' divides the number by 4, and contains the remainder.
- the resulting number is a float, so I'm using int() to convert it to an integer that indicates the actual frame to pick.

All together, the above returns a recurring sequence of 0,1,2,3,0,1,2,3,0,1,2,3,etc. as time progresses at a steady rate.

If it's too fast or slow, tweak the 'speedadjust' float to be higher or lower, and the animation rate will speed up or slow down.

I this formula myself to determine which frame of the animation to draw at any given time. Since the sequence automatically wraps and repeats, it happens at a steady pace, while never having to worry about keeping track of the previous frame and how much time has actually passed. It's worked very well for me...
No need for a delay or wait, the program will draw your sprite every single loop, and automatically switch to the next frame when the time is right.


Another note: I've also used the above to account for sprite rotation: different anim sequences for left, right, up, down, all stored in a single animimage strip.

left = 0-3
right = 4-7
up = 8-11
down= 12-15

keep track of the current 'direction' in a different variable:

if direction=left then startframe=0
elseif direction=right then startframe=4
elseif direction=up then startframe=8
elseif direction=down then startframe=12
end if

and use:
DrawImage (sprite,x,y,int((MilliSecs()/(refreshrate*speedadjust)) Mod 4)+startframe)


That way changing direction will use the appropriate sequence of images, without a whole lot of work.

Last edited 2011


xlsior(Posted 2011) [#4]
Note: adjust 'mod 4' portion accordingly for the number of frames your animation has. If you have 10 frames (0-9), then use 'mod 10' in its place.


Arabia(Posted 2011) [#5]
@degac & @xlsior - it didn't even occur to me to use Millisecs() instead of using Delay(). I especially like your DrawImage example Xlsior - cheers.

That will do the trick for what I'm trying to do in this portion of the program.

Excellent and quick response in the forums as usual :)