In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: Iosmetric projection

...
@author Motoki Matsumoto
Get Adobe Flash player
by mtok 12 Oct 2009
/**
 * Copyright mtok ( http://wonderfl.net/user/mtok )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/6OLg
 */

package  
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Vector3D;
	import flash.filters.GlowFilter;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	/**
	 * ...
	 * @author Motoki Matsumoto
	 */
	public class IsometricWorldTest extends Sprite
	{
		private var _world:IsometricWorld;
		private var _size:Number = 20;
		private var _currentObj:IsometricObject;
		private var _dt:Number;
		public function IsometricWorldTest() 
		{
			addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
		}
		
		private function addedToStageHandler(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
			init();
		}
		private function init():void {
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			_world = buildWorld();
			_world.x = stage.stageWidth * 0.5;
			_world.y = 30;
			//_world.y = stage.stageHeight * 0.5;
			addChild(_world);
			_world.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			_world.addEventListener(MouseEvent.CLICK, clickHandler);
			_world.zsort();
			
			_dt = 1 / stage.frameRate;
			stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
			stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
			
		}
		
		private function clickHandler(e:MouseEvent):void 
		{
			var box:IsometricBox = e.target as IsometricBox;
			var v:Vector3D;
			if (box) {
				v = new Vector3D(
					100 * Math.random() - 50,
					0,
					100 * Math.random() - 50);
				box.velocity = v;
			}
		}
		
		private function keyUpHandler(e:KeyboardEvent):void 
		{
			if (_currentObj) {
				_currentObj.velocity = new Vector3D(0, 0, 0);
			}
		}
		
		private function keyDownHandler(e:KeyboardEvent):void 
		{
			if (_currentObj) {
				switch(e.keyCode) {
				case Keyboard.LEFT:
					_currentObj.velocity = _currentObj.velocity.add(new Vector3D( 0, 0, 1));
					break;
				case Keyboard.RIGHT:
					_currentObj.velocity = _currentObj.velocity.add(new Vector3D( 0, 0, -1));
					break;
				case Keyboard.UP:
					_currentObj.velocity = _currentObj.velocity.add(new Vector3D(-1, 0, 0));
					break;
				case Keyboard.DOWN:
					_currentObj.velocity = _currentObj.velocity.add(new Vector3D(1, 0, 0));
					break;
				}
			}
		}
		
		private function enterFrameHandler(e:Event):void 
		{
			_world.step(_dt);
		}
		
		private function mouseDownHandler(e:MouseEvent):void 
		{
			var box:IsometricBox;
			box = e.target as IsometricBox;
			if (box) {
				if (_currentObj != null) {
					_currentObj.filters = [];
				}
				box.filters = [new GlowFilter(0x00ffff, 1, 4, 4)];
				_currentObj = box;
			}
		}
		
		private function buildWorld():IsometricWorld {
			var iw:IsometricWorld = new IsometricWorld();
			var floor:IsometricFloor;
			var s:int = _size;
			
			for (var i:int = 0; i < 15; i++) {
				for ( var j:int = 0; j < 15; j++) {
					floor = new IsometricFloor(s);
					floor.position = new Vector3D(i * s, 0, j * s);
					iw.addChildObj(floor);
				}
			}
			
			var box:IsometricBox;
			
			box = new IsometricBox(s, 0xff0000);
			box.x = s * 3;
			box.z = s * 3;
			box.height = s * 2 / Math.sqrt(3);
			iw.addChildObj(box);

			box = new IsometricBox(s, 0x00ff00);
			box.x = s * 2;
			box.z = s * 2;
			box.height = s * 2 / Math.sqrt(3);
			iw.addChildObj(box);
			
			box = new IsometricBox(s, 0x0000ff);
			box.x = s * 1;
			box.z = s * 1;
			box.height = s * 2 / Math.sqrt(3);
			iw.addChildObj(box);
			
			return iw;
		}
	}
}

import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.display.Graphics;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.geom.Vector3D;
import flash.geom.Point;

class IsometricWorld extends Sprite {
	private var _floor:Sprite;
	private var _world:Sprite;
	private var _gravity:Number = 2;
	private var _sortBuffer:Vector.<IsometricObject>;
	private var _boundary:Rectangle;
	
