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

エアリバーシ

//////////////////////////////////////////////////////////////////////////////
リバーシ for AS3.0 (1)
http://www.project-nya.jp/modules/weblog/details.php?blog_id=1039
Enterキー・上下左右キーで操作してください。
special thanks to QURAGE
http://qurage.net/labo/fl1/data/reversi.html
//////////////////////////////////////////////////////////////////////////////
Get Adobe Flash player
by dice 28 May 2010
/**
 * Copyright dice ( http://wonderfl.net/user/dice )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/pjMb
 */

// forked from ProjectNya's Reversi
////////////////////////////////////////////////////////////////////////////////
// リバーシ for AS3.0 (1)
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=1039
// Enterキー・上下左右キーで操作してください。
//
// special thanks to QURAGE
// http://qurage.net/labo/fl1/data/reversi.html
////////////////////////////////////////////////////////////////////////////////

package {

	import flash.display.Sprite;
	import flash.display.Shape;
	import flash.geom.Matrix;
	import flash.display.GradientType;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.AntiAliasType;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	import flash.filters.DropShadowFilter;

	[SWF(backgroundColor="#FFFFFF", width="465", height="465", frameRate="30")]

	public class Main extends Sprite {
		private static var color1:uint = 0x3F68AB;
		private static var color2:uint = 0x77B2EE;
		private static var tColor:uint = 0xFFFFFF;
		private static var sColor:uint = 0x00000;
		private static var fontType:String = "_ゴシック";

		public function Main() {
			//Wonderfl.capture_delay(10);
			init();
		}

		private function init():void {
			draw(465, 465);
			var game:Game = new Game();
			addChild(game);
			game.x = 42;
			game.y = 12;
		}
		private function draw(w:uint, h:uint):void {
			var colors:Array = [color1, color2];
			var alphas:Array = [1, 1];
			var ratios:Array = [0, 255];
			var matrix:Matrix = new Matrix();
			matrix.createGradientBox(w, h, 1.25*Math.PI, 0, 0);
			graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
			graphics.drawRect(0, 0, w, h);
			graphics.endFill();
			var tf:TextFormat = new TextFormat();
			tf.font = fontType;
			tf.size = 32;
			tf.align = TextFormatAlign.LEFT;
			var title:TextField = new TextField();
			addChild(title);
			title.x = 20;
			title.y = 3;
			title.width = 120;
			title.height = 40;
			title.type = TextFieldType.DYNAMIC;
			title.selectable = false;
			//title.embedFonts = true;
			//title.antiAliasType = AntiAliasType.ADVANCED;
			title.defaultTextFormat = tf;
			title.textColor = tColor;
			title.text = "Reversi";
			var shade:DropShadowFilter = new DropShadowFilter(1, 90, sColor, 0.4, 4, 4, 2, 2, false, false);
			title.filters = [shade];
			
			var subtitle:TextField = new TextField();
			addChild(subtitle);
			subtitle.x = 20;
			subtitle.y = 35;
			subtitle.width = 120;
			subtitle.height = 40;
			subtitle.autoSize = "left";
			subtitle.type = TextFieldType.DYNAMIC;
			subtitle.selectable = false;
			subtitle.textColor = tColor;
			subtitle.text = "天才には見えるというあの世界";
			subtitle.filters = [shade];
		}

	}

}


//////////////////////////////////////////////////
//	リバーシ全体を管理するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;

class Game extends Sprite {
	private static var pieces:uint = 8;
	private var board:Board;
	private var score:Score;
	private var help:Help;
	public static const INIT:String = "init";
	public static const PLAY:String = "play";
	public static const PUT:String = "put";
	public static const FINISH:String = "finish";
	public static const NO_POINT:String = "noPoint";
	public static const READY:String = "ready";
	public static const RESET:String = "reset";
	public static const NO_HELP:String = "";
	public static const MOVE:String = "move";
	public static const SELECT:String = "select";
	public static const PUT_COMPLETE:String = "putComplete";
	public static const TURN_COMPLETE:String = "turnComplete";

	public function Game() {
		init();
	}

	private function init():void {
		board = new Board();
		score = new Score();
		help = new Help();
		addChild(board);
		board.x = 22;
		board.y = 88;
		addChild(score);
		addChild(help);
		help.x = 194;
		help.y = 245;
		board.init(score, help);
	}

}


//////////////////////////////////////////////////
//	盤面を管理するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.net.navigateToURL;
import flash.net.URLRequest;
import flash.events.MouseEvent;
import flash.utils.escapeMultiByte;

class Board extends Sprite {
	private var mode:String;
	private var player:uint = 0;
	private var map:Map;
	private var score:Score;
	private var help:Help;
	private var manager:Manager;
	private var cursor:Cursor;
	private static var pieces:uint = 8;
	private static var bColor:uint = 0x336600;
	private var pointList:Array;
	private var pieceList:Array;
	private static var pid:uint = 0;
	private var completed:uint = 0;
	private static var initTime:uint = 500;
	private static var startTime:uint = 1000;
	private static var cpuTime:uint = 500;
	private static var finishTime:uint = 1000;
	private static var resetTime:uint = 500;
	private var cpu:Object;
	private var turns:uint;
	private var passed1:Boolean = false;
	private var passed2:Boolean = false;
	//サウンド
	private var seready:SoundEffect;
	private var seput:SoundEffect;
	private var seturn:SoundEffect;
	private var sefanfare:SoundEffect;
	private var seclaps:SoundEffect;
	private var sefailure:SoundEffect;
	private var source1:String = "http://www.project-nya.jp/images/flash/reversi/ready.mp3";
	private var source2:String = "http://www.project-nya.jp/images/flash/reversi/put.mp3";
	private var source3:String = "http://www.project-nya.jp/images/flash/reversi/turn.mp3";
	private var source4:String = "http://www.project-nya.jp/images/flash/reversi/fanfare.mp3";
	private var source5:String = "http://www.project-nya.jp/images/flash/reversi/claps.mp3";
	private var source6:String = "http://www.project-nya.jp/images/flash/reversi/failure.mp3";
	//twitter
	private var twitterBtn:Btn;
	private static var twitterPath:String = "http://twitter.com/home/?status=";
	private var msgs:Array = new Array();
	private var result:String;
	private static var tag:String = " http://wonderfl.net/c/pjMb"


	public function Board() {
		draw();
		seready = new SoundEffect();
		seput = new SoundEffect();
		seturn = new SoundEffect();
		sefanfare = new SoundEffect();
		seclaps = new SoundEffect();
		sefailure = new SoundEffect();
	}

