Flash - Fun with Maps

This is an early prototype for a project that required some intensive mapping capabilities.  I've boiled it down to it's bare essentials in order to minimize the code, but there are millions of directions that you could take it from here.  This was the beginning of my breakthrough to understanding Flash and ActionScript3 and I think that this code could be adapted to become a great tutorial for beginners. If you understand what's going on in the source code you could re-architect it and add all sorts of features. You'll see more variations of it in the future. If you want to see how the project turned out click here.

I had to squish it down to fit in this page, hopefully you can get the rough idea.

Other than the Main class there are only two classes.  The MapSprite class will get instantiated twice (once for the main map that you see when the app loads, and once for the details map that you see when you click on the main map).  When MapSprite gets instantiated, it's constructor creates a few 'Pops', which are the red and green dots that you see on the map.

Note that the image of the US map, which serves as the background for the MapSprite class, is a vector image.  This is important for when you zoom in to magnify the details window.

Here's the code (the Main class is  long, but the others are pretty short and easy to follow)...

Main.as
package
{
    import fl.controls.Button;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;
    import flash.display.Shape;
    import flash.display.DisplayObject;
    import flash.text.TextFormat;
   
    import niallkadermap.*;
       
    public class Main extends Sprite
    {
        //the main map in the bg
        private var mainMap:MapSprite;
        //sets starting position of mainMap, can't assume 0,0
        private var mainMapX:Number = 0;
        private var mainMapY:Number = 0;
        //create the sprite that contains the detailsMap
        //note: it will be cropped when we set it's scrollRect properties
        private var detailsWindow:Sprite;
        //create the map that sits inside detailsWindow
        private var detailsMap:MapSprite;
        //set the scrollRect boundaries of the detailsWindow
        //ALSO used for zoomIn() and zoomOut()
        private var detailsH:Number = 320;
        private var detailsW:Number = 320;
        //set the position of detailsWindow
        private var detailsX:Number = 515;
        private var detailsY:Number = 370;
                               
        //cross hairs in details window
        private var hLine:Shape;
        private var vLine:Shape;
       
        //these 2 vars are instances of the map from the library
        //one will be used as the background for the main map
        //the other will be the background of the details map
        public var bgMap1:MapImg = new MapImg();
        public var bgMap2:MapImg = new MapImg();   
       
        public function Main():void
        {   
            createMainMap();
            createDetailsMap();
        }
       
        function createMainMap():void
        {
            //create the main map and pass in the bg image
            mainMap = new MapSprite(bgMap1);
            //clicking on the main map will make the details
            //map visible, so attach the event listener...
            mainMap.addEventListener(MouseEvent.CLICK, setDetailsMap)
            //set map starting position - can't assumme that it will be 0,0
            mainMap.x = mainMapX;
            mainMap.y = mainMapY;
            addChild(mainMap);
        }
        function createDetailsMap()
        {
            //create the details window that will contain the details map
            detailsWindow = new Sprite();
            //create a window so that we don't show the entire contents of
            //the details window,
            //the rectangular window will clip everything outside of it
            //sw the only part of the details window visible will be inside the rectangle
            //make the rect the dimensions that detailsWindow is supposed to be
            detailsWindow.scrollRect = new Rectangle(0,0,detailsW,detailsH);
            //allows us to use the hand cursor on hover
            detailsWindow.buttonMode = true;
            detailsWindow.useHandCursor = true;
            //create the details map
            detailsMap = new MapSprite(bgMap2);
            //setup detailsMap for drag functionality
            detailsMap.addEventListener(MouseEvent.MOUSE_DOWN, dragMap);
            detailsMap.addEventListener(MouseEvent.MOUSE_UP, stopDragMap);
            detailsWindow.addChild(detailsMap);
           
            //create an outline around the details window so it's easy to see
            var rect = new Shape();
            rect.graphics.lineStyle(4,0x000000);
            rect.graphics.drawRect(0,0,detailsW,detailsH);
            detailsWindow.addChild(rect);
           
            //make cross hairs so it's easy to see the center point of the detailsWindow
            hLine = new Shape();
            hLine.graphics.lineStyle(2,0x000000);
            hLine.graphics.moveTo(0,detailsH/2);
            hLine.graphics.lineTo(detailsW,detailsH/2);
            detailsWindow.addChild(hLine);           
                       
            vLine = new Shape();
            vLine.graphics.lineStyle(2,0x000000);
            vLine.graphics.moveTo(detailsW/2,0);
            vLine.graphics.lineTo(detailsW/2,detailsH);
            detailsWindow.addChild(vLine);
                       
            //set location of detailsWindow on the stage
            detailsWindow.x = detailsX;
            detailsWindow.y = detailsY;
           
            //create a TextFormat for the buttons that
            //we'll make in the next step...
            var tf:TextFormat = new TextFormat();
            tf.font = "Verdana";
            tf.size = 18;
            tf.bold = true;
           
            //create the zoom in and out buttons
            var btnIn:Button = new Button();
            btnIn.height = 50;
            btnIn.width = 50;
            btnIn.label = "In";
            btnIn.move(10,8);
            btnIn.name = "btnIn";
            btnIn.setStyle("textFormat",tf);
            btnIn.addEventListener(MouseEvent.CLICK, zoomIn);
            detailsWindow.addChild(btnIn);
           
            var btnOut:Button = new Button();
            btnOut.height = 50;
            btnOut.width = 50;
            btnOut.label = "Out";
            btnOut.move(78,8);
            btnOut.name = "btnIn";
            btnOut.setStyle("textFormat",tf);
            btnOut.addEventListener(MouseEvent.CLICK, zoomOut);
            detailsWindow.addChild(btnOut);
           
            //create close button and put it in the upper right corner of the detailsWindow
            var btnCloseDetailsWindow = new Button();
            btnCloseDetailsWindow.height = 40;
            btnCloseDetailsWindow.width = 40;
            btnCloseDetailsWindow.label = "X"
            btnCloseDetailsWindow.move(detailsW - 50, 10);
            btnCloseDetailsWindow.name = "btnCloseDetailsWindow";
            btnCloseDetailsWindow.setStyle("textFormat",tf);
            btnCloseDetailsWindow.addEventListener(MouseEvent.CLICK, closeDetailsWindow);
            detailsWindow.addChild(btnCloseDetailsWindow);
           
            detailsWindow.visible = false;
            addChild(detailsWindow);
        }
               
        //////////////////////////////
        //EVENT HANDLERS
        //////////////////////////////
       
        //scales detailsMap and centers it to the point that was clicke in the mainMap
        //to be honest, the math doesn't make complete sense to me!!!!!! Just sort of stumbled into it
        function setDetailsMap(evt:MouseEvent):void
        {
            detailsMap.scaleX = 2;
            detailsMap.scaleY = 2;
           
            detailsMap.x = -(evt.localX * detailsMap.scaleX)+detailsW/2;
            detailsMap.y = -(evt.localY * detailsMap.scaleY)+detailsH/2;
           
            detailsWindow.visible = true;
        }
   
        //allows zooming in for detailsWindow
        //this math is a little fuzzy to me
        //I played with it for a good while
        function zoomIn(evt:MouseEvent):void
        {
            detailsMap.scaleX *= 1.5;
            detailsMap.scaleY *= 1.5;
            detailsMap.x = (detailsMap.x*1.5) - (detailsW/4);
            detailsMap.y = (detailsMap.y*1.5) - (detailsH/4);
        }
       
        //allows zooming Out for detailsWindow
        //once again, math is a little fuzzy to me
        function zoomOut(evt:MouseEvent):void
        {
            detailsMap.scaleX *= .5;
            detailsMap.scaleY *= .5;
            detailsMap.x = (detailsMap.x*.5) + (detailsW/4);
            detailsMap.y = (detailsMap.y*.5) + (detailsH/4);
        }
       
        //draggin functionality for detailsMap
        function dragMap(evt:MouseEvent):void
        {
            detailsMap.startDrag();
        }
       
        function stopDragMap(evt:MouseEvent):void
        {
            detailsMap.stopDrag();
        }
       
        function closeDetailsWindow(evt:MouseEvent):void
        {
            detailsWindow.visible = false;
        }
    }
}