	public function IsometricWorld() {
		super();
		addChild(_floor = new Sprite());
		addChild(_world = new Sprite());
		_sortBuffer = new Vector.<IsometricObject>();
	}
	public function addChildObj(child:IsometricObject):IsometricObject 
	{
		if ( child is IsometricFloor) {
			_floor.addChild(child);
		}else {
			_world.addChild(child);
			_sortBuffer.push(child);
		}
		
		return child;
	}
	public function step(dt:Number):void {
		var i:int;
		var len:int = _world.numChildren;
		var isoObj:IsometricObject;
		var bounce:Number = -0.8;
		var maxX:Number = 280;
		var minX:Number = 0;
		var maxZ:Number = 280;
		var minZ:Number = 0;
		for ( i = 0; i < len; i++) {
			isoObj = _world.getChildAt(i) as IsometricObject;
			isoObj.velocity.y += _gravity;
			isoObj.step(dt);
		
			if (isoObj.x > maxX) {
				isoObj.x = maxX;
				isoObj.velocity.x *= bounce;
			} else if (isoObj.x < minX) {
				isoObj.y = minX;
				isoObj.velocity.x *= bounce;
			}
			
			if ( isoObj.z > maxZ) {
				isoObj.z = maxZ;
				isoObj.velocity.z *= bounce;
			}else if (isoObj.z < minZ) {
				isoObj.z = minZ;
				isoObj.velocity.z *= bounce;
			}
			if ( isoObj.y > 0) {
				isoObj.y = 0;
				isoObj.velocity.y *= bounce;
			}
		}
		
		
		zsort();
	}
	public function zsort():void {
		_sortBuffer = _sortBuffer.sort(
			function(a:IsometricObject, b:IsometricObject):Number {
				return a.depth - b.depth;
			});
		
		var len:int = _sortBuffer.length;
		for (var i:int = 0; i < len; i++) {
			_world.setChildIndex(_sortBuffer[i], i);
		}
	}
}

class IsometricObject extends Sprite {
	private var _position:Vector3D;
	private var _velocity:Vector3D;
	private var _maxSpeed:Number;
	private var _friction:Number = 1;
	private var _bInvalidDisplay:Boolean;
	private var _bInvalidPosition:Boolean;
	private var _depth:Number;

	public function IsometricObject() {
		_position = new Vector3D();
		_velocity = new Vector3D();
		addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
	}
	
	private function addedToStageHandler(e:Event):void 
	{
		removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
		addEventListener(Event.RENDER, renderHandler);
		_draw();		
		_updateScreenPosition();
	}
	
	private function renderHandler(e:Event):void 
	{
		if (_bInvalidDisplay) {
			_draw();
		}
		if (_bInvalidPosition) {
			_updateScreenPosition();
		}
	}
	protected function invalidateDisplay():void {
		_bInvalidDisplay = true;
		if(stage) stage.invalidate();
	}
	protected function invalidatePosition():void {
		_bInvalidPosition = true;
		if(stage) stage.invalidate();
	}
	protected function _draw():void { }
	public function step(dt:Number):void {
		var v:Vector3D = _velocity.clone();
		v.scaleBy(dt);
		position = _position.add(v);

		_velocity.scaleBy(_friction);
	}
	protected function _updateScreenPosition():void {
		var p:Vector3D = IsoUtils.isoToScreen(_position);
		super.x = p.x;
		super.y = p.y;
		_depth = p.z;
		if(stage) stage.invalidate();
	}
	override public function get x():Number { return _position.x; }
	override public function set x(value:Number):void 
	{
		_position.x = value;
		_updateScreenPosition();
	};
	override public function get y():Number { return _position.y; }
	override public function set y(value:Number):void 
	{
		_position.y = value;
		_updateScreenPosition();
	}
	override public function get z():Number { return _position.z; }
	override public function set z(value:Number):void 
	{
		_position.z = value;
		_updateScreenPosition();
	}
	public function get position():Vector3D { return _position; }
	public function set position(value:Vector3D):void 
	{
		_position = value;
		_updateScreenPosition();
	}
	
	public function get depth():Number { return _depth; }
	
	public function get velocity():Vector3D { return _velocity; }
	public function set velocity(value:Vector3D):void 
	{
		_velocity = value;
	}
	
	public function get vx():Number { return _velocity.x; }
	public function set vx(value:Number):void 
	{
		_velocity.x = value;
	}
	
	public function get vy():Number { return _velocity.y; }
	public function set vy(value:Number):void 
	{
		_velocity.y = value;
	}
	
