Global / Local Animation
This example takes a look a two ways of solving a simple animation problem. The program draws a screen full of characters running one of two animation sequences (the anims are just a sequence of numbers).
In the first example, each character has a position and animation settings. Those settings being, the current frame (from the set) and the max number of frames this set contains. So each character in the list has it's own local animation settings, which need to the bumped each update. So if we have a 1000 characters, then this small process is being executed 1000 times.
Local Animation Version
[pbcode]
loadfont "arial",1,18
loadfont "arial",2,32
// Make a series of images as our animation
Dim AnimFrames(32)
For lp=0 to GetArrayElements(AnimFrames())
Img=NewImage(32,32,2)
rendertoimage img
text 0,0,str$(lp)
AnimFrames(lp)=img
Next
rendertoscreen
Type tObject
x#,y# ; final screen position
CurrentFrame
Maxframes
EndType
Dim o as tObject list
MaxObjects=1000
For lp=0 to MaxObjects
o=new tObject
o.x =rnd(getscreenwidth())
o.y =rnd(getscreenheight())
if lp<(MaxObjects/2)
o.maxframes =32
else
o.maxframes =16
endif
next
setfont 2
ink $ffff0000
Do
Cls
frames++
// update the animation logic for each object
t=timer()
For each o()
o.CurrentFrame=mod(o.CurrentFrame+1,o.maxframes)
next
tt1#+=timer()-t
// Draw them loop, so we split processing time
// from the drawing time
t=timer()
lockbuffer
For each o()
drawimage animframes(o.currentframe),o.x,o.y,true
next
unlockbuffer
tt2#+=timer()-t
print "Anim Time:"+Str$(tt1#/frames)
print "Anim Time:"+Str$(tt2#/frames)
print fps()
Sync
loop
[/pbcode]
Global Animation Version
In this version, we're breaking the animation data out of the character structure and making them into a unique animations array. Now rather than each character manually updating it's local animation settings, it's just pulling the current frame from the pre-calculated global animation array. So rather than calculating a result multiple times, we're calculating the answer once and then reusing it multiple times. A simple logical shift, that can be very useful when tweaking your programs performance.
[pbcode]
loadfont "arial",1,18
loadfont "arial",2,32
// Make a series of images as our animation
Dim AnimFrames(32)
For lp=0 to GetArrayElements(AnimFrames())
Img=NewImage(32,32,2)
rendertoimage img
text 0,0,str$(lp)
AnimFrames(lp)=img
Next
rendertoscreen
Type tAnim
CurrentFrame
Maxframes
Endtype
Dim GlobalAnims(2) as tAnim
GlobalAnims(1) = nEw tAnim
GlobalAnims(1).CurrentFrame=0
GlobalAnims(1).MaxFrames=32
GlobalAnims(2) = nEw tAnim
GlobalAnims(2).CurrentFrame=0
GlobalAnims(2).MaxFrames=16
Type tObject
x#,y# ; final screen position
anim
EndType
Dim o as tObject list
MaxObjects=1000
For lp=0 to MaxObjects
o=new tObject
o.x =rnd(getscreenwidth())
o.y =rnd(getscreenheight())
if lp<(MaxObjects/2)
o.anim=1 ;32 frame anim
else
o.anim=2 ;16 frame anim
endif
next
setfont 2
ink $ffff0000
Do
Cls
frames++
// update the unique animations
t=timer()
for lp=1 to getarrayelements(GlobalAnims())
CurrentFrame=GlobalAnims(lp).CurrentFrame+1
GlobalAnims(lp).CurrentFrame=mod(CurrentFrame+1,GlobalAnims(lp).maxframes)
next
tt1#+=timer()-t
// Draw them loop, so we split processing time
// from the drawing time
t=timer()
lockbuffer
For each o()
ThisAnim=o.Anim
drawimage animframes(GlobalAnims(ThisAnim).CurrentFrame),o.x,o.y,true
next
unlockbuffer
tt2#+=timer()-t
print "Anim Time:"+Str$(tt1#/frames)
print "Anim Time:"+Str$(tt2#/frames)
print fps()
Sync
loop
[/pbcode]
You can apply this seemingly simple concept to not only animation frames, but calculations also, we often just need to turn the problem upside down ..
Want to learn more about program optimization -> A Crash Course In Optimization (http://www.underwaredesign.com/forums/index.php?topic=2548.0)