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

Node Star 3 [entire path - BFS]

This time, using a BFS (Breadth First Search - FIFO),  it highlights all connected nodes and edges from the node you select.

-x to make controls appear and disappear
-right click on node to delete it, and all the nodes and edges along paths connected
-left click and move mouse to drag node and redraw immediately connected edges.
-hit reload to get new graph
Get Adobe Flash player
by NME 06 Sep 2015
// forked from NME's Not done with this yet
// forked from NME's Nodes Star 2 -  [Updated]
// forked from NME's Nodes Star 1 - randomly connected
// @author  -  NME   a.k.a. Anthony Pace ap13mo@student.ocadu.ca - Toronto, ON, Canada
//Not done yet, in fact I just started this... doing this when I have a couple minutes here and there, because I have a ton of Homework.
package {
    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.text.TextField;
    import flash.utils.Dictionary;
    public class FlashTest extends Sprite {
        public var hoverNodeColour:uint = 0x333388;
        public var hoverEdgeColour:uint = 0x0000ff;
        public var selectedEdgeColour:uint = 0xff0000;
        public var unselectedEdgeColour:uint = 0x000000;
        public var selectedNodeColour:uint = 0xff0080;
        public var unselectedNodeColour:uint = 0x888888;
        public var nodeRadius:uint = 4;
        
        public var nodeLayer:Sprite;
        public var edgeLayer:Sprite;
        
        public function FlashTest() {
            Wonderfl.disable_capture ();//
            init();
        }
        private function init():void{
            removeEventListener(Event.ADDED_TO_STAGE, init);
            var offset:Pt = new Pt(stage.stageWidth/2,stage.stageHeight/2);//used as centre of "circle" and as control point for bezier curves
            var maxNodes:uint=60+Math.random()*120;//play around here and later in the equation to get nifty constructs 
            var radius:uint = nodeRadius;
            var pix2:Number = Math.PI*2;
            var r2d:Number = pix2/180;
            
            var bigRad:uint = offset.x-radius-40;  //the radius (a.k.a. distance) for the nodes from the centre of the collective 'circle'
            var r2dx180_nodes:Number = r2d*(180/maxNodes);
            
            edgeLayer = new Sprite(); //Could have been a shape layer, but I want to draw edges individually
            nodeLayer = new Sprite();
            
            
            
            var nodes:Vector.<Node> = new Vector.<Node>;//I am only storing references here temporarily in this case, because there isn't a reason, at least right now, to store them this way after they've been generated
            
            //make the nodes, and give them their coordinates
            var node1:Node, node2:Node;
            var radian:Number;
            for(var i:uint=0;i!=maxNodes;i++){
                node1 = new Node(i,radius,unselectedNodeColour);
                radian = i*r2dx180_nodes;
                node1.x = offset.x + Math.cos(radian)*(bigRad);
                node1.y = offset.y + Math.sin(radian)*(bigRad);
                nodeLayer.addChild(node1);
                nodes.push(node1);
            }
            
            Edge.anchorPt = offset; //This is where I define the control point that will be static among all Edges
                                    //if you connect this to the mouse, it yields intersting results graphically
            
            //setup the connections between nodes, create the edges
            var edge:Edge; 
            var j:uint,k:uint;
            for(i=0;i!=maxNodes;i++){
                node1 = nodes[i];
                
                //this is where we establish the connections
                k= (i+5*(7*i+5))%maxNodes;//Math.random()*maxNodes;
                node2 = nodes[k];
                if(node2.connections[node1.id]===undefined && node2!=node1){
                    edge = makeEdge(node1,node2);
                    edge.drawEdge(unselectedEdgeColour);
                    edgeLayer.addChild(edge);
                }
            }
            for(i=0;i!=maxNodes;i++){
                node1 = nodes[i];
                if(!hasConnections(node1)){//
                    deletePathsFromNode(node1);
                }
            }

            nodes=null;
            
            //make things visible
            stage.addChild(edgeLayer);
            stage.addChild(nodeLayer);
            
            //these events allow the dragging of elements
            nodeLayer.addEventListener(MouseEvent.MOUSE_OVER,mouseOverNLEH);
            nodeLayer.addEventListener(MouseEvent.MOUSE_OUT,mouseOutNLEH); 
            nodeLayer.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownNLEH);
            //when the mouse moves faster than image is rendered... listening in a parent layer
            //or even globally for movement solves that problem, and it cuts down on the amount of listeners
            stage.addEventListener(MouseEvent.MOUSE_UP,mouseUpSEH);
            stage.addEventListener(MouseEvent.MOUSE_MOVE,mouseMoveSEH);
            
            nodeLayer.addEventListener(MouseEvent.RIGHT_CLICK,mouseRightClickNLEH);//
            stage.addEventListener(MouseEvent.RIGHT_CLICK,function(me:MouseEvent):void{});
            
            
            //Keyboard event to make nodes invisible
            stage.addEventListener(KeyboardEvent.KEY_DOWN, 
                function(ke:KeyboardEvent):void{
                    if(ke.keyCode == 88){
                        if(nodeLayer.visible){
                            nodeLayer.visible = false;
                            stage.removeChild(nodeLayer);
                        }else {
                            nodeLayer.visible = true;
                            stage.addChild(nodeLayer);
                        }
                    }
                }
            );
            
        }
        
        
        /////////////////////////////////////////////////////////////////
        //These variables and functions, are used for dragging the nodes
        public var isDragging:Boolean = false;
        public var draggedNode:Node; //if you don't know what type of class it will be, you can use Object instead
        public function mouseOverNLEH(me:MouseEvent):void{
            if (!draggedNode){
                var node:Node = me.target as Node;
                node.drawDot(nodeRadius,hoverNodeColour);
                //redrawConnectedEdges(node, hoverEdgeColour);//
                redrawPathsFromNode(node,hoverEdgeColour,hoverNodeColour);
            }
            me.updateAfterEvent(); 
        }
        public function mouseOutNLEH(me:MouseEvent):void{//
            if (!isDragging){
                var node:Node = me.target as Node;
                node.drawDot(nodeRadius,unselectedNodeColour);
                //redrawConnectedEdges(node, unselectedEdgeColour);
                redrawPathsFromNode(node,unselectedEdgeColour,unselectedNodeColour);
                draggedNode=null;
            }
            me.updateAfterEvent(); 
        }
        public function mouseDownNLEH(me:MouseEvent):void{
            isDragging=true;
            draggedNode = me.target as Node;
            //this is where would redraw them with the move colour
            draggedNode.drawDot(nodeRadius,selectedNodeColour);
            redrawConnectedEdges(draggedNode, selectedEdgeColour);//
            me.updateAfterEvent(); 
        }
        public function mouseUpSEH(me:MouseEvent):void{
            if(isDragging){
                isDragging=false;
                //this is where we would set them back to normal
                draggedNode.drawDot(nodeRadius,hoverNodeColour);
                redrawConnectedEdges(draggedNode, hoverEdgeColour);
                draggedNode=null;
            }
            me.updateAfterEvent();
        }
        public function mouseMoveSEH(me:MouseEvent):void{
            if(me.buttonDown && isDragging){
                draggedNode.x = me.stageX;
                draggedNode.y = me.stageY;
                redrawConnectedEdges(draggedNode, selectedEdgeColour);
            }
            me.updateAfterEvent();
        }
        
        //right click on a node, to start deleting nodes and their connected edges 
        public function mouseRightClickNLEH(me:MouseEvent):void{
            deletePathsFromNode( me.target as Node); 
            me.updateAfterEvent(); 
        }
        
        //this function is only called when dragging node around
        public function redrawConnectedEdges(node:Node,edgeColour:uint):void{//
            for each(var edge:Edge in node.edges){
                
                edge.drawEdge(edgeColour);
            }
        }
        public function redrawPathsFromNode(startNode:Node,edgeColour:uint,nodeColour:uint):void{
            //essentially a BFS ...
            var visitedNodes:Dictionary = new Dictionary(); //where we've been
            var drawnEdges:Dictionary = new Dictionary();
            var next:Vector.<Node> = new Vector.<Node>; //where we haven't crawled through yet
            
            var currentNode:Node; //current
            var node2:Node;
            var edge:Edge;
            next.push(startNode);
            
            while(next.length!=0){
                currentNode = next.shift();
                visitedNodes[currentNode]=true;
                for each(edge in currentNode.edges){
                    if(edge.node1 === currentNode){
                        node2 = edge.node2;
                    }else{
                        node2 = edge.node1;   
                    }
                    if(!(node2 in visitedNodes)){
                        next.push(node2);
                        node2.drawDot(nodeRadius,nodeColour);          
                    }
                    if(!(edge in drawnEdges)){
                         drawnEdges[edge]=true;
                         edge.drawEdge(edgeColour);
                    }
                }
            }
        }
        //this is called after the generation of the nodes, and connections are being made
        public function makeEdge(node1:Node,node2:Node):Edge{
            node1.connections[node2.id] = node2;
            node2.connections[node1.id] = node1;            
            var edge:Edge = new Edge(node1,node2);
            node1.edges[edge]=edge;
            node2.edges[edge]=edge;            
            return edge;
        }
        
        ///////////////////////////////////////
        //functions required for deleting nodes
        public function hasConnections(node:Node):Boolean{
            var oc:uint = 0;
            for each(var n:Node in node.connections){
                oc++;
                break;
            }
            return Boolean(oc);
        }
        public function deletePathsFromNode(startNode:Node):void{
            //essentially a BFS ... because I am using FIFO
            var visited:Dictionary = new Dictionary(); //where we've been
            var next:Vector.<Node> = new Vector.<Node>; //where we haven't crawled through yet
            
            var currentNode:Node; //current
            var node2:Node;
            var edge:Edge;
            next.push(startNode);
            
            while(next.length!=0){
                currentNode = next.shift();
                visited[currentNode]=true;
                for each(edge in currentNode.edges){
                    if(edge.node1 === currentNode){
                        node2 = edge.node2;
                    }else{
                        node2 = edge.node1;   
                    }
                    if(!(node2 in visited)){
                        next.push(node2);
                        delete node2.edges[edge]; //edge reference to current edge from connected node
                        delete node2.connections[currentNode.id]; //connection reference to me from connected node
                        delete currentNode.connections[node2.id];//my connection reference to the connected node
                        delete currentNode.edges[edge]; //primary node's reference to the current edge           
                    }
                    edgeLayer.removeChild(edge);
                }
                if(nodeLayer.contains(currentNode)){
                    nodeLayer.removeChild(currentNode);   //
                }
            }
            
        }
        
    }
}
import flash.display.Graphics;
import flash.display.Sprite;
import flash.utils.Dictionary;
internal class Pt {
    public var x:uint;
    public var y:uint;
    public function Pt(x:uint,y:uint){
        this.x = x;
        this.y = y;
    }
}

internal class Node extends Sprite{
    public var id:uint;
    public var connections:Dictionary;//tells you the connections by node id
    public var edges:Dictionary; //:Vector.<Edge>;
    public function Node(id:uint,radius:uint=1,colour:uint=0){
        this.connections = new Dictionary();
        this.edges = new Dictionary();//Vector.<Edge>;
        this.id=id;
        drawDot(radius,colour);
    }
    public function drawDot(radius:uint=1,colour:uint=0):void{
        //I could memoize the results, but I'm doing it this way for... I might do it later when I start playing around later
        this.graphics.clear();
        this.graphics.beginFill(colour);
        this.graphics.drawCircle(0,0,radius);
        this.cacheAsBitmap = true;
    }
}
internal class Edge extends Sprite{
    public var node1:Node;
    public var node2:Node;
    public static var anchorPt:Pt;
    public function Edge (node1:Node,node2:Node){
        this.node1 = node1;
        this.node2 = node2;
    }
    public function drawEdge(colour:uint = 0x000000):void{
        var g:Graphics = this.graphics;
        g.clear();
        g.lineStyle(.25,colour);
        g.moveTo(node1.x,node1.y);
        g.curveTo(anchorPt.x,anchorPt.y,node2.x,node2.y);
    }
}