JLSA Logo

Dynamic Drawing

Posted in Inspiration on by James Penman

I was fooling about with the behavioral seeking code that drives the fishpond in our former Play section. I’ve just started dipping my toe into the drawing API of Actionscript 3.0 and was interested in having a line draw the path one of my fish would be swimming. The test worked out fine, so I followed through on the idea a little more and added fish, changed behaviors, and so on. I ultimately came up with a nifty random doodle drawing animation where one line wanders at random, another line seeks the wanderer, and then a third line seeks the second line (as pictured below). The topmost line I made the same color as the background so there’d be the illusion of negative space.

Dynamic Drawing Output Screenshot - Johnny Lightning Strikes Again

Screenshot of the dynamic drawing output

You can see the whole thing playing out real time right here. I’m using Keith Peters’ SteeredVehicle class to drive my lines. If you’re interested in how all of that works, please grab his book titled AdvancED Actionscript 3.0 Animation. All I did in my document class was instantiate 3 steered vehicles and invoked their seek() and wander() method (after tweaking some of their internal values a smidgen). I also adjust the line-style width every frame based on some simple conditions as you’ll see below.

//Please forgive any orphans lines of code in here.
//I was changing this document a lot during my prototyping
//efforts and tried to clean this up as best as I could.
 
package
{
	import com.foed.SteeredVehicle;
	import com.foed.Vector2D;
 
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
 
	import flash.events.Event;
 
	[SWF(backgroundColor=0x333333)]
 
	public class DynamicLine extends Sprite
	{
		private var _lineThickness = 20;
		private var _lineColor:Number = 0x125689;
		private var _vehicle:SteeredVehicle;
		private var _vehicle2:SteeredVehicle;
		private var _vehicle3:SteeredVehicle;
 
		private var _drawingSprite:Sprite;
		private var _drawing2:Sprite;
		private var _drawing3:Sprite;
		private var _widgetTimer:Timer;
 
		private var _decrease:Boolean = true;
 
		private var _maxWidth = 20;
		private var _widthChange = 0.02;
		private var _widthCounter:Number = _maxWidth;
 
		private var _line1Color:Number = 0x555555;
		private var _line2Color:Number = 0x777777;
		private var _line3Color:Number = 0x333333;
 
		public function DynamicLine()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
 
			_vehicle3 = new SteeredVehicle();
			addChild(_vehicle3);
			with (_vehicle3)
			{
				maxSpeed = 5;
				edgeBehavior = "bounce";
				position = new Vector2D(600, 400);
				visible = false;
			}
 
			_vehicle2 = new SteeredVehicle();
			addChild(_vehicle2);
			with (_vehicle2)
			{
				maxSpeed = 4;
				edgeBehavior = "bounce";
				position = new Vector2D(400, 300);
				visible = false;
			}
 
			_vehicle = new SteeredVehicle();
			addChild(_vehicle);
			with (_vehicle)
			{
				maxSpeed = 3;
				edgeBehavior = "bounce";
				position = new Vector2D(200, stage.stageHeight);
				_vehicle.visible = false;
			}
 
			_drawingSprite = new Sprite();
			addChild(_drawingSprite);
			_drawing2 = new Sprite();
			addChild(_drawing2);
			_drawing3 = new Sprite();
			addChild(_drawing3);
 
			_drawingSprite.graphics.moveTo(_vehicle.x, _vehicle.y);
			_drawing2.graphics.moveTo(_vehicle2.x, _vehicle2.y);
			_drawing3.graphics.moveTo(_vehicle3.x, _vehicle3.y);
 
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
 
		private function onEnterFrame(event:Event):void
		{
			if(_widthCounter > 1 && _decrease)
			{
				_widthCounter -= _widthChange;
			}
			else if(_widthCounter < _maxWidth)
			{
				_decrease = false;
				_widthCounter += _widthChange;
			}
			else
			{
				_decrease = true;
			}
 
			_drawingSprite.graphics.lineStyle(_widthCounter, _line1Color);
			_drawing2.graphics.lineStyle(_widthCounter, _line2Color);
			_drawing3.graphics.lineStyle(_widthCounter, _line3Color);
 
			_vehicle.seek(_vehicle2.position);
			_vehicle2.seek(_vehicle3.position);
			_vehicle3.wander();
 
			_drawingSprite.graphics.moveTo(_vehicle.x, _vehicle.y);
			_drawing2.graphics.moveTo(_vehicle2.x, _vehicle2.y);
			_drawing3.graphics.moveTo(_vehicle3.x, _vehicle3.y);
 
			_vehicle.update();
			_vehicle2.update();
			_vehicle3.update();
 
			_drawingSprite.graphics.lineTo(_vehicle.x, _vehicle.y);
			_drawing2.graphics.lineTo(_vehicle2.x, _vehicle2.y);
			_drawing3.graphics.lineTo(_vehicle3.x, _vehicle3.y);
		}
	}
}