	public function init(s:Score, h:Help):void {
		score = s;
		help = h;
		seready.load(source1, "ready");
		seput.load(source2, "put");
		seturn.load(source3, "turn");
		sefanfare.load(source4, "fanfare");
		seclaps.load(source5, "claps");
		sefailure.load(source6, "failure");
		reset(null);
	}
	//カーソル位置にコマを配置する(キー設定)
	private function initialize():void {
		manager = new Manager(this);
		addChild(manager);
		manager.addEventListener(Game.READY, readySelect, false, 0, true);
		manager.addEventListener(Game.MOVE, moveCursor, false, 0, true);
		manager.addEventListener(Game.SELECT, selectCursor, false, 0, true);
		manager.addEventListener(Game.RESET, resetSelect, false, 0, true);
		manager.enable = false;
		cpu = new Object();
	}
	private function reset(evt:TimerEvent):void {
		if (evt) evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, reset);
		initialize();
		map = new Map();
		score.init();
		mode = Game.INIT;
		score.showMessage(mode);
		help.show("ready?");
		score.resetTime();
		seready.play("ready", 1);
		manager.help = Game.READY;
		if (pieceList) clearPieces();
		pieceList = new Array();
	}
	private function readySelect(evt:Event):void {
		manager.help = Game.NO_HELP;
		var timer:Timer = new Timer(initTime, 1);
		timer.addEventListener(TimerEvent.TIMER_COMPLETE, start, false, 0, true);
		timer.start();
		help.hide();
	}
	private function start(evt:TimerEvent):void {
		evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, start);
		score.startTime();
		putPiece(1, 3, 3);
		putPiece(2, 3, 4);
		putPiece(1, 4, 4);
		putPiece(2, 4, 3);
	}
	//盤面にコマを配置する
	private function put(px:uint, py:uint):void {
		if (map.getPoint(px, py)) {
			if (map.getHint(px, py)) {
				switch (player) {
				case 1 :
					putPiece(player, px, py);
					break;
				case 2 :
					cpuPiece(player, px, py);
					var timer:Timer = new Timer(cpuTime, 1);
					timer.addEventListener(TimerEvent.TIMER_COMPLETE, cpuPut, false, 0, true);
					timer.start();
					break;
				}
			} else {
				score.showMessage(Game.NO_POINT);
			}
		} else {
			score.showMessage(Game.NO_POINT);
		}
	}
	//盤面にコマを配置する(配置可能なマスに)
	private function putPiece(p:uint, px:uint, py:uint):void {
		//trace("[#"+player+"] ("+px+", "+py+")");
		var point:Point = pointList[px+py*pieces];
		var xPos:uint = point.x;
		var yPos:uint = point.y;
		var id:uint = px+py*pieces;
		var piece:Piece = new Piece();
		addChild(piece);
		piece.id = id;
		piece.px = px;
		piece.py = py;
		piece.x = xPos;
		piece.y = yPos;
		pieceList[id] = piece;
		piece.addEventListener(Game.PUT_COMPLETE, putComplete, false, 0, true);
		piece.addEventListener(Game.TURN_COMPLETE, turnComplete, false, 0, true);
		piece.put(p);
		score.put(p);
		map.put(p, px, py);
		seput.play("put", 1);
		hideHint();
		pid ++;
		manager.enable = false;
	}
	private function cpuPiece(p:uint, px:uint, py:uint):void {
		cpu = {p: p, px: px, py: py};
	}
	private function cpuPut(evt:TimerEvent):void {
		evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, cpuPut);
		putPiece(cpu.p, cpu.px, cpu.py);
	}
	private function clearPieces():void {
		for (var px:uint = 0; px < pieces; px++) {
			for (var py:uint = 0; py < pieces; py++) {
				var piece:Piece = pieceList[px+py*pieces];
				if (piece) removeChild(piece);
				piece = null;
			}
		}
		pid = 0;
	}
	//コマ配置後の処理
	private function putComplete(evt:Event):void {
		switch (mode) {
			case Game.INIT :
				completed ++;
				if (completed == 4) {
					completed = 0;
					mode = Game.PLAY;
					score.showMessage(mode);
					player = 2;
					var timer:Timer = new Timer(startTime, 1);
					timer.addEventListener(TimerEvent.TIMER_COMPLETE, prepare, false, 0, true);
					timer.start();
				}
				break;
			case Game.PLAY :
				turn(evt.target.px, evt.target.py);
				break;
		}
	}
	//反転するコマ情報を取得する
	private function turn(px:uint, py:uint):void {
		var list:Array = map.getTurnList(player, px, py);
		turns = list.length;
		if (turns > 0) {
			turnPieces(player, list);
			seturn.play("turn", 1);
		}
	}
	//コマを反転する
	private function turnPieces(p:uint, list:Array):void {
		for (var n:uint = 0; n < list.length; n++) {
			var tx:uint = list[n].x;
			var ty:uint = list[n].y;
			var piece:Piece = pieceList[tx+ty*pieces];
			piece.turn();
			score.turn(p);
			map.put(p, tx, ty);
		}
	}
	//コマ反転後の処理
	private function turnComplete(evt:Event):void {
		completed ++;
		if (completed == turns) {
			completed = 0;
			if (pid < pieces*pieces) {
				prepare(null);
			} else {
				finish();
			}
		}
	}
	//攻守交代
	private function prepare(evt:TimerEvent):void {
		if (evt) evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, prepare);
		player = player%2 + 1;
		switch (player) {
			case 1 :
				score.showMessage(Game.PUT, player, passed2);
				map.getBestPrio(player);
				if (showHint()) {
					if (!cursor) {
						cursor = new Cursor();
						addChild(cursor);
						setCursor(4, 4);
						manager.setCursor(4, 4);
					}
					manager.enable = true;
					passed1 = false;
				} else {
					passed1 = true;
				}
				break;
			case 2 :
				score.showMessage(Game.PUT, player, passed1);
				var best:Object = map.getBestPrio(player);
				if (!isNaN(best.x) && !isNaN(best.y)) {
					manager.autoCursor(best.x, best.y);
					passed2 = false;
				} else {
					passed2 = true;
				}
				break;
		}
		if (passed1 && passed2) {
			finish();
		} else if ((player == 1 && passed1) || (player == 2 && passed2)) {
			prepare(null);
		}
	}
	private function moveCursor(evt:Event):void {
		setCursor(evt.target.cx, evt.target.cy);
	}
	private function selectCursor(evt:Event):void {
		put(evt.target.cx, evt.target.cy);
	}
	//盤面にカーソルを配置する
	private function setCursor(cx:uint, cy:uint):void {
		var point:Point = pointList[cx+cy*pieces];
		var xPos:uint = point.x;
		var yPos:uint = point.y;
		cursor.x = xPos;
		cursor.y = yPos;
	}
	//ヒントを表示する
	private function showHint():Boolean {
		var hint:uint = 0;
		for (var px:uint = 0; px < pieces; px++) {
			for (var py:uint = 0; py < pieces; py++) {
				var point:Point = pointList[px+py*pieces];
				if (map.getHint(px, py)) {
					hint ++;
					point.hint();
				} else {
					point.init();
				}
			}
		}
		if (hint > 0) {
			return true;
		} else {
			return false;
		}
	}
	//ヒントを非表示にする
	private function hideHint():void {
		for (var px:uint = 0; px < pieces; px++) {
			for (var py:uint = 0; py < pieces; py++) {
				var point:Point = pointList[px+py*pieces];
				point.init();
			}
		}
	}
	//ゲーム終了の処理
	private function finish():void {
		mode = Game.FINISH;
		score.showMessage(mode);
		score.showScore(mode);
		var timer:Timer = new Timer(finishTime, 1);
		timer.addEventListener(TimerEvent.TIMER_COMPLETE, showHelp, false, 0, true);
		timer.start();
		score.stopTime();
		player = 0;
		passed1 = false;
		passed2 = false;
	}
	private function showHelp(evt:TimerEvent):void {
		evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, showHelp);
		var scr:Array = score.getScore();
		var p1:uint = scr[0];
		var p2:uint = scr[1];
		//twitter
		result = String(p1) + ":" + String(p2);
		if (p1 > p2) {
			help.show("    win!");
			sefanfare.play("fanfare", 1);
			msgs = ["   は   に ", " で勝ったよ!"];
		} else if (p1 == p2) {
			help.show("draw");
			seclaps.play("claps", 1);
			msgs = ["   は   と ", " の引き分けでした。"];
		} else {
			help.show("    lose");
			sefailure.play("failure", 1);
			msgs = ["   は   に ", " で負けました..."];
		}
		removeChild(cursor);
		cursor = null;
		manager.help = Game.RESET;
	}
	private function resetSelect(evt:Event):void {
		manager.help = Game.NO_HELP;
		var timer:Timer = new Timer(resetTime, 1);
		timer.addEventListener(TimerEvent.TIMER_COMPLETE, reset, false, 0, true);
		timer.start();
		help.hide();
	}
	private function draw():void {
		graphics.beginFill(bColor);
		graphics.drawRect(-2, -2, 340, 340);
		graphics.endFill();
		pointList = new Array();
		for (var px:uint = 0; px < pieces; px++) {
			for (var py:uint = 0; py < pieces; py++) {
				var point:Point = new Point();
				addChild(point);
				var id:uint = px+py*pieces;
				point.id = id;
				pointList[id] = point;
				point.x = 21 + 42*px;
				point.y = 21 + 42*py;
				point.init();
			}
		}
		for (var cx:uint = 0; cx < 2; cx++) {
			for (var cy:uint = 0; cy < 2; cy++) {
				var corner:Shape = new Shape();
				addChild(corner);
				corner.graphics.beginFill(bColor);
				corner.graphics.drawCircle(0, 0, 4);
				corner.graphics.endFill();
				corner.x = 84 + 168*cx;
				corner.y = 84 + 168*cy;
			}
		}
		//twitter
		twitterBtn = new Btn();
		addChild(twitterBtn);
		twitterBtn.x = 365;
		twitterBtn.y = 350;
		twitterBtn.init({label: "twitter"});
		twitterBtn.addEventListener(MouseEvent.CLICK, twitter, false, 0, true);
	}
	//twitter対応
	private function twitter(evt:MouseEvent):void {
		var msg:String = "";
		switch (mode) {
			case Game.INIT :
				msg = "ゲームを開始します。";
				break;
			case Game.PLAY :
				msg = "ゲーム中です。";
				break;
			case Game.FINISH :
				msg = msgs[0] + result + msgs[1];
				break;
		}
		navigateToURL(new URLRequest(twitterPath + escapeMultiByte(msg + tag)), "_blank");			
	}

}


