tileset
finding surrounding tiles in a tileset
/**
* 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 );
}
}
}
}
}