MapSprite.as
package niallkadermap
{
    import flash.display.Sprite;
    import flash.display.DisplayObject;
    
    public class MapSprite extends Sprite
    {
        var popsAry:Array;
        
        function MapSprite(bg:DisplayObject)
        {
            //add the backgroun img
            //to this sprite
            addChild(bg);
            //create the 'pops'
            popsAry = new Array(
                new Pop(1,490,322,"POP 1"),
                new Pop(2,505,222,"POP 2"),
                new Pop(3,490,342,"POP 3"),
                new Pop(4,318,331,"POP 4")
            );
            addPops();                        
        }

        public function addPops():void
        {
            //the pops will add themselves
            //to this sprite
            for(var i:int=0; i < popsAry.length; i++)
            {
                popsAry[i].addPop(this);
            }
            
        }
    }
}

Pop.as
package niallkadermap
{
    import flash.display.DisplayObjectContainer;
    import flash.display.Sprite;
    
    public class Pop extends Sprite
    {
        var pId:Number;
        var pX:Number;
        var pY:Number;
        var popDetails:String;
        
        public function Pop(pId:Number,pX:Number, pY:Number,popDetails:String)
        {                        
            this.pId = pId
            this.pX = pX;
            this.pY = pY;
            this.popDetails = popDetails;
                                    
            graphics.lineStyle(2,0x00FF00);
            graphics.beginFill(0xFF0000);
            graphics.drawCircle(this.pX,this.pY,4);
            graphics.endFill();
        }
        
        function addPop(target:DisplayObjectContainer):void
        {
            //add this pop to the target...
            target.addChild(this);
        }
    }
}
1 Comment - Average Rating:3

Comments:
Thanx for this post, do u have any sample app for flash with Android.

Rating: 3
Date Posted: December 5th, 2010



RECENT ARTICLES