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

Layout Editor (for Dijkstra Particle Streams (Ver.1.1))

----------------------------------------------------------------------------------
* Dijkstra Particle Streams (Ver.1.1) 用のエディタ
* http://wonderfl.net/code/8bf10095433ea8cad0aff3f911f3aed6b15c6a36
* ----------------------------------------------------------------------------------
* [操作方法]
* マウスのみ。ショートカットキー等は一切ございません。
* ----------------------------------------------------------------------------------
* [マニュアル]
* 右上のボタン:上から壁編集、スタート編集、ゴール編集モードへの切り替え
* 右下のボタン:上から読み込み、書き出し、マップ全消去
* 
* [壁編集モード]
* ・マップをクリックすることで壁を設置・除去できます。
* ・removableのチェックを入れると、実行時に除去できる壁を設置できます。
* 
* [スタート編集モード]
* ・マップのノードをクリックすると、右にウインドウが表示されます。
* ・例えば、(ID.0)にチェックを入れると、
*  そのノードからID.0のゴールへ向かうスタート地点が1つ作成されます。
*  (実行時、ID.0のゴールが存在しなければ、そこからパーティクルは出現しません)
* ・2つチェックを入れると、そのノードにスタート地点が2つ作成されます。
* 
* [ゴール編集モード]
* ・マップのノードをクリックすると、右にウインドウが表示されます。
* ・例えば、ID.0を選択すると、そのノードにID.0のゴール地点が1つ作成されます。
*  (同じノードに2つ以上の異なるゴール地点を作成することはできません)
* ・異なるノードに同じIDのゴール地点を作成することはできます。
*  その場合、パーティクルは同じIDを持つゴール地点の中で、
*  一番近いゴール地点を目的地として進みます。
* 
* [読み込み・
Get Adobe Flash player
by o8que 23 Feb 2010
/**
 * Copyright o8que ( http://wonderfl.net/user/o8que )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/9sOc
 */

/* ----------------------------------------------------------------------------------
 * Dijkstra Particle Streams (Ver.1.1) 用のエディタ
 * http://wonderfl.net/code/8bf10095433ea8cad0aff3f911f3aed6b15c6a36
 * ----------------------------------------------------------------------------------
 * [操作方法]
 * マウスのみ。ショートカットキー等は一切ございません。
 * ----------------------------------------------------------------------------------
 * [マニュアル]
 * 右上のボタン:上から壁編集、スタート編集、ゴール編集モードへの切り替え
 * 右下のボタン:上から読み込み、書き出し、マップ全消去
 * 
 * [壁編集モード]
 * ・マップをクリックすることで壁を設置・除去できます。
 * ・removableのチェックを入れると、実行時に除去できる壁を設置できます。
 * 
 * [スタート編集モード]
 * ・マップのノードをクリックすると、右にウインドウが表示されます。
 * ・例えば、(ID.0)にチェックを入れると、
 *  そのノードからID.0のゴールへ向かうスタート地点が1つ作成されます。
 *  (実行時、ID.0のゴールが存在しなければ、そこからパーティクルは出現しません)
 * ・2つチェックを入れると、そのノードにスタート地点が2つ作成されます。
 * 
 * [ゴール編集モード]
 * ・マップのノードをクリックすると、右にウインドウが表示されます。
 * ・例えば、ID.0を選択すると、そのノードにID.0のゴール地点が1つ作成されます。
 *  (同じノードに2つ以上の異なるゴール地点を作成することはできません)
 * ・異なるノードに同じIDのゴール地点を作成することはできます。
 *  その場合、パーティクルは同じIDを持つゴール地点の中で、
 *  一番近いゴール地点を目的地として進みます。
 * 
 * [読み込み・書き出し]
 * ・下のコピペ用テキストエリアに、然るべきXMLをペーストして
 *  importボタンを押すと、XMLのデータが読み込まれます。
 * ・exportボタンを押すと、現在のマップ(壁、スタート、ゴール)の状態が
 *  下のコピペ用テキストエリアに、XML形式で出力されます。
 *
 * [作成したレイアウトの適用方法]
 * ・Dijkstra Particle Streams (Ver.1.1)をForkします。
 * ・650行辺りに変数dataに代入されているXMLがあるので全部消します。
 * ・変数dataにexportで出力されたXMLをコピペして書き換えます。
 * ・成功すれば、あなたが作成したレイアウトで実行されるでしょう!
 * ----------------------------------------------------------------------------------
 * [Tips]
 * ・マップの一番外側の黒いノードは画面外になります。
 * ・ノードは、スタート地点があると緑、ゴール地点があると赤、両方あると紫になります。
 * ・パーティクルの経路探索は各ゴール地点が行っているので、
 *  ゴール地点を増やしすぎると、処理が重くなる可能性があります。
 *  (同IDの異なるゴール地点も、それぞれ地点ごとに別に計算しているので注意)
 * ・コピペ用テキストエリアには、最初「Dijkstra Particle Streams (Ver.1.1)」の
 *  XMLデータが入っています。importして見てみると感じが掴めると思います。
 * ・コピペは全て選択からのコピーで
 * ----------------------------------------------------------------------------------
 * [作例]
 * Juggle Them!! (ジャグれ!!)
 * http://wonderfl.net/code/71ba419847037961758341adf477c4fc0faee767
 * "LIFE" (「命」)
 * http://wonderfl.net/code/9d0f2ea71c617566ad145782ba6c1bb5c336f15b
 */

package {
	import com.bit101.components.*;
	import flash.display.*;
	import flash.events.*;
	
	[SWF(frameRate=10)]
	public class main extends Sprite {
		public static var nodes:Array;
		public static var walls:Array;
		
		private var _mode:Mode;
		
		// 各コンポーネントの参照
		private var _map:Sprite;
		private var _wallLayer:Sprite;
		private var _cursor:Shape;
		
		private var _currentMode:Text;
		private var _wallSelect:PushButton;
		private var _startSelect:PushButton;
		private var _goalSelect:PushButton;
		
		private var _IOTextField:Text;
		private var _importButton:PushButton;
		private var _exportButton:PushButton;
		private var _clearButton:PushButton;
		
		public function main() {
			graphics.beginFill(0x000000);
			graphics.drawRect(0, 0, 465, 465);
			graphics.endFill();
			
			initializeMap();
			initializeComponents();
			initializeMode();
		}
		
		private function initializeMap():void {
			_map = new Sprite();
			_map.x = _map.y = 5;
			addChild(_map);
			
			initializeNodes();
			
			_wallLayer = new Sprite();
			_map.addChild(_wallLayer);
			
			_cursor = new Shape();
			_map.addChild(_cursor);
			_map.addEventListener(MouseEvent.MOUSE_MOVE, moveCursor);
		}
		
		private function initializeNodes():void {			
			main.nodes = [];
			main.walls = [];
			for (var row:int = 0; row < 33; row++) {
				main.nodes[row] = [];
				for (var col:int = 0; col < 33; col++) {
					var node:Node = new Node(col, row);
					main.nodes[row][col] = node;
					_map.addChild(node);
				}
			}
		}
		
		private function moveCursor(e:MouseEvent):void {
			_cursor.x = Math.min(_map.mouseX - (_map.mouseX % 11), 352);
			_cursor.y = Math.min(_map.mouseY - (_map.mouseY % 11), 352);
		}
		
		private function initializeComponents():void {
			// モード選択用パネルの作成
			_currentMode = new Text(this, 373, 5);
			_currentMode.width = 87, _currentMode.height = 20, _currentMode.editable = false;
			var modeSelectPanel:Panel = new Panel(this, 373, 25);
			modeSelectPanel.width = 87, modeSelectPanel.height = 72;
			_wallSelect = new PushButton(modeSelectPanel, 3, 3, "build a Wall", changeToWallMode);
			_startSelect = new PushButton(modeSelectPanel, 3, 26, "set a Start", changeToStartMode);
			_goalSelect = new PushButton(modeSelectPanel, 3, 49, "set a Goal", chageToGoalMode);
			_wallSelect.width = _startSelect.width = _goalSelect.width = 81;
			
			// コピペフィールド・インポート・エクスポート・クリアの作成
			_IOTextField = new Text(this, 5, 373, "");
			_IOTextField.width = 363;
			_IOTextField.height = 87;
			setDefaultXML();
			_importButton = new PushButton(this, 373, 378, "import", importXML);
			_exportButton = new PushButton(this, 373, 406.5, "export", exportXML);
			_clearButton = new PushButton(this, 373, 435, "clear all", clearAll);
			_importButton.width = _exportButton.width = _clearButton.width = 87;
		}
		
		private function changeToWallMode(e:Event):void {
			_mode.exit();
			_mode = WallMode.instance;
			_mode.enter();
		}
		
		private function changeToStartMode(e:Event):void {
			_mode.exit();
			_mode = StartMode.instance;
			_mode.enter();
		}
		
		private function chageToGoalMode(e:Event):void {
			_mode.exit();
			_mode = GoalMode.instance;
			_mode.enter();
		}
		
		private function initializeMode():void {
			// 擬似ヌルオブジェクト
			_mode = new Mode();
			WallMode.instance.setContext(this);
			StartMode.instance.setContext(this);
			GoalMode.instance.setContext(this);
			
			changeToWallMode(null);
			_map.addEventListener(MouseEvent.CLICK, clickMap);
		}
		
		private function clickMap(e:MouseEvent):void {
			_mode.clickMap(e);
		}
		
		private function importXML(e:MouseEvent):void {
			clearAll(null);
			var xml:XML = new XML(_IOTextField.text);
			
			for each(var w:XML in xml.walls.*) {
				var removable:Boolean = ((w.@rem == "t") ? true : false);
				addWall(new Wall(int(w.@x), int(w.@y), removable));
			}
			
			var node:Node;
			for each(var s:XML in xml.starts.*) {
				node = main.nodes[int(s.@y)][int(s.@x)];
				node.startDests[int(s.@goal)] = true;
				node.draw(false);
			}
			for each(var g:XML in xml.goals.*) {
				node = main.nodes[int(g.@y)][int(g.@x)];
				node.goalID = int(g.@id);
				node.draw(false);
			}
		}
		
		private function exportXML(e:MouseEvent):void {
			var xml:XML = <root><walls /><starts /><goals /></root>;
			
			for (var i:int = 0; i < main.walls.length; i++) {
				var wall:XML = <wall />
				wall.@x = main.walls[i].tilex, wall.@y = main.walls[i].tiley;
				wall.@rem = ((main.walls[i].removable) ? "t" : "f");
				xml.walls.appendChild(wall);
			}
			
			for (var row:int = 0; row < 33; row++) {
				for (var col:int = 0; col < 33; col++) {
					var node:Node = main.nodes[row][col];
					for (var dest:int = 0; dest < 16; dest++) {
						if (node.startDests[dest]) {
							var start:XML = <start />;
							start.@goal = dest,	start.@x = col,	start.@y = row;
							xml.starts.appendChild(start);
						}
					}
					if (node.goalID != -1) {
						var goal:XML = <goal />;
						goal.@id = node.goalID, goal.@x = col, goal.@y = row;
						xml.goals.appendChild(goal);
					}
				}
			}
			
			_IOTextField.text = xml.toXMLString();
		}
		
		private function clearAll(e:MouseEvent):void {
			for (var row:int = 0; row < 33; row++) {
				for (var col:int = 0; col < 33; col++) {
					var node:Node = main.nodes[row][col];
					for (var dest:int = 0; dest < 16; dest++) {
						node.startDests[dest] = false;
					}
					node.goalID = -1;
					node.draw(false);
				}
			}
			
			for (var i:int = main.walls.length - 1; i >= 0; i--) {
				main.walls[i].remove();
			}
			
			_mode.exit();
			_mode.enter();
		}
		
		public function addWall(wall:Wall):void {
			_wallLayer.addChild(wall);
			main.walls.push(wall);
		}
		
		public function setCurrentModeText(str:String):void {
			_currentMode.text = str;
		}
		
		public function drawCursor(size:int):void {
			_cursor.graphics.clear();
			_cursor.graphics.lineStyle(1, 0xffffff);
			_cursor.graphics.drawRect(0.5, 0.5, size - 1, size - 1);
		}
		
		private function setDefaultXML():void {
			var xml:XML =
			<root>
				<walls>
					<wall x="0" y="0" rem="f"/><wall x="2" y="0" rem="f"/>
					<wall x="4" y="0" rem="f"/><wall x="6" y="0" rem="f"/>
					<wall x="8" y="0" rem="f"/><wall x="10" y="0" rem="f"/>
					<wall x="21" y="0" rem="f"/><wall x="23" y="0" rem="f"/>
					<wall x="25" y="0" rem="f"/><wall x="27" y="0" rem="f"/>
					<wall x="29" y="0" rem="f"/><wall x="31" y="0" rem="f"/>
					
					<wall x="0" y="31" rem="f"/><wall x="2" y="31" rem="f"/>
					<wall x="4" y="31" rem="f"/><wall x="6" y="31" rem="f"/>
					<wall x="8" y="31" rem="f"/><wall x="10" y="31" rem="f"/>
					<wall x="21" y="31" rem="f"/><wall x="23" y="31" rem="f"/>
					<wall x="25" y="31" rem="f"/><wall x="27" y="31" rem="f"/>
					<wall x="29" y="31" rem="f"/><wall x="31" y="31" rem="f"/>
					
					<wall x="0" y="2" rem="f"/><wall x="0" y="4" rem="f"/>
					<wall x="0" y="6" rem="f"/><wall x="0" y="8" rem="f"/>
					<wall x="0" y="10" rem="f"/><wall x="0" y="21" rem="f"/>
					<wall x="0" y="23" rem="f"/><wall x="0" y="25" rem="f"/>
					<wall x="0" y="27" rem="f"/><wall x="0" y="29" rem="f"/>
					
					<wall x="31" y="2" rem="f"/><wall x="31" y="4" rem="f"/>
					<wall x="31" y="6" rem="f"/><wall x="31" y="8" rem="f"/>
					<wall x="31" y="10" rem="f"/><wall x="31" y="21" rem="f"/>
					<wall x="31" y="23" rem="f"/><wall x="31" y="25" rem="f"/>
					<wall x="31" y="27" rem="f"/><wall x="31" y="29" rem="f"/>
				</walls>
				<starts>
					<start goal="0" x="13" y="0"/><start goal="0" x="14" y="0"/>
					<start goal="0" x="15" y="0"/><start goal="0" x="16" y="0"/><start goal="0" x="17" y="0"/>
					<start goal="0" x="18" y="0"/><start goal="0" x="19" y="0"/>
					
					<start goal="1" x="0" y="13"/><start goal="1" x="0" y="14"/>
					<start goal="1" x="0" y="15"/><start goal="1" x="0" y="16"/><start goal="1" x="0" y="17"/>
					<start goal="1" x="0" y="18"/><start goal="1" x="0" y="19"/>
				</starts>
				<goals>
					<goal id="0" x="13" y="32"/><goal id="0" x="14" y="32"/>
					<goal id="0" x="15" y="32"/><goal id="0" x="16" y="32"/><goal id="0" x="17" y="32"/>
					<goal id="0" x="18" y="32"/><goal id="0" x="19" y="32"/>
					
					<goal id="1" x="32" y="13"/><goal id="1" x="32" y="14"/>
					<goal id="1" x="32" y="15"/><goal id="1" x="32" y="16"/><goal id="1" x="32" y="17"/>
					<goal id="1" x="32" y="18"/><goal id="1" x="32" y="19"/>
				</goals>
			</root>;
			
			_IOTextField.text = xml.toXMLString();
		}
	}
}
//package {
	import flash.display.*;
	
	//public 
	class Node extends Sprite {
		public var isWall:Boolean;
		public var startDests:Array;
		public var goalID:int;
		
		private var _tilex:int;
		private var _tiley:int;
		
		public function Node(tilex:int, tiley:int) {
			_tilex = tilex;
			_tiley = tiley;
			x = _tilex * 11;
			y = _tiley * 11;
			
			initialize();
			draw();
		}
		
		public function initialize():void {
			isWall = false;
			startDests = [];
			for (var i:int = 0; i < 16; i++) {
				startDests.push(false);
			}
			goalID = -1;
		}
		
		public function draw(selected:Boolean = false):void {
			graphics.clear();
			
			if (selected) {
				graphics.lineStyle(1, 0xffff00);
			}else {
				graphics.lineStyle(1, 0x333333);
			}
			
			if (hasStart() && hasGoal()) {
				graphics.beginFill(0xff00ff);
			}else if (hasStart()) {
				graphics.beginFill(0x00ff00);
			}else if (hasGoal()) {
				graphics.beginFill(0xff0000);
			}else if (_tilex == 0 || _tilex == 32 || _tiley == 0 || _tiley == 32) {
				graphics.beginFill(0x111111);
			}else {
				graphics.beginFill(0x222222);
			}
			
			graphics.drawRect(0.25, 0.25, 10.5, 10.5);
			graphics.endFill();
		}
		
		private function hasStart():Boolean {
			for each(var dest:Boolean in startDests) {
				if (dest) { return true; }
			}
			return false;
		}
		
		private function hasGoal():Boolean {
			return (goalID != -1);
		}
		
		// 壁やスタート・ゴールノードになっていないかどうか
		public function isFree():Boolean {
			return !(isWall || hasStart() || hasGoal());
		}
	}
//}
//package {
	import flash.display.*;
	import flash.geom.Point;
	
	//public 
	class Wall extends Sprite {
		private var _tilex:int;
		private var _tiley:int;
		private var _removable:Boolean;
		
		public function get tilex():int { return _tilex; }
		public function get tiley():int { return _tiley; }
		public function get removable():Boolean { return _removable; }
		
		public function Wall(tilex:int, tiley:int, removable:Boolean) {
			_tilex = tilex;
			_tiley = tiley;
			_removable = removable;
			
			x = _tilex * 11;
			y = _tiley * 11;
			
			setNodePassablity(true);
			draw();
		}
		
		// 壁を設置した部分のノードの通行可能性を変更する
		private function setNodePassablity(isWall:Boolean):void {
			main.nodes[_tiley][_tilex].isWall = isWall;
			main.nodes[_tiley][_tilex + 1].isWall = isWall;
			main.nodes[_tiley + 1][_tilex].isWall = isWall;
			main.nodes[_tiley + 1][_tilex + 1].isWall = isWall;
		}
		
		// 壁の画像を描画する
		private function draw():void {
			if (_removable) {
				graphics.lineStyle(1, 0x666666);
				graphics.beginFill(0x444444);
				graphics.drawRect(0.25, 0.25, 21.5, 21.5);
				graphics.endFill();
			}else {
				graphics.beginFill(0x444444);
				graphics.drawRect(0, 0, 22, 22);
				graphics.endFill();
			}
		}
		
		// 壁を取り除く際に呼ぶ関数
		public function remove():void {
			setNodePassablity(false);
			parent.removeChild(this);
			main.walls.splice(main.walls.indexOf(this), 1);
		}
		
		// 指定した位置に壁が設置できるか
		public static function buildable(tilex:int, tiley:int):Boolean {
			if (tilex == 32 || tiley == 32) {
				return false;
			}
			
			return (main.nodes[tiley][tilex].isFree() &&
			main.nodes[tiley][tilex + 1].isFree() &&
			main.nodes[tiley + 1][tilex].isFree() &&
			main.nodes[tiley + 1][tilex + 1].isFree());
		}
	}
//}
//package {
	import flash.events.MouseEvent;
	
	class Mode {
		protected var _context:main;
		
		public function setContext(context:main):void {
			_context = context;
		}
		
		public function enter():void { }
		public function exit():void { }
		public function clickMap(e:MouseEvent):void { }
	}
//}
//package {
	import com.bit101.components.*;
	import flash.events.*;
	
	//public 
	class WallMode extends Mode {
		private static var _instance:WallMode;
		
		private var _wallPanel:Panel;
		private var _removableCheck:CheckBox;
		private var _removable:Boolean;
		
		public static function get instance():WallMode {
			if (WallMode._instance == null) {
				_instance = new WallMode(new SingletonEnforcer());
			}
			return _instance;
		}
		
		public function WallMode(enforcer:SingletonEnforcer) {
			_wallPanel = new Panel(null, 373, 102);
			_wallPanel.width = 87, _wallPanel.height = 20;
			_removableCheck = new CheckBox(_wallPanel, 5, 5, "removable", reverseRemovability);
			_removable = false;
		}
		
		private function reverseRemovability(e:Event):void {
			_removable = e.currentTarget.selected;
		}
		
		override public function enter():void {
			_context.setCurrentModeText("Wall edit mode");
			_context.drawCursor(22);
			_context.addChild(_wallPanel);
			_removable = _removableCheck.selected = false;
		}
		
		override public function exit():void {
			if (_context.contains(_wallPanel)) {
				_context.removeChild(_wallPanel);
			}
		}
		
		override public function clickMap(e:MouseEvent):void {
			if (e.target is Wall) {
				e.target.remove();
			}else if (e.target is Node) {
				var tilex:int = int(e.target.x / 11);
				var tiley:int = int(e.target.y / 11);
				if (Wall.buildable(tilex, tiley)) {
					_context.addWall(new Wall(tilex, tiley, _removable));
				}
			}
		}
	}
//}
//class SingletonEnforcer { }
//package {
	import com.bit101.components.*;
	import flash.events.*;
	
	//public 
	class StartMode extends Mode {
		private static var _instance:StartMode;
		
		private var _startPanel:Panel;
		private var _destChecks:Array;
		private var _selectedNode:Node;
		
		public static function get instance():StartMode {
			if (StartMode._instance == null) {
				_instance = new StartMode(new SingletonEnforcer());
			}
			return _instance;
		}
		
		public function StartMode(enforcer:SingletonEnforcer) {
			_startPanel = new Panel(null, 373, 102);
			_startPanel.width = 87, _startPanel.height = 245;
			_destChecks = [];
			for (var i:int = 0; i < 16; i++) {
				var destCheck:CheckBox = new CheckBox(_startPanel, 5, 5 + i * 15, "to Goals(ID." + i + ")", clickDestCheck);
				_destChecks.push(destCheck);
			}
			
			cancelSelection();
		}
		
		private function clickDestCheck(e:MouseEvent):void {
			for (var i :int = 0; i < 16; i++) {
				_selectedNode.startDests[i] = _destChecks[i].selected;
			}
			_selectedNode.draw(true);
		}
		
		private function cancelSelection():void {
			// 擬似ヌルオブジェクト
			_selectedNode = new Node(0, 0);
		}
		
		override public function enter():void {
			_context.setCurrentModeText("Start edit mode");
			_context.drawCursor(11);
			_selectedNode.draw(true);
		}
		
		override public function exit():void {
			_selectedNode.draw(false);
			cancelSelection();
			if (_context.contains(_startPanel)) {
				_context.removeChild(_startPanel);
			}
		}
		
		override public function clickMap(e:MouseEvent):void {
			if (!(e.target is Node)) {
				if (_context.contains(_startPanel)) {
					_context.removeChild(_startPanel);
				}
				return;
			}
			
			_selectedNode.draw(false);
			_selectedNode = e.target as Node;
			_selectedNode.draw(true);
			
			for (var i:int = 0; i < 16; i++) {
				_destChecks[i].selected = _selectedNode.startDests[i];
			}
			
			_context.addChild(_startPanel);
		}
		
		
	}
//}
//class SingletonEnforcer { }
//package {
	import com.bit101.components.*;
	import flash.events.*;
	
	//public 
	class GoalMode extends Mode {
		private static var _instance:GoalMode;
		
		private var _goalPanel:Panel;
		private var _goalButtons:Array;
		private var _selectedNode:Node;
		
		public static function get instance():GoalMode {
			if (GoalMode._instance == null) {
				_instance = new GoalMode(new SingletonEnforcer());
			}
			return _instance;
		}
		
		public function GoalMode(enforcer:SingletonEnforcer) {
			_goalPanel = new Panel(null, 373, 102);
			_goalPanel.width = 87, _goalPanel.height = 260;
			_goalButtons = [new RadioButton(_goalPanel, 5, 5, "none", false, clickGoalButton)];
			for (var i:int = 0; i < 16; i++) {
				var goalButton:RadioButton = new RadioButton(_goalPanel, 5, 20 + i * 15, "ID." + i, false, clickGoalButton);
				_goalButtons.push(goalButton);
			}
			
			cancelSelection();
		}
		
		private function clickGoalButton(e:MouseEvent):void {
			for (var i:int = 0; i < 16; i++) {
				if (_goalButtons[i + 1].selected) {
					_selectedNode.goalID = i;
					break;
				}
			}
			if (i == 16) {
				_selectedNode.goalID = -1;
			}
			_selectedNode.draw(true);
		}
		
		private function cancelSelection():void {
			// 擬似ヌルオブジェクト
			_selectedNode = new Node(0, 0);
		}
		
		override public function enter():void {
			_context.setCurrentModeText("Goal edit mode");
			_context.drawCursor(11);
			_selectedNode.draw(true);
		}
		
		override public function exit():void {
			_selectedNode.draw(false);
			cancelSelection();
			if (_context.contains(_goalPanel)) {
				_context.removeChild(_goalPanel);
			}	
		}
		
		override public function clickMap(e:MouseEvent):void {
			if (!(e.target is Node)) {
				if (_context.contains(_goalPanel)) {
					_context.removeChild(_goalPanel);
				}
				return;
			}
			
			_selectedNode.draw(false);
			_selectedNode = e.target as Node;
			_selectedNode.draw(true);
			
			_goalButtons[_selectedNode.goalID + 1].selected = true;
			
			_context.addChild(_goalPanel);
		}
	}
//}
class SingletonEnforcer { }