//////////////////////////////////////////////////
//	盤面上のコマの位置を管理するクラス
//////////////////////////////////////////////////

class Map {
	private static var pieces:uint = 8;
	//空マップ
	private var aMap:Array;
	//盤面上のコマ配置マップ
	private var bMap:Array;
	//優先度マップ
	private var pMap:Array;
	//走査マップ
	private var cMap:Array;
	//ヒント表示マップ
	private var hMap:Array;

	public function Map() {
		init();
	}

	private function init():void {
		aMap = new Array();
		aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
		aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
		aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
		aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
		aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
		aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
		aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
		aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
		bMap = copyMap(aMap);
		cMap = copyMap(aMap);
		pMap = new Array();
		pMap.push([7, 0, 5, 6, 6, 5, 0, 7]);
		pMap.push([0, 0, 2, 3, 3, 2, 0, 0]);
		pMap.push([5, 2, 5, 4, 4, 5, 2, 5]);
		pMap.push([6, 3, 4, 4 ,4, 4, 3, 6]);
		pMap.push([6, 3, 4, 4 ,4, 4, 3, 6]);
		pMap.push([5, 2, 5, 4, 4, 5, 2, 5]);
		pMap.push([0, 0, 2, 3, 3, 2, 0, 0]);
		pMap.push([7, 0, 5, 6, 6, 5, 0, 7]);
	}
	private function copyMap(list:Array):Array {
		var map:Array = new Array();
		for (var n:uint = 0; n < list.length; n++) {
			map[n] = list[n].concat();
		}
		return map;
	}
	//コマの配置をマップに設定する
	public function put(p:uint, x:uint, y:uint):void {
		bMap[y][x] = p;
		cMap[y][x] = p;
		for (var cx:int = x-1; cx <= x+1; cx++) {
			for (var cy:int = y-1; cy <= y+1; cy++) {
				if (cx >= 0 && cx < pieces && cy >= 0 && cy < pieces) {
					var player:Object = bMap[cy][cx];
					player = (player == 0) ? "*" : player;
					cMap[cy][cx] = player;
				}
			}
		}
	}
	//配置可能なマスかどうかを判定する
	public function getPoint(x:uint, y:uint):Boolean {
		if (bMap[y][x] == 0) {
			return true;
		} else {
			return false;
		}
	}
	//走査対象のコマかどうかを判定する
	private function getCheck(x:uint, y:uint):Boolean {
		var check:Object = cMap[y][x];
		if (check == "*") {
			return true;
		} else {
			return false;
		}
	}
	//ヒント表示するコマかどうかを判定する
	public function getHint(x:uint, y:uint):Boolean {
		var hint:Object = hMap[y][x];
		if (hint == "*") {
			return true;
		} else {
			return false;
		}
	}
	//優先順位の高いマスを取得する({x: 0, y: 0}で返す)
	public function getBestPrio(p:uint):Object {
		var px:Number = undefined;
		var py:Number = undefined;
		var best:uint = 0;
		hMap = copyMap(aMap);
		for (var x:uint = 0; x < pieces; x++) {
			for (var y:uint = 0; y < pieces; y++) {
				if (getCheck(x, y)) {
					var prio:uint = pMap[y][x];
					var turns:uint = getTurns(p, x, y);
					if (turns > 0) {
						hMap[y][x] = "*";
						prio += turns;
						/*
						if (best < prio) {
							px = x;
							py = y;
							best = prio;
						} else if (best == prio) {
							if (Math.random() > 0.5) {
								px = x;
								py = y;
								best = prio;
							}
						}
						*/
						if (best <= prio) {
							px = x;
							py = y;
							best = prio;
						}
					}
				}
			}
		}
		return {x: px, y: py};
	}
	//指定したマスの8方向に対して反転できるコマ数を取得する
	public function getTurns(p:uint, x:uint, y:uint):uint {
		var turns:uint = 0;
		for (var dx:int = -1; dx <= 1; dx++) {
			for (var dy:int = -1; dy <= 1; dy++) {
			if (dx == 0 && dy == 0) continue;
				var px:int = x + dx;
				var py:int = y + dy;
				while (px >= 0 && px < pieces && py >= 0 && py < pieces) {
					var player:uint = bMap[py][px];
					if (player == 0) break;
					if (player == p) {
						if (dx != 0) {
							turns += dx*(px - x) - 1;
						} else {
							turns += dy*(py - y) - 1;
						}
						break;
					}
					px += dx;
					py += dy;
				}
			}
		}
		return turns;
	}
	//反転するコマ情報を取得する
	public function getTurnList(p:uint, x:uint, y:uint):Array {
		var list:Array = new Array();
		for (var dx:int = -1; dx <= 1; dx++) {
			for (var dy:int = -1; dy <= 1; dy++) {
				if (dx == 0 && dy == 0) continue;
				var px:int = x + dx;
				var py:int = y + dy;
				var checking:Boolean = true;
				while (px >= 0 && px < pieces && py >= 0 && py < pieces) {
					var player:uint = bMap[py][px];
					if (player == 0) break;
					if (player == p) {
						if (checking) {
							px = x + dx;
							py = y + dy;
							checking = false;
							continue;
						} else {
							break;
						}
					}
					if (!checking && player != p) {
						list.push({x: px, y: py});
					}
					px += dx;
					py += dy;
				}
			}
		}
		return list;
	}

}


