Poetry In MotionMaking Large & Multilayered Animating AvatarsIn this example, we use ALARMEXEC and global functions to build custom animations. |
As of the Mac V1.1.3 Palace client, or Windows 1.1.6, you can have self-animating props you select a group of props with their "animate" or "palindrome" (aka "bounce") flags set, and off they go, pretty much lagless and automatic. If animation is what you want, the built-in animation scheme is clearly your first and prefered option 95% of the time.
However....
The avatar consists of a solid black heart made from two props,
surrounded by transparent flame made from four more props. There are
only three frames of animation, but that's 12 moving props and two
still props fourteen props all told. Even if you could get
that many props in the list (Palace only lets you have nine) they
wouldn't display correctly, since they overlap and only one could
change at a time.
For this custom animation, we use
three global variables (and an optional debugging flag called
"debugOn," easily removed), and a global function in the
ON SIGNON block...
burnInt GLOBAL burning GLOBAL burnCt GLOBAL 200 burnInt = ; delay in ticks FALSE burning = ; power switch 0 burnCt = ; frame counter ; burn animation loop for hot heart burn_it GLOBAL ; global function.... { burn_it GLOBAL ; declares itself! burnInt GLOBAL ; frame rate burning GLOBAL ; on/off toggle burnCt GLOBAL ; frame counter debugOn GLOBAL time GLOBAL ; alternative for DATETIME { { "Now Burning @ " time EXEC ITOA & " / " & burnCt ITOA & LOGMSG } debugOn IF burnCt 3 % bdx = { [ "hfl1_1" "hfl1_2" "hfl1_3" "hfl1_4" "hfl1_5" "hfl1_6" "ht_4" "ht_5" ] SETPROPS } bdx 0 == IF { [ "hfl2_1" "hfl2_2" "hfl2_3" "hfl2_4" "hfl2_5" "hfl2_6" "ht_4" "ht_5" ] SETPROPS } bdx 1 == IF { [ "hfl3_1" "hfl3_2" "hfl3_3" "hfl3_4" "hfl3_5" "hfl3_6" "ht_4" "ht_5" ] SETPROPS } bdx 2 == IF burnCt ++ { "Next burn @ " time EXEC burnInt + ITOA & LOGMSG } debugOn IF burn_it burnInt ALARMEXEC ; reschedule } { "Burn Has Stopped at " burnCt ITOA & LOGMSG } burning IFELSE } burn_it DEF ; end function def |
The trick here is to declare burn_it GLOBAL inside
the function itself, then have it reschedule itself over and
over, using ALARMEXEC each time it runs. It's not
really recursion, but it plays recursion on the internet.
We use our three global variables
to: turn the animation on and off (burning); keep
track of which frame is next (burnCt); and most
importantly when using this, to control the speed
(burnInt).
It's important to
remember that such an animation loop can become a burning lag machine.
Unlike built-in animation, it's calling the server for
changes at each and every frame change. So it's
important that your find an appropriate interval for
the animation frames an interval that may need
to get changed depending on how many people are around
at the time. The default shown here, 200 ticks, is just
over 3 seconds between frames. Depending on what sort
of tolerances you're willing to put up with, you
might be able to push it below 50.
Note too that any other operation
that changes the avatar appearance, such as macros, or the ";cost" or BotBot "np" commands, should also set
burning to zero (i.e., it should turn the animation
off).
Here's some OUTCHAT
code to turn this off and on on command. The global function
aps is described elsewhere. You
can call this by saying "burn" or "burn on" to
start animation, and "burn off" to stop it.
; fire costume { { 1 burning = 0 12 aps EXEC burn_it EXEC } { 0 burning = } "$1" GREPSUB "n" == CHATSTR "burn" == OR IFELSE ""CHATSTR = } CHATSTR "^burn o([nf])" GREPSTR CHATSTR "burn" == OR IF |