electronslibres.ca ça mute avec l'AS3

29Jan/100

What a wonderfull world

I was surfing on the web last week when I found a map of the world drawn with separated pixels.
It was static jpeg, and I thought, hey why not draw this dynamically, and animate it on mouse over ?

This my first script really using flash player 10. In fact I am using the vector class which is a top level class inside flash player 10. The properties and methods of a Vector object are similar — in most cases identical — to the properties and methods of an Array. In any case where you would use an Array in which all the elements have the same data type, a Vector instance is preferable. It will (and should though I did not test it) increase the speed and optimize the data you are working with.

I first found a map in two colours : grey and white:

And here is the commented code to guide you trough all the steps:

// output bitmapData
private var _map:BitmapData;
 
// vector objects = typed arrays
private var _pts:Vector.<Point> = new Vector.<Point>();
private var _origin:Vector.<Point> = new Vector.<Point>();
 
// width and height of the map
public static const HEIGHT:int = 272;
public static const WIDTH:int = 500;
 
// a reference to the lenght of our vector
private var points_nb:int;
 
public function PixelMap()
{
	addEventListener(Event.ADDED_TO_STAGE , _init );
}
 
private function _init(e:Event = null):void
{
	removeEventListener(Event.ADDED_TO_STAGE , _init );
	stage.quality = "medium";
 
	// create an instance of Map object embed inside the library
	var map:Map = new Map(WIDTH, HEIGHT);
 
	// Draw map inside temp BitmapData
	var temp:BitmapData = new BitmapData(WIDTH, HEIGHT, false, 0x0);
	temp.draw(map);
 
	// fill our _map bitmapData with black ,
	// dimenseions ares the size of the stage = Map size
	_map = new BitmapData(WIDTH, HEIGHT, true, 0x00000000);
 
	// define the step to pick the pixels
	var margin:int = 3;
	var iy:int;
	var ix:int;
 
	// loop inside temp BitmapData for every one out of three pixels
	// if this pixel is not white, draw one black point inside our _map instance
	for(iy = 0; iy &lt; HEIGHT; iy += margin)
	{
		for(ix = 0; ix &lt; WIDTH; ix += margin)
		{
			// if the color being returned is not white
			if(temp.getPixel32(ix,iy) != 0xFFFFFFFF)
			{
				//color the pixel at positions ix, iy
				// with white in the _map bitmapData instance
				_map.setPixel32(ix, iy, 0xFFFFFFFF);
 
				// get a random position for each white pixels
				_pts.push(new Point(Math.random() * 500,Math.random() * 272));
 
				// keep a reference to the original
				// position of the pixel inside a Vector instance
				_origin.push(new Point(ix,iy));
			}
		}
	}
 
	// a reference to the length of
	// our vector instance
	points_nb = _pts.length;
 
	// create a new bitmap
	// with the newly organized _map bitmapData
	addChild(new Bitmap(_map));
 
	// add animation
	addEventListener(Event.ENTER_FRAME , _update );
}
 
private function _update(e:Event):void
{
	// mouse X & Y positions
	var __x:int = mouseX;
	var __y:int = mouseY;
	var i:int = 0;
 
	// reference to the point we are moving
	// it is drawn inside the _map bitmapData
	var p :Point;
 
	// reference the same point
	// with the originals x & y coordinates
	var o :Point;
 
	// vars to store the temp x & y
	var px:int;
	var py:int;
	var ox:int;
	var oy:int;
	var prox:int;
 
	var dify:int;
	var difx:int;
 
	// loop inside the vector's instance which stores all our points
	while(i &lt; points_nb)
	{
		// reference the pixel we are playing with
		p = _pts[int(i)];
		o = _origin[int(i)];
 
		// store its x & y coordinates
		px = p.x;
		py = p.y;
 
		// get the originals x & y coordinates of the point
		ox = o.x;
		oy = o.y;
 
		// how far is the point from the mouse position?
		prox = Math.sqrt((__x - px) * (__x - px) + (__y - py) * (__y - py));
 
		// if distance between the mouse and the point
		// is less than 12 pixels
		if(prox &lt;= 12)
		{
			// change this point's color to black
			_map.setPixel32(px, py, 0x000000);
 
			// calculate the new random coordinates for that point
			// this is where we want to move the pixel
			px = px + Math.round(Math.random() * 60 - 30);
			py = py + Math.round(Math.random() * 60 - 30);
 
			// color the point at the new coordinates in white
			_map.setPixel32(px, py, 0xFFFFFFFF);
 
			// store the new coordinates inside the point instance
			// which is stored inside the vector's instance
			p.x = px;
			p.y = py;
 
		}
		else
		{
			// if the point's position we are looking at
			// is different from its original one
			if(p != o)
			{
				// calculates the distance between
				// the origine and the current position
				difx = px - ox;
				dify = py - oy;
 
				// change the point's color to black
				_map.setPixel32(px, py, 0x000000);
 
				// if the point is closer than 1 pixel, then use the original coordinates,
				// else ease back the point to its inital position
				difx &lt; 1 ? px = ox : px = px - difx * 0.1 ;
				dify &lt; 1 ? py = oy : py = py - dify * 0.1 ;
 
				// color the point at the new position
				_map.setPixel32(px, py, 0xFFFFFFFF);
 
				// and store the new point's position inside the vector's instance
				p.x = px;
				p.y = py;
			}
		}
 
		// increase i to loop inside the vector's instance
		i++;
	}
}