//////////////////////////////////////////////////
//	コマの動きを管理するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;

class Piece extends Sprite {
	public var id:uint;
	public var px:uint;
	public var py:uint;
	private var piece1:PieceShape;
	private var piece2:PieceShape;
	private var scale:Number = 1;
	private var light:Shape;
	private var _brightness:Number = 0;

	public function Piece() {
		draw();
	}

	public function put(p:uint):void {
		id = p;
		var piece:PieceShape = this["piece"+id];
		addChild(piece);
		piece.scaleX = piece.scaleY = scale = 1.6;
		addEventListener(Event.ENTER_FRAME, putPiece, false, 0, true);
	}
	private function putPiece(evt:Event):void {
		var piece:PieceShape = this["piece"+id];
		scale -= 0.1;
		piece.scaleX = piece.scaleY = scale;
		if (scale <= 1) {
			piece.scaleX = piece.scaleY = scale = 1;
			removeEventListener(Event.ENTER_FRAME, putPiece);
			dispatchEvent(new Event(Game.PUT_COMPLETE))
		}
	}
	public function turn():void {
		var old:PieceShape = this["piece"+id];
		removeChild(old);
		id = id%2 + 1;
		var piece:PieceShape = this["piece"+id];
		addChild(piece);
		addChild(light);
		var timer:Timer = new Timer(50, 6);
		timer.addEventListener(TimerEvent.TIMER, turnPiece, false, 0, true);
		timer.addEventListener(TimerEvent.TIMER_COMPLETE, motion, false, 0, true);
		timer.start();
	}
	private function turnPiece(evt:TimerEvent):void {
		if (evt.target.currentCount == 4) {
			evt.target.removeEventListener(TimerEvent.TIMER, turnPiece);
			removeChild(light);
		}
	}
	private function motion(evt:TimerEvent):void {
		evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, motion);
		brightness = 100;
		addEventListener(Event.ENTER_FRAME, bright, false, 0, true);
	}
	private function bright(evt:Event):void {
		brightness -= 20;
		if (brightness <= 0) {
			brightness = 0;
			removeEventListener(Event.ENTER_FRAME, bright);
			dispatchEvent(new Event(Game.TURN_COMPLETE))
		}
	}
	private function draw():void {
		/*
		graphics.beginFill(0x000000);
		graphics.drawCircle(0, 0, 20);
		graphics.endFill();
		//*/
		piece1 = new PieceShape(1);
		piece2 = new PieceShape(2);
		light = new Shape();
		light.graphics.beginFill(0xFFFFFF);
		light.graphics.drawCircle(0, 0, 20);
		light.graphics.drawCircle(0, 0, 15);
		light.graphics.endFill();
	}
	private function get brightness():Number {
		return _brightness;
	}
	private function set brightness(param:Number):void {
		_brightness = param;
		ColorManager.brightOffset(this, _brightness);
	}

}


//////////////////////////////////////////////////
//	コマを描画するクラス
//////////////////////////////////////////////////

import flash.display.Shape;
import flash.geom.Matrix;
import flash.display.GradientType;
import flash.display.SpreadMethod;
import flash.display.InterpolationMethod;

class PieceShape extends Shape {
	private var type:uint = 1;
	private static var cList:Array = [[0x888888, 0x000000], [0xFFFFFF, 0xBBBBBB]];
	private static var bList:Array = [0x444444, 0xDDDDDD];

	public function PieceShape(t:uint) {
		type = t;
		//draw();
	}

	private function draw():void {
		var colors:Array = cList[1];
		var alphas:Array = [1, 1];
		var ratios:Array = [0, 255];
		var matrix:Matrix = new Matrix();
		matrix.createGradientBox(36, 36, 0.25*Math.PI, -18, -18);
		graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix, SpreadMethod.PAD, InterpolationMethod.RGB, 0);
		graphics.drawCircle(0, 0, 18);
		graphics.endFill();
		var bColor:uint = bList[1];
		graphics.beginFill(bColor);
		graphics.drawCircle(0, 0, 15);
		graphics.endFill();
	}

}


//////////////////////////////////////////////////
//	マスを着色するクラス
//////////////////////////////////////////////////

import flash.display.Shape;
import flash.geom.ColorTransform;

class Point extends Shape {
	public var id:uint;
	private static var bColor:uint = 0x66CC00;
	private static var cColor:uint = 0x66CCFF;
	private static var bColorTrans:ColorTransform;
	private static var cColorTrans:ColorTransform;

	public function Point() {
		draw();
	}

	public function init():void {
		transform.colorTransform = bColorTrans;
	}
	public function hint():void {
		transform.colorTransform = cColorTrans;
	}
	private function draw():void {
		graphics.beginFill(0xFFFFFF);
		graphics.drawRect(-20, -20, 40, 40);
		graphics.endFill();
		bColorTrans = new ColorTransform(0, 0, 0, 1, 0, 0, 0, 0);
		bColorTrans.color = bColor;
		cColorTrans = new ColorTransform(0, 0, 0, 1, 0, 0, 0, 0);
		cColorTrans.color = cColor;
	}

}


