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

tileset

finding surrounding tiles in a tileset
Get Adobe Flash player
by nicoptere 07 Feb 2011
    Embed
/**
 * Copyright nicoptere ( http://wonderfl.net/user/nicoptere )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/bRV8
 */

package  
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	
	public class Tileset extends Sprite 
	{
		private var colors:Vector.<int> = Vector.<int>([ 0xFFFFFF, 0, 0xFF0000, 0xFFCC00, 0x003399, 0x00AA33, 0x9900CC ]);
		private var tileset:Vector.<int>;
		private var tilesetWidth:int = 20;
		private var tilesetHeight:int;
		private var tileWidth:int = 465 / 20;
		private var tileHeight:int = 465 / 20;
		
		public function Tileset() 
		{
			tileset = Vector.<int>( [
										1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
										1, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
										1, 0, 2, 2, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
										1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 1,
										1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1,
										1, 1, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 1,
										1, 1, 0, 0, 0, 0, 5, 0, 0, 0, 3, 3, 0, 3, 4, 0, 0, 0, 0, 1,
										1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4, 0, 0, 0, 0, 1,
										1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 4, 0, 0, 0, 0, 0, 1,
										1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 1,
										1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 4, 0, 4, 4, 4, 1,
										1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 4, 4, 4, 1,
										1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 1,
										1, 0, 0, 0, 0, 0, 5, 5, 5, 4, 0, 4, 0, 4, 0, 0, 0, 0, 0, 1,
										1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 1,
										1, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 1,
										1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 1,
										1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
										1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
										1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
									] );
			
			tilesetHeight = tileset.length / tilesetWidth;
			
			addEventListener( Event.ENTER_FRAME, checkMoves );
			
		}
		
		private function checkMoves(e:Event):void 
		{
			graphics.clear();
			
			render( tileset );
			
			var connexity:int = 4;// 4 | 8
			var maxDepth:int = 5;
			
			var validMoves:Vector.<Vector.<int>> = possibleMoves( mouseX / tileWidth, mouseY / tileHeight, tileset, maxDepth, connexity );
			if ( validMoves != null )
			{
				var i:int, p:Point;
				for each( var v:Vector.<int> in validMoves )
				{
					graphics.beginFill( colors[ colors.length - 1 ], .2 );
					for each( i in v )
					{
						p = IndexToPoint( i );
						graphics.drawRect( p.x * tileWidth, p.y * tileHeight, tileWidth, tileHeight );
					}
				}
			}
		}
		
		private function possibleMoves( posX:Number, posY:Number, tileset:Vector.<int>, maxDepth:int = 1, connexity:int = 4 ):Vector.<Vector.<int>>
		{
			var i:int = pointToIndex( new Point( posX, posY ) );
			
			if ( !tileset[ i ] )//if the first tile is walkable
			{
				
				var valid:Vector.<Vector.<int>> = new Vector.<Vector.<int>>();
				valid.push( Vector.<int>( [ i ] ) );
				
				var tilesetClone:Vector.<int> = tileset.concat();
				var max:int = ( maxDepth * maxDepth );
				if( maxDepth % 2 == 0 )max--;
				recursiveCheck( valid, tilesetClone, 0, max, connexity );
				
				return valid;
				
			}
			return null;
		}
		
		private function recursiveCheck( valid:Vector.<Vector.<int>>, tileset:Vector.<int>, depth:int = 0, maxDepth:int = 1, connexity:int = 4 ):void
		{
			if ( depth == maxDepth )
			{
				return;
			}
			else
			{
				try
				{
					for each( var i:int in valid[ depth ] )
					{
						valid.push( checkSlot( IndexToPoint( i ), tileset, connexity ) );
					}
					recursiveCheck( valid, tileset, ++depth, maxDepth, connexity )
				}
				catch ( err:Error ){return;}
			}
		}
		
		private function checkSlot( p:Point, tileset:Vector.<int>, connexity:int = 4 ):Vector.<int>
		{
			var i:int;
			var tiles:Vector.<int> = new Vector.<int>();
			
			i = pointToIndex( new Point( p.x - 1, p.y ) );//left
			if ( !tileset[ i ] ) lockTile( i, tileset, tiles );
			
			i = pointToIndex( new Point( p.x + 1, p.y ) );//right
			if ( !tileset[ i ] ) lockTile( i, tileset, tiles );
			
			i = pointToIndex( new Point( p.x, p.y - 1 ) );//top
			if ( !tileset[ i ] ) lockTile( i, tileset, tiles );
			
			i = pointToIndex( new Point( p.x, p.y + 1 ) );//bottom
			if ( !tileset[ i ] ) lockTile( i, tileset, tiles );
			
			if ( connexity == 4 ) return tiles;//if we want a connexity 4, no need to go further
			
			i = pointToIndex( new Point( p.x - 1, p.y - 1 ) );//top-left
			if ( !tileset[ i ] ) lockTile( i, tileset, tiles );
			
			i = pointToIndex( new Point( p.x + 1, p.y - 1 ) );//top-right
			if ( !tileset[ i ] ) lockTile( i, tileset, tiles );
			
			i = pointToIndex( new Point( p.x - 1, p.y + 1 ) );//bootom-left
			if ( !tileset[ i ] ) lockTile( i, tileset, tiles );
			
			i = pointToIndex( new Point( p.x + 1, p.y + 1 ) );//bottom-right
			if ( !tileset[ i ] ) lockTile( i, tileset, tiles );
			
			return tiles;
		}
		private function lockTile( i:int, tileset:Vector.<int>, tiles:Vector.<int> ):void
		{
			tileset[ i ] = 1;//makes tile non walkable
			tiles.push( i );
		}
		
		//downscaling from draw size to tileset size
		private function pointToIndex( p:Point ):int
		{
			return XYtoIndex( int( p.x ), int( p.y ) );
		}
		
		//clamping values to grid
		private function XYtoIndex( x:int, y:int ):int
		{
			if ( x < 0 ) x = 0;
			if ( x > tilesetWidth - 1 ) x = tilesetWidth - 1;
			
			if ( y < 0 ) y = 0;
			if ( y > tilesetHeight - 1 ) y = tilesetHeight - 1;
			
			return y * tilesetWidth + x;
		}
		
		//retrieving x/y values from an index
		private function IndexToPoint( i:int ):Point
		{
			return new Point( ( i % tilesetWidth ), int( i / tilesetWidth ) );
		}
		
		//renders the tileset
		private function render(tileset:Vector.<int>):void 
		{
			var value:int;
			var p:Point;
			var i:int;
			for ( i = 0; i < tileset.length; i++ )
			{
				value = tileset[ i ];
				if ( value )
				{
					graphics.beginFill( colors[ value ] );
					p = IndexToPoint( i );
					graphics.drawRect( p.x * tileWidth, p.y * tileHeight, tileWidth, tileHeight );
				}
			}
		}
	}
}