Animated Brushes 5

A little experiment with 'Animated Brushes'. There is one hidden 'leader' brush that animates around in a circle. There are 10 hidden 'wanderer' brushes that head towards the leader (most of the time). There are 100 other 'follower' brushes that pick a random wanderer and head towards its, occasionally changing wander mid journey.

Click to create a new set of follower brushes. The source (DirMX movie) is available here.

The main behaviour that drives the animation is as follows:

property myBuffer, myOutput, myPixel, myCanvasColour

property myBrushList, myWanderList, myLeader

on exitFrame me
  -- loop on the frame
  go to the frame
end

on beginSprite (me)
  -- create a reference to the stage's image
  myOutput = (the stage).image 
  -- create a 'buffer' image. The brushes will paint
  -- to this image 'offscreen'. When all the brushes
  -- have finished painting, then this buffer is 
  -- painted to the screen
  myBuffer = myOutput.duplicate()
  -- Create a little 'helper' pixel. Rather than filling
  -- the buffer with black each frame and then letting
  -- the brushes paint on it, this pixel will be copied 
  -- to the buffer with a lowish blend level (which means
  -- that the brush strokes will leave trails briefly)
  myPixel = image(1,1,myBuffer.depth)
  myPixel.setPixel(0,0,rgb(0,0,0))

  -- Create an empty list to store 'brush' objects in
  myBrushList = []
  myWanderList = []
  myLeader = script("Leader").new()
  myLeader.Initialise(myBuffer)
end



on enterframe (me)
  -- check if there are enough brushes. If not, then add more
  if myWanderList.count < 10 then me.AddWanderer()
  if myBrushList.count < 100 then me.AddBrush()
  -- fade out the last image that was painted 
  -- (lower blend levels reveal more of the previous image)
  myBuffer.copyPixels(myPixel, myBuffer.rect, myPixel.rect,[BlendLevel: 12])
  -- tell the brushes to paint themselves
  myLeader.Animate()
  call(#Animate, myWanderList, myLeader)
  -- Randomise(myBrushList)
  mx = myBrushList.count
  repeat with i = 1 to mx
    myBrushList[i].Animate(myWanderList, i)
  end repeat
  tmp = myBrushList[1]
  myBrushList.deleteAt(1)
  myBrushList.append(tmp)
  -- finally, copy the buffer image to the output (so it is visible)
  myOutput.copyPixels(myBuffer, myOutput.rect, myBuffer.rect)
end



on mouseDown (me)
  --if the doubleClick then 
  myBrushList.deleteAll()
  --end if
end



on AddWanderer (me)

  aBrush = script("wanderer").new()
  aBrush.Initialise(myBuffer)
  -- add this brush to the list
  myWanderList.add(aBrush)

end





on AddBrush (me)

  -- create a new brush object

  

  aBrush = script("follower").new()

  -- initialise it by passing in a reference to the buffer image

  aBrush.Initialise(myBuffer)

  -- add this brush to the list

  --  myBrushList.add(aBrush)

  if myWanderList.count then

    myBrushList.addAt(random(myWanderList.count), aBrush)

  else

    myBrushList[1] = aBrush

  end if

  

end
First published 21/05/2005