//////////////////////////////////////////////////
//	得点を管理するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.DropShadowFilter;

class Score extends Sprite {
	private var pieces1:uint = 0;
	private var pieces2:uint = 0;
	private var score1:TextField;
	private var score2:TextField;
	private var count:TextField;
	private var message:TextField;
	private var player:Array;
	private var msgs:Object;
	private var time:Time;
	private var txt:TextField;
	private static var bColor:uint = 0xFFFF00;
	private static var sColor:uint = 0x000000;
	private static var b1Color:uint = 0x66CC00;
	private static var b2Color:uint = 0xFFFFFF;
	private static var fontType:String = "_ゴシック";
	//private static var initMsg:String = "ゲームを初期化しています。";
	private static var initMsg:String = "Enterキー・上下左右キーで操作してください。";
	private static var playMsg:String = "ゲームを開始します。";
	private static var putMsg:String = "の番です。";
	private static var passMsg:String = "はパス。";
	private static var finishMsg:String = "ゲームは終了しました。";
	private static var noPointMsg:String = "そのマスにはコマを置けません。";

	public function Score() {
		draw();
		initialize();
	}

	private function initialize():void {
		msgs = new Object();
		msgs[Game.INIT] = initMsg;
		msgs[Game.PLAY] = playMsg;
		msgs[Game.PUT] = putMsg;
		msgs[Game.FINISH] = finishMsg;
		msgs[Game.NO_POINT] = noPointMsg;
		player = new Array();
		player[1] = "   ";
		player[2] = "あなたじゃない   ";
		time = new Time(txt);
	}
	public function init():void {
		pieces1 = 0;
		pieces2 = 0;
		showScore();
	}
	public function put(p:uint):void {
		this["pieces"+p] ++;
		showScore();
	}
	public function turn(p:uint):void {
		this["pieces"+p] ++;
		var r:uint = p%2 + 1;
		this["pieces"+r] --;
		showScore();
	}
	public function showScore(mode:String = null):void {
		count.text = String(pieces1 + pieces2) + "\n----\n64";
		score1.text = mode == Game.FINISH ? String(pieces1) : "?";
		score2.text = mode == Game.FINISH ? String(pieces2) : "?";
	}
	public function showMessage(mode:String, p:uint = 0, passed:Boolean = false):void {
		switch (mode) {
			case Game.PUT :
				if (!passed) {
					message.text = player[p] + msgs[mode];
				} else {
					var r:uint = p%2 + 1;
					message.text = player[r] + passMsg + player[p] + msgs[mode];
				}
				break;
			default :
				message.text = msgs[mode];
				break;
		}
	}
	public function getScore():Array {
		return [pieces1, pieces2];
	}
	public function startTime():void {
		time.start();
	}
	public function stopTime():void {
		time.stop();
	}
	public function resetTime():void {
		time.reset();
	}
	private function draw():void {
		graphics.beginFill(bColor);
		graphics.drawRect(20, 56, 340, 24);
		graphics.endFill();
		graphics.beginFill(b1Color);
		graphics.drawRoundRect(256, 0, 104, 44, 12);
		graphics.endFill();
		graphics.beginFill(b2Color);
		graphics.drawRoundRect(258, 2, 100, 40, 8);
		graphics.endFill();
		var piece1:PieceShape = new PieceShape(1);
		addChild(piece1);
		piece1.x = 288;
		piece1.y = 29;
		piece1.width = piece1.height = 24;
		var piece2:PieceShape = new PieceShape(2);
		addChild(piece2);
		piece2.x = 328;
		piece2.y = 29;
		piece2.width = piece2.height = 24;
		var shade:DropShadowFilter = new DropShadowFilter(1, 90, sColor, 0.3, 2, 2, 2, 2, false, false);
		filters = [shade];
		drawText();
	}
	private function drawText():void {
		var tf:TextFormat = new TextFormat();
		tf.font = "_ゴシック";
		tf.size = 12;
		tf.align = TextFormatAlign.LEFT;
		message = new TextField();
		addChild(message);
		message.x = 30;
		message.y = 59;
		message.width = 404;
		message.height = 21;
		message.type = TextFieldType.DYNAMIC;
		message.selectable = false;
		message.antiAliasType = AntiAliasType.ADVANCED;
		message.defaultTextFormat = tf;
		message.textColor = 0x000000;
		var shade:DropShadowFilter = new DropShadowFilter(1, 90, sColor, 0.4, 2, 2, 2, 2, false, false);
		var tfn:TextFormat = new TextFormat();
		tfn.font = fontType;
		tfn.size = 12;
		tfn.align = TextFormatAlign.CENTER;
		var name1:TextField = new TextField();
		addChild(name1);
		name1.x = 260;
		name1.y = 1;
		name1.width = 30;
		name1.height = 19;
		name1.type = TextFieldType.DYNAMIC;
		name1.selectable = false;
		//name1.embedFonts = true;
		//name1.antiAliasType = AntiAliasType.ADVANCED;
		name1.defaultTextFormat = tfn;
		name1.textColor = 0x000000;
		name1.text = "You";
		name1.filters = [shade];
		var name2:TextField = new TextField();
		addChild(name2);
		name2.x = 290;
		name2.y = 1;
		name2.width = 30;
		name2.height = 19;
		name2.type = TextFieldType.DYNAMIC;
		name2.selectable = false;
		//name2.embedFonts = true;
		//name2.antiAliasType = AntiAliasType.ADVANCED;
		name2.defaultTextFormat = tfn;
		name2.textColor = 0x000000;
		name2.text = "CPU";
		name2.filters = [shade];
		var tfc:TextFormat = new TextFormat();
		tfc.font = fontType;
		tfc.size = 14;
		tfc.align = TextFormatAlign.CENTER;
		score1 = new TextField();
		addChild(score1);
		score1.x = 260;
		score1.y = 19;
		score1.width = 30;
		score1.height = 23;
		score1.type = TextFieldType.DYNAMIC;
		score1.selectable = false;
		//score1.embedFonts = true;
		//score1.antiAliasType = AntiAliasType.ADVANCED;
		score1.defaultTextFormat = tfc;
		score1.textColor = 0;
		score1.text = String(0);
		score2 = new TextField();
		addChild(score2);
		score2.x = 290;
		score2.y = 19;
		score2.width = 30;
		score2.height = 23;
		score2.type = TextFieldType.DYNAMIC;
		score2.selectable = false;
		//score2.embedFonts = true;
		//score2.antiAliasType = AntiAliasType.ADVANCED;
		score2.defaultTextFormat = tfc;
		score2.textColor = 0;
		score2.text = String(0);
		count = new TextField();
		addChild(count);
		count.x = 285;
		count.y = 1;
		count.type = TextFieldType.DYNAMIC;
		count.selectable = false;
		count.autoSize = "center";
		count.defaultTextFormat = tfn;
		count.textColor = 0x000000;
		count.text = "5\n----\n64";
		count.filters = [shade];
		var tft:TextFormat = new TextFormat();
		tft.font = fontType;
		tft.size = 16;
		tft.align = TextFormatAlign.LEFT;
		var timer:TextField = new TextField();
		addChild(timer);
		timer.x = 140;
		timer.y = 18;
		timer.width = 40;
		timer.height = 21;
		timer.type = TextFieldType.DYNAMIC;
		timer.selectable = false;
		//timer.embedFonts = true;
		//timer.antiAliasType = AntiAliasType.ADVANCED;
		timer.defaultTextFormat = tft;
		timer.textColor = 0xFFFFFF;
		timer.text = "Time";
		txt = new TextField();
		addChild(txt);
		txt.x = 185;
		txt.y = 18;
		txt.width = 55;
		txt.height = 21;
		txt.type = TextFieldType.DYNAMIC;
		txt.selectable = false;
		//txt.embedFonts = true;
		//txt.antiAliasType = AntiAliasType.ADVANCED;
		txt.defaultTextFormat = tft;
		txt.textColor = 0xFFFFFF;
		txt.text = "00:00";
	}

}