	public function get vz():Number { return _velocity.z; }
	public function set vz(value:Number):void 
	{
		_velocity.z = value;
	}
}

class IsometricFloor extends IsometricObject {
	private var _size:Number;
	private var _color:uint;
	private var _walkable:Boolean = true;
	public function IsometricFloor(size:Number, color:uint = 0xcccccc) {
		_size = size;
		_color = color;
		super();
	}
	
	override protected function _draw():void 
	{
		var g:Graphics = graphics;
		g.lineStyle(1, 0, 0.8);
		g.beginFill(color, 0.5);
		g.moveTo( -_size, 0);
		g.lineTo(0, -_size * 0.5);
		g.lineTo(_size, 0);
		g.lineTo(0, _size * 0.5);
		g.lineTo( -_size, 0);
		g.endFill();
	}
	
	public function get size():Number { return _size; }
	public function set size(value:Number):void 
	{
		_size = value;
	}
	
	public function get color():uint { return _color; }
	public function set color(value:uint):void 
	{
		_color = value;
	}
	
	public function get walkable():Boolean { return _walkable; }
	public function set walkable(value:Boolean):void 
	{
		_walkable = value;
	}
}

class IsometricBox extends IsometricObject {
	private var _size:Number;
	private var _color:uint;
	private var _height:Number;
	private var _invalidDisplay:Boolean = true;
	public function IsometricBox(size:Number, color:uint=0xcccccc) {
		_size = size;
		_height = size;
		_color = color;
		super();
	}
	override protected function _draw():void 
	{
		var red:uint = _color >> 16;
		var green:uint = _color >> 8 & 0xff;
		var blue:uint = _color & 0xff;
		var c:uint;
		
		var g:Graphics = graphics;
		var h:Number = _height;
		var s:Number = _size;

		//left
		c = (red >> 1) << 16 | (green >> 1) << 8 | blue >> 1;
		g.beginFill(c);
		g.moveTo( -s, -h);
		g.lineTo(  0,  s * 0.5 - h);
		g.lineTo(  0,  s * 0.5);
		g.lineTo( -s, 0);
		g.lineTo( -s, -h);
		g.endFill();
		
		//right
		c = (red * 0.75) << 16 | (green * 0.75) << 8 | blue * 0.75;
		g.beginFill(c);
		g.moveTo( s, -h);
		g.lineTo( 0, s * 0.5 - h);
		g.lineTo( 0, s * 0.5);
		g.lineTo( s, 0);
		g.lineTo( s, -h);
		g.endFill();

		//top
		g.beginFill(color);
		g.moveTo(  -s, - h	 		);
		g.lineTo(	0, - h - s * 0.5);
		g.lineTo(   s, - h			);
		g.lineTo(	0, - h + s * 0.5);
		g.lineTo(  -s, - h 			);
		g.endFill();
	}
	
	public function get color():uint { return _color; }
	public function set color(value:uint):void 
	{
		_color = value;
		_invalidDisplay = true;
		if (stage != null) {
			stage.invalidate();
		}
	}
	
	public function get size():Number { return _size; }
	public function set size(value:Number):void 
	{
		_size = value;
		_invalidDisplay = true;
		if (stage != null) {
			stage.invalidate();
		}
	}
	
	override public function get height():Number { return _height; }
	override public function set height(value:Number):void 
	{
		_height = value;
		_invalidDisplay = true;
		if (stage != null) {
			stage.invalidate();
		}
	}
}

class IsoUtils {
	public static const Y_CORRECT:Number = Math.cos( -Math.PI / 6) * Math.SQRT2;
	private static const SQRT2_2:Number = Math.sqrt(2) * 0.5;
	private static const SQRT3_2:Number = Math.sqrt(3) * 0.5;
	public static function isoToScreen(pos:Vector3D):Vector3D {
		var screenX:Number = pos.x - pos.z;
		var screenY:Number = pos.y * Y_CORRECT + (pos.x + pos.z) * 0.5;
		var depth:Number = SQRT3_2 * (pos.x + pos.y) - SQRT2_2 * pos.y;
		return new Vector3D(screenX, screenY, depth);		
	}
	public static function screenToIso(point:Point):Vector3D {
		var xpos:Number = point.y + point.x * 0.5;
		var ypos:Number = 0;
		var zpos:Number = point.y - point.x * 0.5;
		return new Vector3D(xpos, ypos, zpos);
	}
}