forked from: tileset

by bradsedito forked from tileset (diff: 24)
♥0 | Line 158 | Modified 2011-07-18 04:14:29 | MIT License
play

ActionScript3 source code

/**
 * Copyright bradsedito ( http://wonderfl.net/user/bradsedito )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/j5bC
 */

// forked from nicoptere's tileset
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 tilesetSize:int = 10; 
        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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
                                        0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
                                        0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
                                        0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
                                        0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1,
                                        0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1,
                                        0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0,
                                        0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                        0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
                                        0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
                                        1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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.drawCircle( p.x * tileWidth, p.y * tileHeight, tilesetSize);
//                  graphics.drawRect( p.x * tileWidth, p.y * tileHeight, tileWidth, tileHeight );
                }
            }
        }
    }
}