//////////////////////////////////////////////////
//	タイマーを管理するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.text.TextField;
import flash.utils.getTimer;
import flash.utils.Timer;
import flash.events.TimerEvent;

class Time extends Sprite {
	private var target:TextField;
	private var startTime:uint;
	private var timer:Timer;
	private var countTime:uint = 30;

	public function Time(tg:TextField) {
		target = tg;
	}

	public function start():void {
		startTime = getTimer();
		timer = new Timer(countTime);
		timer.addEventListener(TimerEvent.TIMER, count, false, 0, true);
		timer.start();
	}
	private function count(evt:TimerEvent):void {
		var sec:uint = Math.floor((getTimer() - startTime)/1000);
		var min:String  = String(Math.floor(sec/60));
		min = (uint(min) < 10) ? "0" + min : min;
		var msec:String = String(sec%60);
		msec = (uint(msec) < 10) ? "0" + msec : msec;
		target.text = min + ":" + msec;
	}
	public function stop():void {
		timer.removeEventListener(TimerEvent.TIMER, count);
	}
	public function reset():void {
		target.text = "00:00";
	}

}


//////////////////////////////////////////////////
//	カーソル操作を管理するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.events.Event;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;

class Manager extends Sprite {
	private var board:Board;
	private static var pieces:uint = 8;
	public var cx:int;
	public var cy:int;
	private var tx:uint;
	private var ty:uint;
	private var cpu:Object;
	private static var autoTime:uint = 200;
	private var helpMode:String = "";
	private var keyMode:Boolean = false;

	public function Manager(b:Board) {
		board = b;
		if (stage) init();
		else addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
	}

	private function init(evt:Event = null):void {
		removeEventListener(Event.ADDED_TO_STAGE, init);
		cpu = new Object();
		stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown, false, 0, true);
	}
	//カーソル位置を設定する
	public function setCursor(x:uint, y:uint):void {
		cx = x;
		cy = y;
	}
	//キー操作の処理
	private function keyDown(evt:KeyboardEvent):void {
		if (helpMode) {
			if (evt.keyCode == Keyboard.ENTER) {
				dispatchEvent(new Event(helpMode));
			}
		}
		if (keyMode) {
			switch (evt.keyCode) {
				case Keyboard.ENTER :
					dispatchEvent(new Event(Game.SELECT));
					break;
				case Keyboard.LEFT :
					cx --;
					break;
				case Keyboard.UP :
					cy --;
					break;
				case Keyboard.RIGHT :
					cx ++;
					break;
				case Keyboard.DOWN :
					cy ++;
					break;
			}
			if (cx > pieces - 1) cx = 0;
			if (cx < 0) cx = pieces - 1;
			if (cy > pieces - 1) cy = 0;
			if (cy < 0) cy = pieces - 1;
			dispatchEvent(new Event(Game.MOVE));
		}
	}
	//カーソル位置を移動する
	public function autoCursor(px:uint, py:uint):void {
		tx = px;
		ty = py;
		var timer:Timer = new Timer(autoTime);
		timer.addEventListener(TimerEvent.TIMER, moveCursor, false, 0, true);
		timer.start();
	}
	private function moveCursor(evt:TimerEvent):void {
		var mx:int = uint(tx > cx) - uint(tx < cx);
		var my:int = uint(ty > cy) - uint(ty < cy);
		if (mx != 0 || my != 0) {
			cx += mx;
			cy += my;
			dispatchEvent(new Event(Game.MOVE));
			if (cx == tx && cy == ty) {
				evt.target.removeEventListener(TimerEvent.TIMER, moveCursor);
				dispatchEvent(new Event(Game.SELECT));
			}
		}
	}
	public function set enable(param:Boolean):void {
		keyMode = param;
	}
	public function set help(param:String):void {
		helpMode = param;
	}

}


//////////////////////////////////////////////////
//	カーソルを描画するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.display.Shape;
import flash.utils.Timer;
import flash.events.TimerEvent;

class Cursor extends Sprite {
	private var id:uint = 0;
	private var cursor0:Shape;
	private var cursor1:Shape;
	private static var bColor:uint = 0x66CC00;
	private static var cColor:uint = 0x66CCFF;

	public function Cursor() {
		draw();
		init();
	}

