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