Animated Behaviors
Interactive Multimedia :: Automatic Animation Examples
"automatic animation" is the control of animation from lingo. this can refer to any and all sprite properties, and is used to make behaviors for objects that either simulate real-world physical motion (bouncing, gravity, friction, etc) or that have some form of intelligence (following the the mouse or other objects, for instance).
Core ideas:
* exitframe handlers for sprite behaviors. use these to make behaviors that will run constantly, moving the sprites they're attached to every frame.
* spritenum. put "property spritenum" at the beginning of any behavior script, and the behavior will know which sprite it has been attached to by saying "sprite(spritenum)" instead of "sprite(1)" or "sprite(15)".
* \dd or subtract a small amount repeatedly onto a sprite property to animate it.
* vector motion (velocity): store the 'amount to change' in a property variable, so you can easily do things like speed up, slow down, change directions, etc.
* boundary conditions: check the limits of sprite property values and alter the properties and/or the velocities to keep things in range.
Example Behavior Scripts:
each of these is a standalone behavior. because they use the spritenum property, they can be used on any sprites, or on multiple sprites at the same time.
--
follow mouse behavior
--
drag this behavior onto a sprite
--
it will make that sprite follow the mouse
--
around the stage. it can go onto
any sprite,
--
because it uses the spritenum property.
--
it uses the exitframe handler to run constantly.
property spritenum
on exitframe
sprite(spritenum).loch = the mouseh
sprite(spritenum).locv = the mousev
end
to improve this behavior, add the line
cursor 200
which will hide the cursor so all you see is the sprite.
Auto-Animating
--
generic auto-animation structure
property spritenum
on exitframe
-- 1. get
current property values
-- 2.
calculate new values
-- 3. set
sprite properties to new values
end
----------------------------------------
--
behavior to make a sprite move
--
across the stage. change the
amounts
--
added to x and y to go in different directions.
--
use negative numbers to go up or left.
property spritenum
on exitframe
-- get
current location
x = sprite(spritenum).loch
y = sprite(spritenum).locv
--
calculate new location
x2 = x
+ 2
y2 = y
+ 1
-- set
sprite properties to new location
sprite(spritenum).loch = x2
sprite(spritenum).locv = y2
end
----------------------------------------
--
move across stage behavior
--
written in a more concise way.
property spritenum
on exitframe
-- set a
variable to refer to the sprite,
-- which
saves some typing later.
s = sprite(spritenum)
x = s.loch
y = s.locv
x2 = x
+ 2
y2 = y
+ 1
s.loch
= x2
s.locv
= y2
end
--
constant rotation behavior
--
makes a sprite rotate all the time.
property spritenum
on exitframe
r = sprite(spritenum).rotation
r2 = r + 1
sprite(spritenum).rotation = r2
end
-- random
position
property spritenum
on exitframe
sprite(spritenum).loch = random(320)
sprite(spritenum).locv = random(240)
end
--
random walk
--
instead of moving to a random position,
--
move BY a random amount instead.
--
this will mostly make it walk down and to the right,
--
because the random amounts are always positive.
property spritenum
on exitframe
-- get
current sprite properties
x = sprite(spritenum).loch
y = sprite(spritenum).locv
-- random
distance for x and y
dx = random(10)
dy = random(10)
-- add
distance to get new position
x2 = x
+ dx
y2 = y
+ dy
-- change
sprite properties
sprite(spritenum).loch = x2
sprite(spritenum).locv = y2
end
Change the random lines like so to add left and up movement:
-- random distance for x and y,
-- from -4
to 5
dx = random(10) - 5
dy = random(10) - 5
--
move across the stage,
--
until you hit the right ege.
--
move back to the left edge.
property spritenum
on exitframe
x = sprite(spritenum).loch
x2 = x
+ 2
-- if you
hit the right edge,
-- go back
to the left
if x2 > 320 then x2 = 0
sprite(spritenum).loch = x2
end
To do this with vertical movement, add commands to increment y; check if it's over 240; and set y back to 0 if it is.
----------------------------------------
--
random walk with wrap-around
property spritenum
on exitframe
-- get
current sprite properties
x = sprite(spritenum).loch
y = sprite(spritenum).locv
-- random
distance for x and y,
dx = random(20) - 10
dy = random(20) - 10
-- add
distance to get new position
x2 = x
+ dx
y2 = y
+ dy
-- check
boundaries
if x2 > 320 then x2 = 320
if x2 < 0 then x2 = 0
if y2 > 240 then y2 = 240
if y2 < 0 then y2 = 0
-- change
sprite properties
sprite(spritenum).loch
= x2
sprite(spritenum).locv = y2
end
Bouncing
to make a sprite bounce, you need to keep its velocity as a property.
then, if it hits the wall, multiply the velocity times -1. this will make it go backwards, but at the same speed it was going before.
Use a beginsprite handler to set the initial velocity. beginsprite gets called once, when the sprite first appears on the stage - it's good for doing things like initializing variables that a behavior is going to use.
--
bounce up down
property spritenum
property dy
on beginsprite
dy = 2
end
on exitframe
-- get
current sprite properties
y = sprite(spritenum).locv
-- add
distance to get new position
y2 = y
+ dy
-- check
boundaries
-- if you
hit the top or bottom then
-- reverse
direction.
if y2 > 240 then dy=-dy
if y2 < 0 then dy=-dy
-- change
sprite properties
sprite(spritenum).locv = y2
end
--
bounce against all 4 walls
property spritenum
property dx,dy
on beginsprite
dx = 2
dy = 3
end
on exitframe
-- get
current sprite properties
x = sprite(spritenum).loch
y = sprite(spritenum).locv
-- add
distance to get new position
x2 = x
+ dx
y2 = y
+ dy
-- check
boundaries
-- if you
hit the top or bottom then
-- reverse
direction.
if x2 > 320 then dx=-dx
if x2 < 0 then dx=-dx
if y2 > 240 then dy=-dy
if y2 < 0 then dy=-dy
-- change
sprite properties
sprite(spritenum).loch = x2
sprite(spritenum).locv = y2
end
Bouncing with Friction
--
move x/y with friction
--
try different starting velocities
--
and different friction values.
property spritenum
property dx,dy
on beginsprite
dx = 2.0
dy = 3.0
end
on exitframe
-- get
current sprite properties
x = sprite(spritenum).loch
y = sprite(spritenum).locv
-- multiply
dx and dy by a number
-- just
less than 1.0 to make friction.
dx = dx *
.99
dy = dy *
.99
-- add
distance to get new position
x2 = x
+ dx
y2 = y
+ dy
-- check
boundaries
-- if you
hit the top or bottom then
-- reverse
direction.
if x2 > 320 then dx=-dx
if x2 < 0 then dx=-dx
if y2 > 240 then dy=-dy
if y2 < 0 then dy=-dy
-- change
sprite properties
sprite(spritenum).loch = x2
sprite(spritenum).locv = y2
end
Bouncing with Gravity
--
bounce up down with gravity
--
add gravity to the y velocity
--
to make the sprite accelerate
--
towards the bottom of the stage.
property spritenum
property dy
on beginsprite
dy = 0
end
on exitframe
-- get
current sprite properties
y = sprite(spritenum).locv
-- add
gravity
dy = dy + 1
-- add
distance to get new position
y2 = y
+ dy
-- check
boundaries
-- if you
hit the top or bottom then
-- reverse direction.
if y2 > 240 then dy=-dy
if y2 < 0 then dy=-dy
sprite(spritenum).locv = y2
end
To avoid
getting stuck in the ground, modify the if/then statements to do
"takeback":
if y2 >
240 then
dy=-dy
y2 = 240-- takeback: don't let y2 go
over the boundary.
end
if
To make the ball slow down, add friction when it hits the ground:
if y2 >
240 then
dy = -dy -- reverse direction
dy = dy * .95 -- slow down a
little bit
y2 = 240-- takeback: don't let y2 go
over the boundary.
end
if
--
random movement on mouseenter
on mouseenter
dx = random
(20) - 10
dy = random
(20) - 10
end
on exitframe
x = sprite(spritenum).loch
y = sprite(spritenum).locv
-- multiply
dx and dy by a number
-- just
less than 1.0 to make friction.
dx = dx *
.99
dy = dy *
.99
-- add
distance to get new position
x2 = x
+ dx
y2 = y
+ dy
-- check
boundaries
-- if you
hit the top or bottom then
-- reverse
direction and constrain to
-- the
edges.
if x2 > 320 then
dx = -dx
x2 = 320
end if
if x2 < 0 then
dx = -dx
x2 = 9
end if
if y2 > 240 then
dy = -dy
y2 = 240
end if
if y2 < 0 then
dy = -dy
y2 = 0
end if
sprite(spritenum).loch = x2
sprite(spritenum).locv = y2
end
Moving Towards Things (like the mouse)
--
move towards mouse behavior
property spritenum
on exitframe
-- get
current location
x = sprite(spritenum).loch
y = sprite(spritenum).locv
-- if
sprite is to the left of the mouse,
-- move to
the right. if it's to the right,
-- then
move to the left.
if x < the mouseh then x = x + 1
else if x > the mouseh then x = x - 1
if y < the mousev then y = y + 1
else if y > the mousev then y = y -1
sprite(spritenum).loch = x
sprite(spritenum).locv = y
end
--
move towards mouse with proportional speed
property spritenum
on exitframe
-- get
current location
x = sprite(spritenum).loch
y = sprite(spritenum).locv
-- get the
target location
xtarget = the mouseh
ytarget =
the mousev
-- get the
distance between them
xdistance = xtarget - x
ydistance = ytarget - y
-- move
amount is 1/10 the distance
xmove = xdistance / 10.0
ymove = ydistance / 10.0
--
calculate new position
x2 = x
+ xmove
y2 = y
+ ymove
sprite(spritenum).loch = x2
sprite(spritenum).locv = y2
end
--
spring simulation
--
swings back and forth across the
--
center of the stage
property spritenum
property dx
on exitframe
-- get
current location
x = sprite(spritenum).loch
-- if on
the right side, accelerate towards the left
if x > 160 then dx = dx - 1
-- if on
the left side, accelerate towards the right
if x < 160 then dx = dx + 1
-- get new
position
x2 = x
+ dx
-- set sprite
property
sprite(spritenum).loch = x2
end
--
spring simulation with friction
--
and center trap
property spritenum
property dx
on exitframe
-- get
current location
x = sprite(spritenum).loch
-- only
change if more than 5 pixels
-- to the
left or right.
if x > 165 then dx = dx - 1
if x < 155 then dx = dx + 1
-- friction
dx = dx *
.95
-- get new
position
x2 = x
+ dx
-- set
sprite property
sprite(spritenum).loch = x2
end