	private function init():void {
		var cursor:Shape = this["cursor"+id];
		addChild(cursor);
		var timer:Timer = new Timer(250);
		timer.addEventListener(TimerEvent.TIMER, change, false, 0, true);
		timer.start();
	}
	private function change(evt:TimerEvent):void {
		var old:Shape = this["cursor"+id];
		removeChild(old);
		id = (id+1)%2;
		var cursor:Shape = this["cursor"+id];
		addChild(cursor);
	}
	private function draw():void {
		cursor0 = new Shape();
		cursor0.graphics.beginFill(0xFFFFFF);
		cursor0.graphics.moveTo(-21, -21);
		cursor0.graphics.lineTo(-21, -6);
		cursor0.graphics.lineTo(-18, -6);
		cursor0.graphics.lineTo(-18, -18);
		cursor0.graphics.lineTo(-6, -18);
		cursor0.graphics.lineTo(-6, -21);
		cursor0.graphics.lineTo(-21, -21);
		cursor0.graphics.moveTo(21, -21);
		cursor0.graphics.lineTo(21, -6);
		cursor0.graphics.lineTo(18, -6);
		cursor0.graphics.lineTo(18, -18);
		cursor0.graphics.lineTo(6, -18);
		cursor0.graphics.lineTo(6, -21);
		cursor0.graphics.lineTo(21, -21);
		cursor0.graphics.moveTo(-21, 21);
		cursor0.graphics.lineTo(-21, 6);
		cursor0.graphics.lineTo(-18, 6);
		cursor0.graphics.lineTo(-18, 18);
		cursor0.graphics.lineTo(-6, 18);
		cursor0.graphics.lineTo(-6, 21);
		cursor0.graphics.lineTo(-21, 21);
		cursor0.graphics.moveTo(21, 21);
		cursor0.graphics.lineTo(21, 6);
		cursor0.graphics.lineTo(18, 6);
		cursor0.graphics.lineTo(18, 18);
		cursor0.graphics.lineTo(6, 18);
		cursor0.graphics.lineTo(6, 21);
		cursor0.graphics.lineTo(21, 21);
		cursor0.graphics.endFill();
		cursor1 = new Shape();
		cursor1.graphics.beginFill(0xFFFFFF);
		cursor1.graphics.moveTo(-22, -22);
		cursor1.graphics.lineTo(-22, -7);
		cursor1.graphics.lineTo(-19, -7);
		cursor1.graphics.lineTo(-19, -19);
		cursor1.graphics.lineTo(-7, -19);
		cursor1.graphics.lineTo(-7, -22);
		cursor1.graphics.lineTo(-22, -22);
		cursor1.graphics.moveTo(22, -22);
		cursor1.graphics.lineTo(22, -7);
		cursor1.graphics.lineTo(19, -7);
		cursor1.graphics.lineTo(19, -19);
		cursor1.graphics.lineTo(7, -19);
		cursor1.graphics.lineTo(7, -22);
		cursor1.graphics.lineTo(22, -22);
		cursor1.graphics.moveTo(-22, 22);
		cursor1.graphics.lineTo(-22, 7);
		cursor1.graphics.lineTo(-19, 7);
		cursor1.graphics.lineTo(-19, 19);
		cursor1.graphics.lineTo(-7, 19);
		cursor1.graphics.lineTo(-7, 22);
		cursor1.graphics.lineTo(-22, 22);
		cursor1.graphics.moveTo(22, 22);
		cursor1.graphics.lineTo(22, 7);
		cursor1.graphics.lineTo(19, 7);
		cursor1.graphics.lineTo(19, 19);
		cursor1.graphics.lineTo(7, 19);
		cursor1.graphics.lineTo(7, 22);
		cursor1.graphics.lineTo(22, 22);
		cursor1.graphics.endFill();
	}

}


//////////////////////////////////////////////////
//	ヘルプ表示を管理するクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.GlowFilter;

class Help extends Sprite {
	private var amplitude:Number = 0;
	private var scale:Number = 1;
	private static var targetScale:Number = 2;
	private static var deceleration:Number = 0.5;
	private static var friction:Number = 0.6;
	private var txt:TextField;
	private static var tColor:uint = 0x000000;
	private static var gColor:uint = 0xFFFFFF;
	private static var fontType:String = "_ゴシック";

	public function Help() {
		draw();
		hide();
	}

	public function hide():void {
		visible = false;
	}
	public function show(help:String):void {
		txt.text = help;
		visible = true;
		amplitude = 0;
		scale = 1;
		addEventListener(Event.ENTER_FRAME, elastic, false, 0, true);
	}
	private function elastic(evt:Event):void {
		amplitude += targetScale - scale;
		scale += amplitude*friction;
		amplitude *= deceleration;
		scaleX = scaleY = scale;
		if (Math.abs(targetScale - scale) < 0.005 && Math.abs(amplitude) < 0.001) {
			scaleX = scaleY = targetScale;
			removeEventListener(Event.ENTER_FRAME, elastic);
		}
	}
	private function draw():void {
		var tf:TextFormat = new TextFormat();
		tf.font = fontType;
		tf.size = 32;
		tf.align = TextFormatAlign.CENTER;
		txt = new TextField();
		addChild(txt);
		txt.x = -75;
		txt.y = -19;
		txt.width = 150;
		txt.height = 39;
		txt.type = TextFieldType.DYNAMIC;
		txt.selectable = false;
		//txt.embedFonts = true;
		//txt.antiAliasType = AntiAliasType.ADVANCED;
		txt.defaultTextFormat = tf;
		txt.textColor = tColor;
		var glow:GlowFilter = new GlowFilter(gColor, 1, 10, 10, 10, 1, false, false);
		txt.filters = [glow];
	}

}


//////////////////////////////////////////////////
// ColorManagerクラス
//////////////////////////////////////////////////

import flash.display.DisplayObject;
import flash.geom.ColorTransform;
import flash.filters.ColorMatrixFilter;

class ColorManager {
	private static var rs:Number = 0.3086;
	private static var gs:Number = 0.6094;
	private static var bs:Number = 0.0820;

	public function ColorManager() {
	}

	public static function brightOffset(target:DisplayObject, param:Number):void {
		target.transform.colorTransform = getBrightOffset(param);
	}
	private static function getBrightOffset(param:Number):ColorTransform {
		var percent:Number = 1;
		var offset:Number = param*2.55;
		var colorTrans:ColorTransform = new ColorTransform(0, 0, 0, 1, 0, 0, 0, 0);
		colorTrans.redMultiplier = percent;
		colorTrans.greenMultiplier = percent;
		colorTrans.blueMultiplier = percent;
		colorTrans.redOffset = offset;
		colorTrans.greenOffset = offset;
		colorTrans.blueOffset = offset;
		colorTrans.alphaMultiplier = 1;
		colorTrans.alphaOffset = 0;
		return colorTrans;
	}
	public static function saturation(target:DisplayObject, param:Number):void {
		target.filters = [getSaturation(param)];
	}
	private static function getSaturation(param:Number):ColorMatrixFilter {
		var colorMatrix:ColorMatrixFilter = new ColorMatrixFilter();
		var p:Number = param*0.01;
		var r:Number = (1 - p)*rs;
		var g:Number = (1 - p)*gs;
		var b:Number = (1 - p)*bs;
		var matrix:Array = [r + p, g, b, 0, 0, r, g + p, b, 0, 0, r, g, b + p, 0, 0, 0, 0, 0, 1, 0];
		colorMatrix.matrix = matrix;
		return colorMatrix;
	}

}


//////////////////////////////////////////////////
// SoundEffectクラス
//////////////////////////////////////////////////

import flash.events.EventDispatcher;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.events.ProgressEvent;
import flash.net.URLRequest;

class SoundEffect extends EventDispatcher {
	private static var soundList:Object;
	private var sound:Sound;
	private var channel:SoundChannel;
	private static var initialized:Boolean = false;
	private var volume:Number;
	private var looping:Boolean = false;

	public function SoundEffect() {
		if (!initialized) initialize();
	}

	private static function initialize():void {
		initialized = true;
		soundList = new Object();
	}
	public function init(Snd:Class, id:String):void {
		var snd:Sound = new Snd();
		soundList[id] = snd;
	}
	public function load(file:String, id:String):void {
		var snd:Sound = new Sound();
		snd.load(new URLRequest(file));
		snd.addEventListener(ProgressEvent.PROGRESS, progress, false, 0, true);
		snd.addEventListener(Event.COMPLETE, loaded, false, 0, true);
		soundList[id] = snd;
	}
	public function play(id:String, vol:Number, loop:Boolean = false):void {
		if (channel != null) channel.stop();
		sound = soundList[id];
		volume = vol;
		looping = loop;
		channel = sound.play();
		var transform:SoundTransform = channel.soundTransform;
		transform.volume = volume;
		channel.soundTransform = transform;
		if (looping) {
			channel.addEventListener(Event.SOUND_COMPLETE, complete, false, 0, true);
		}
	}
	public function stop():void {
		if (channel != null) {
			channel.stop();
			channel.removeEventListener(Event.SOUND_COMPLETE, complete);
		}
	}
	private function progress(evt:ProgressEvent):void {
		dispatchEvent(evt);
	}
	private function loaded(evt:Event):void {
		dispatchEvent(evt);
	}
	private function complete(evt:Event):void {
		channel.removeEventListener(Event.SOUND_COMPLETE, complete);
		if (looping) {
			channel = sound.play(0);
			channel.addEventListener(Event.SOUND_COMPLETE, complete, false, 0, true);
			var transform:SoundTransform = channel.soundTransform;
			transform.volume = volume;
			channel.soundTransform = transform;
		}
	}

}


//////////////////////////////////////////////////
// Btnクラス
//////////////////////////////////////////////////

import flash.display.Sprite;
import flash.display.Shape;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.GlowFilter;
import flash.events.MouseEvent;

class Btn extends Sprite {
	public var id:uint;
	private var shade:Shape;
	private var bottom:Shape;
	private var light:Shape;
	private var base:Shape;
	private var txt:TextField;
	private var label:String = "";
	private static var fontType:String = "_ゴシック";
	private var _width:uint = 60;
	private static var _height:uint = 20;
	private static var corner:uint = 5;
	private var type:uint = 1;
	private static var bColor:uint = 0xFFFFFF;
	private static var sColor:uint = 0x000000;
	private static var upColor:uint = 0x666666;
	private static var overColor:uint = 0x333333;
	private static var offColor:uint = 0x999999;
	private static var gColor:uint = 0x0099FF;
	private var blueGlow:GlowFilter;
	private var shadeGlow:GlowFilter;
	private var _clicked:Boolean = false;
	private var _enabled:Boolean = true;

	public function Btn() {
	}

	public function init(option:Object):void {
		if (option.id != undefined) id = option.id;
		if (option.label != undefined) label = option.label;
		if (option.width != undefined) _width = option.width;
		if (option.type != undefined) type = option.type;
		draw();
	}
	private function draw():void {
		switch (type) {
		case 1 :
			bColor = 0xFFFFFF;
			sColor = 0x000000;
			upColor = 0x666666;
			overColor = 0x333333;
			offColor = 0x999999;
			break; 
		case 2 :
			bColor = 0x000000;
			sColor = 0xFFFFFF;
			upColor = 0x666666;
			overColor = 0x999999;
			offColor = 0x333333;
			break;
		}
		blueGlow = new GlowFilter(gColor, 0.6, 5, 5, 2, 3, false, true);
		shadeGlow = new GlowFilter(sColor, 0.3, 4, 4, 2, 3, false, true);
		shade = new Shape();
		bottom = new Shape();
		light = new Shape();
		base = new Shape();
		txt = new TextField();
		addChild(shade);
		addChild(bottom);
		addChild(light);
		addChild(base);
		addChild(txt);
		createBase(shade, _width, _height, corner, sColor);
		shade.filters = [shadeGlow];
		createBase(bottom, _width, _height, corner, sColor, 0.3);
		createBase(light, _width, _height, corner, gColor);
		light.filters = [blueGlow];
		createBase(base, _width, _height, corner, bColor);
		txt.x = -_width*0.5;
		txt.y = -_height*0.5;
		txt.width = _width;
		txt.height = _height - 1;
		txt.type = TextFieldType.DYNAMIC;
		txt.selectable = false;
		//txt.embedFonts = true;
		//txt.antiAliasType = AntiAliasType.ADVANCED;
		var tf:TextFormat = new TextFormat();
		tf.font = fontType;
		tf.size = 12;
		tf.align = TextFormatAlign.CENTER;
		txt.defaultTextFormat = tf;
		txt.text = label;
		enabled = true;
		mouseChildren = false;
	}
	private function rollOver(evt:MouseEvent):void {
		_over();
	}
	private function rollOut(evt:MouseEvent):void {
		_up();
	}
	private function press(evt:MouseEvent):void {
		_down();
	}
	private function release(evt:MouseEvent):void {
		_up();
	}
	private function click(evt:MouseEvent):void {
	}
	private function _up():void {
		txt.y = -_height*0.5;
		txt.textColor = upColor;
		base.y = -1;
		light.visible = false;
		light.y = -1;
	}
	private function _over():void {
		txt.y = -_height*0.5;
		txt.textColor = overColor;
		base.y = -1;
		light.visible = true;
		light.y = -1;
	}
	private function _down():void {
		txt.y = -_height*0.5 + 1;
		txt.textColor = overColor;
		base.y = 0;
		light.visible = true;
		light.y = 0;
	}
	private function _off():void {
		txt.y = -_height*0.5 + 1;
		txt.textColor = offColor;
		base.y = 0;
		light.visible = false;
		light.y = 0;
	}
	public function get clicked():Boolean {
		return _clicked;
	}
	public function set clicked(param:Boolean):void {
		_clicked = param;
		enabled = !_clicked;
		if (_clicked) {
			_down();
		} else {
			_up();
		}
	}
	public function get enabled():Boolean {
		return _enabled;
	}
	public function set enabled(param:Boolean):void {
		_enabled = param;
		buttonMode = _enabled;
		mouseEnabled = _enabled;
		useHandCursor = _enabled;
		if (_enabled) {
			_up();
			addEventListener(MouseEvent.MOUSE_OVER, rollOver, false, 0, true);
			addEventListener(MouseEvent.MOUSE_OUT, rollOut, false, 0, true);
			addEventListener(MouseEvent.MOUSE_DOWN, press, false, 0, true);
			addEventListener(MouseEvent.MOUSE_UP, release, false, 0, true);
			addEventListener(MouseEvent.CLICK, click, false, 0, true);
		} else {
			_off();
			removeEventListener(MouseEvent.MOUSE_OVER, rollOver);
			removeEventListener(MouseEvent.MOUSE_OUT, rollOut);
			removeEventListener(MouseEvent.MOUSE_DOWN, press);
			removeEventListener(MouseEvent.MOUSE_UP, release);
			removeEventListener(MouseEvent.CLICK, click);
		}
	}
	private function createBase(target:Shape, w:uint, h:uint, c:uint, color:uint, alpha:Number = 1):void {
		target.graphics.beginFill(color, alpha);
		target.graphics.drawRoundRect(-w*0.5, -h*0.5, w, h, c*2);
		target.graphics.endFill();
	}

}