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

正月なので百人一首 (でも時間と気力がなくて二十人一首)

Japanese Carta Game - Hyaku-nin(niju-nin) isshu -
正月なので百人一首 (でも時間と気力がなくて二十人一首)
@author Hiiragi(http://twitter.com/Hiiragi3)

あけましておめでとうございます。

音量注意です。
あと、レンタルサーバー(ロリポ)にアセットデータを置いてるので、
あんまりロードしまくらないようにご協力お願い致します。

ロードが止まってしまった場合は、ブラウザの再読み込みを実行してください。

バグを発見した際には、コメントとかTwitterとかで教えていただけるとありがたいです。
ただ、しばらくネットを見れないので、すぐに対処はできません。ご了承ください。

・仕様
百人一首のうち、最初の20個のみ登録してます。
ステージには20枚のうち12枚の札がランダムで選ばれて配置されます。
計8回戦です。
詠み手の発音が悪いのは、そこらへんをディレクションする気力の限界によるものです。
BGMはきれいなループはしません。

・余談
とりあえず作ってみたら、コードや構造がぐちゃぐちゃ過ぎて、作りながら泣きそうでした。
いかにこういう制作の経験がないかを露呈しまったわけですが、
この経験をもとに、今年も精進したいと思います。

本年もよろしくお願い致します。

SE : ノタの森 
http://nota.from.tv/ 

BGM : TAM Music Factory
http://www.tam-music.com/
Get Adobe Flash player
by Hiiragi 31 Dec 2009
    Embed
package 
{
	import flash.display.*;
	import flash.events.*;
	import flash.media.*;
	import flash.net.*;
	import flash.system.*;
	import flash.text.*;
	
	
	/**
	 * Japanese Carta Game - Hyaku-nin(niju-nin) isshu -
	 * 正月なので百人一首 (でも時間と気力がなくて二十人一首)
	 * @author Hiiragi(http://twitter.com/Hiiragi3)
	 * 
	 * あけましておめでとうございます。
	 *
	 * 音量注意です。
	 * あと、レンタルサーバー(ロリポ)にアセットデータを置いてるので、
	 * あんまりロードしまくらないようにご協力お願い致します。
	 * 
	 * ロードが止まってしまった場合は、ブラウザの再読み込みを実行してください。
	 * 
	 * バグを発見した際には、コメントとかTwitterとかで教えていただけるとありがたいです。
	 * ただ、しばらくネットを見れないので、すぐに対処はできません。ご了承ください。
	 * 
	 * ・仕様
	 * 百人一首のうち、最初の20個のみ登録してます。
	 * ステージには20枚のうち12枚の札がランダムで選ばれて配置されます。
	 * 計8回戦です。
	 * 詠み手の発音が悪いのは、そこらへんをディレクションする気力の限界によるものです。
	 * BGMはきれいなループはしません。
	 * 
	 * ・余談
	 * とりあえず作ってみたら、コードや構造がぐちゃぐちゃ過ぎて、作りながら泣きそうでした。
	 * いかにこういう制作の経験がないかを露呈しまったわけですが、
	 * この経験をもとに、今年も精進したいと思います。
	 * 
	 * 本年もよろしくお願い致します。
	 * 
	 * SE : ノタの森 
	 * http://nota.from.tv/ 
	 * 
	 * BGM : TAM Music Factory
	 * http://www.tam-music.com/
	 */
	[SWF(width=465, height=465, frameRate=60, backgroundColor=0xFFFFFF)]
	public class Main extends Sprite 
	{
		private var gameData:GameData;
		private var sw:int;
		private var sh:int;
		
		private var _tf:TextField;
		
		private var _loadCntTxt:TextField;
		
		//Sprite
		private var _loadCntTxtSp:Sprite;
		
		//ButtonController
		private var btnController:Controller;
		private var cardController:CardController;
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			sw = this.stage.stageWidth;
			sh = this.stage.stageHeight;
			
			_tf = new TextField();
			_tf.text = "Load Start...\n";
			_tf.autoSize = TextFieldAutoSize.LEFT;
			this.addChild(_tf);
			
			_loadCntTxtSp = new Sprite();
			_loadCntTxtSp.graphics.beginFill(0, .5);
			_loadCntTxtSp.graphics.drawRect(0, sh / 2 - 50, sw, 100);
			_loadCntTxtSp.graphics.endFill();
			this.addChild(_loadCntTxtSp);
			
			_loadCntTxt = new TextField();
			_loadCntTxt.autoSize = TextFieldAutoSize.LEFT;
			_loadCntTxt.defaultTextFormat = new TextFormat("小塚明朝 Pro M", 50, 0xFFFFFF, FontStyle.BOLD, null, null, null, null, TextFormatAlign.CENTER);
			_loadCntTxtSp.addChild(_loadCntTxt);
			
			gameData = new GameData();
			gameData.addEventListener(GameDataLoadEvent.COMPLETE, loadComplete);
			gameData.addEventListener(GameDataLoadEvent.PROGRESS, loadProgress);
			gameData.loadStart();
		}
		
		private function loadCntTxtUpdate():void
		{
			_loadCntTxt.text = gameData.loadNumCnt + " / " + gameData.loadNumCntMax;
			_loadCntTxt.x = sw / 2 - _loadCntTxt.width / 2;
			_loadCntTxt.y = sh / 2 - _loadCntTxt.height / 2;
		}
		
		private function loadProgress(e:DataEvent):void 
		{
			_tf.appendText(e.data + "\n");
			loadCntTxtUpdate();
			if (_tf.height > this.stage.stageHeight) _tf.y = this.stage.stageHeight - _tf.height;
		}
		
		private function loadComplete(e:DataEvent):void 
		{
			_tf.appendText(e.data + "\n");
			_tf.appendText("GameData Load Complete");
			if (_tf.height > this.stage.stageHeight) _tf.y = this.stage.stageHeight - _tf.height;
			
			this.removeChild(_tf);
			initialize();
		}
		
		private function initialize():void
		{
			trace("initialize Start");
			this.addChild(new Bitmap(new Tatami(480, 480, 30)));
			
			
			var tf:TextFormat = new TextFormat("小塚明朝 Pro M", 50, 0xFFFFFF, FontStyle.BOLD, null, null, null, null, TextFormatAlign.CENTER);
			var startBtn:GameButton = new GameButton("開始", "startBtn", 200, 80, 20, tf, 0x990000, 0x995555);
			
			tf = new TextFormat("小塚明朝 Pro M", 25, 0xFFFFFF, FontStyle.BOLD, null, null, null, null, TextFormatAlign.CENTER);
			var retryBtn:GameButton = new GameButton("再挑戦", "retryBtn", 200, 50, 20, tf, 0x990000, 0x995555);
			var sendTwitterBtn:GameButton = new GameButton("ついったーで得点宣言", "sendTwitterBtn", 200, 50, 20, tf, 0x990000, 0x995555);
			var giveUpBtn:GameButton = new GameButton("投了", "giveUpBtn", 100, 50, 20, tf, 0x990000, 0x995555);
			
			btnController = new Controller(this, gameData, startBtn, giveUpBtn, retryBtn, sendTwitterBtn);
			this.addChild(btnController);
			
			btnController.showController(ControllerFlag.GAME_START);
			
			
		}
		
	}
}




import adobe.utils.ProductManager;
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.text.*;
import flash.geom.*;
import flash.net.*;
import flash.media.*;
import flash.system.Security;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.tweens.ITween;
import org.libspark.betweenas3.tweens.ITweenGroup;

//ButtonController
class Controller extends Sprite
{
	private var _rootDOC:DisplayObjectContainer;
	private var _sw:int;
	private var _sh:int;
	
	private var _bgmSound:Sound;
	private var _bgmSoundChannel:SoundChannel;
	
	public var _startBtn:GameButton;
	private var _giveUpBtn:GameButton;
	public var _retryBtn:GameButton;
	private var _sendTwitterBtn:GameButton;
	
	public var _filmSp:Sprite;
	public var _filmSp_playingMenu:Sprite;
	
	private var _gameData:GameData;
	private var _cardController:CardController;
	
	private var _twitterURL:String = "http://twitter.com/home?status=";
	
	private var totalScoreTxt:TextField;	//結果表示
	private var _totalScoreSp:StatusView;	//プレイ中のスコア表示
	
	public function Controller(DOC:DisplayObjectContainer, gameData:GameData, startBtn:GameButton = null, giveUpBtn:GameButton = null, retryBtn:GameButton = null, sendTwitterBtn:GameButton = null)
	{
		_rootDOC = DOC;
		_gameData = gameData;
		_sw = _rootDOC.stage.stageWidth;
		_sh = _rootDOC.stage.stageHeight;
		
		_totalScoreSp = new StatusView();
		
		if (startBtn != null)	_startBtn = startBtn;
		if (giveUpBtn != null)	{
			_giveUpBtn = giveUpBtn;
			create_filmSp_playingMenu();
		}
		if (retryBtn != null)	_retryBtn = retryBtn;
		if (sendTwitterBtn != null)	_sendTwitterBtn = sendTwitterBtn;
		
		_filmSp = new Sprite();
		_filmSp.graphics.clear();
		_filmSp.graphics.beginFill(0x000000, .5);
		_filmSp.graphics.drawRect(0, 0, _rootDOC.stage.stageWidth, _rootDOC.stage.stageHeight);
		_filmSp.graphics.endFill();
		
		var tf:TextFormat = new TextFormat("小塚明朝 Pro M", 40, 0xFFFFFF, FontStyle.BOLD);
		totalScoreTxt = new TextField();
		totalScoreTxt.defaultTextFormat = tf;
		totalScoreTxt.autoSize = TextFieldAutoSize.LEFT;
		
		_cardController = new CardController(_rootDOC, _gameData, this);
		
		_bgmSound = _gameData.bgm[0];
		_bgmSoundChannel = _bgmSound.play(0, 999999, new SoundTransform(.5));
		
		this.addEventListener(MouseEvent.CLICK, onMouseClickHandler);
	}
	
	private function onMouseClickHandler(e:MouseEvent):void 
	{
		//trace(e.target.name);
		switch (e.target.name) 
		{
			case "startBtn":
				clearController();
				this.addChild(_cardController);
				_cardController.dealCards(12);
				break;
			case "giveUpBtn":
				trace("GiveUp");
				clearController();
				_cardController.reset();
				showController(ControllerFlag.GAME_START);
				break;
			case "retryBtn":
				clearController();
				this.addChild(_cardController);
				_cardController.dealCards(12);
				break;
			case "sendTwitterBtn":
				var str:String = "わんだふる・二十人一首の得点 : " + _gameData.score;
				var url:URLRequest = new URLRequest(encodeURI(_twitterURL + str));
				navigateToURL(url);
				break;
		}
	}
	
	private function create_filmSp_playingMenu():void 
	{
		_filmSp_playingMenu = new Sprite();
		_filmSp_playingMenu.graphics.clear();
		_filmSp_playingMenu.graphics.beginFill(0x000000, .5);
		_filmSp_playingMenu.graphics.drawRect(0, 0, _rootDOC.stage.stageWidth, 60);
		_filmSp_playingMenu.graphics.endFill();
		
		_totalScoreSp.x = 10;
		_totalScoreSp.y = 20;
		_filmSp_playingMenu.addChild(_giveUpBtn);
		_filmSp_playingMenu.addChild(_totalScoreSp);
		
		_giveUpBtn.x = _filmSp_playingMenu.width - _giveUpBtn.width - 20;
		_giveUpBtn.y = _filmSp_playingMenu.height / 2 - _giveUpBtn.height / 2;
	}
	
	public function showController(flag:String):void 
	{
		switch (flag) 
		{
			case ControllerFlag.GAME_START:
				clearController();
				this.addChild(_filmSp);
				
				_startBtn.x = _sw / 2 - _startBtn.width / 2;
				_startBtn.y = _sh / 2 - _startBtn.height / 2;
				this.addChild(_startBtn);
				
				break;
			case ControllerFlag.PLAYING:
				_filmSp_playingMenu.y = _sh + 100;
				this.addChild(_filmSp_playingMenu);
				BetweenAS3.tween(_filmSp_playingMenu, { y:_sh - _filmSp_playingMenu.height }, null, 0.4, null ).play();
				break;
			case ControllerFlag.GAME_END:
				trace("gameEnd");
				clearController();
				this.addChild(_filmSp);
				totalScoreTxt.text = "総得点 : " + _gameData.score;
				totalScoreTxt.x = _sw / 2 - totalScoreTxt.width / 2;
				totalScoreTxt.y = 100;
				this.addChild(totalScoreTxt);
				_retryBtn.x = _sw / 2 - _retryBtn.width / 2;
				_retryBtn.y = _sh / 2 - _retryBtn.height / 2;
				this.addChild(_retryBtn);
				
				_sendTwitterBtn.x = _sw / 2 - _sendTwitterBtn.width / 2;
				_sendTwitterBtn.y = _retryBtn.y + _retryBtn.height + 20;
				this.addChild(_sendTwitterBtn);
				break;
		}
	}
	
	public function clearController():void 
	{
		//今表示している表示オブジェクトを全消し
		var len:int = this.numChildren;
		for (var i:int = 0; i < len; i++)	this.removeChildAt(0);
	}
	
	public function scoreUpData(text:String):void 
	{
		_totalScoreSp.textUpdate(text);
	}
	
	//getter/setter
	public function get giveUpBtn():GameButton { return _giveUpBtn; }
	
	public function set giveUpBtn(value:GameButton):void 
	{
		_giveUpBtn = value;
		create_filmSp_playingMenu();
	}
}

class ControllerFlag
{
	public static const GAME_START:String = "gameStart";
	public static const PLAYING:String = "playing";
	public static const GAME_END:String = "gameEnd";
}


//statusView
class StatusView extends Sprite
{
	private var _statusTxt:TextField;
	
	public function StatusView() 
	{
		_statusTxt = new TextField();
		_statusTxt.autoSize = TextFieldAutoSize.LEFT;
		_statusTxt.defaultTextFormat = new TextFormat("小塚明朝 Pro M", 20, 0xFFFFFF, FontStyle.BOLD);
		this.addChild(_statusTxt);
	}
	
	public function textUpdate(text:String):void
	{
		_statusTxt.text = text;
	}
}

//CardController
class CardController extends Sprite
{
	private var _rootDOC:DisplayObjectContainer;
	private var _sw:int;
	private var _sh:int;
	
	private var _gameData:GameData;
	private var _controller:Controller;
	
	private var _cardIndex:Array = [];
	private var _nowCard:int;
	private var _gameFlag:Boolean = false;
	private var _openingFlag:Boolean = true; //オープニング時かどうか(中断を押して戻った時にgameStartを発動させないため
	
	private var _startSp:Sprite;
	private var _startTxt:TextField;
	
	private var _voiceSound:Sound;
	private var _voiceSoundChannel:SoundChannel;
	
	private var _answerMatchSprite:Sprite;
	private var _answerMissSprite:Sprite;
	private var _scoreTxt:TextField;
	private var _scoreWindow:Sprite;
	
	private var _limitGauge:LimitGauge;
	
	private var _limitTxt:TextField;
	private var _limitSp:Sprite;
	
	private var _gameCnt:int = 0;
	private var gameCntMax:int = 8;
	
	public function CardController(rootDOC:DisplayObjectContainer, gameData:GameData, controller:Controller)
	{
		_rootDOC = rootDOC;
		_sw = rootDOC.stage.stageWidth;
		_sh = rootDOC.stage.stageHeight;
		_gameData = gameData;
		_controller = controller;
		
		_startTxt = new TextField();
		_startTxt.autoSize = TextFieldAutoSize.LEFT;
		_startTxt.text = "開始";
		_startTxt.setTextFormat(new TextFormat("小塚明朝 Pro M", 50, 0xFFFFFF, FontStyle.BOLD));
		_startTxt.y = _sh / 2 - _startTxt.height / 2;
		
		_startSp = new Sprite();
		_startSp.graphics.beginFill(0x000000, 0.5);
		_startSp.graphics.drawRect(0, 0, _sw, 100);
		_startSp.graphics.endFill();
		_startSp.y = _sh / 2 - _startSp.height / 2;
		
		_answerMatchSprite = new Sprite();
		_answerMatchSprite.graphics.lineStyle(2, 0x660000);
		_answerMatchSprite.graphics.beginFill(0xAA0000);
		_answerMatchSprite.graphics.drawCircle(50, 50 , 50);
		_answerMatchSprite.graphics.drawCircle(50, 50 , 40);
		_answerMatchSprite.graphics.endFill();
		_answerMatchSprite.alpha = 0;
		_answerMatchSprite.mouseEnabled = false;
		
		_answerMissSprite = new Sprite();
		_answerMissSprite.graphics.lineStyle(2, 0x000066);
		_answerMissSprite.graphics.beginFill(0x0000AA);
		_answerMissSprite.graphics.moveTo(10, 0);
		_answerMissSprite.graphics.lineTo(50, 43);
		_answerMissSprite.graphics.lineTo(90, 0);
		_answerMissSprite.graphics.lineTo(100, 10);
		_answerMissSprite.graphics.lineTo(57, 50);
		_answerMissSprite.graphics.lineTo(100, 90);
		_answerMissSprite.graphics.lineTo(90, 100);
		_answerMissSprite.graphics.lineTo(50, 57);
		_answerMissSprite.graphics.lineTo(10, 100);
		_answerMissSprite.graphics.lineTo(0, 90);
		_answerMissSprite.graphics.lineTo(43, 50);
		_answerMissSprite.graphics.lineTo(0, 10);
		_answerMissSprite.graphics.lineTo(10, 0);
		_answerMissSprite.graphics.endFill();
		_answerMissSprite.alpha = 0;
		_answerMissSprite.mouseEnabled = false;
		
		_limitTxt = new TextField();
		_limitTxt.text = "時間切れ";
		_limitTxt.autoSize = TextFieldAutoSize.LEFT;
		_limitTxt.setTextFormat(new TextFormat("小塚明朝 Pro M", 40, 0xFFFFFF, FontStyle.BOLD));
		
		_limitSp = new Sprite();
		_limitSp.graphics.beginFill(0x0, .5);
		_limitSp.graphics.drawRect(0, 0, _sw, 150);
		_limitSp.graphics.endFill();
		_limitSp.addChild(_limitTxt);
		_limitTxt.x = _limitSp.width / 2 - _limitTxt.width / 2;
		_limitTxt.y = _limitSp.height / 2 - _limitTxt.height / 2;
		_limitSp.y = _sh / 2 - _limitSp.height / 2;
		
		_scoreTxt = new TextField();
		_scoreTxt.autoSize = TextFieldAutoSize.LEFT;
		_scoreTxt.defaultTextFormat = new TextFormat("小塚明朝 Pro M", 40, 0xFFFFFF, FontStyle.BOLD);
		_scoreTxt.visible = false;
		
		_scoreWindow = new Sprite();
		_scoreWindow.graphics.beginFill(0, .5);
		_scoreWindow.graphics.drawRect(0, 0, _sw, 150);
		_scoreWindow.graphics.endFill();
		_scoreWindow.y = _sh / 2 - _scoreWindow.height / 2;
		_scoreWindow.visible = false;
		
		_limitGauge = new LimitGauge(_sw - 20, 10);
		_limitGauge.x = 10;
		_limitGauge.y = 5;
		
		this.addEventListener("cardClick", cardClickHandler);
	}
	
	public function reset():void 
	{
		var len:int = this.numChildren;
		for (var i:int = 0; i < len; i++)
		{
			this.removeChildAt(0);
		}
		
		_gameData.score = 0;
		_gameData.combo = 0;
		_openingFlag = true;
		if (_voiceSoundChannel != null) _voiceSoundChannel.stop();
		this.removeEventListener(Event.ENTER_FRAME, voiceLengthCheck);
	}
	
	public function dealCards(num:int):void
	{
		reset();
		_gameCnt = 0;
		_openingFlag = false;
				
		clearCard();
		_cardIndex = _gameData.getIndexNumbers(num);
		//trace("_cardIndex = " + _cardIndex);
		
		var len:int = _cardIndex.length;
		var card:Sprite;
		var tweenArray:Array = [];
		
		for (var i:int = 0; i < len; i++) 
		{
			card = _gameData.card[_cardIndex[i]];
			card.filters = [new DropShadowFilter(2, 45, 0x000000, 0.5, 4, 4, 1, 1)];
			card.x = _sw + 100;
			card.y = _sh + 100;
			
			tweenArray.push(BetweenAS3.func(function():void{ _gameData.se[2].play() }));
			tweenArray.push(BetweenAS3.tween(card, { x:i % 4 * 110 + 40, y:Math.floor(i / 4) * 120 + 40, rotation:Math.floor(Math.random()*40 - 20)}, null, 0.1, null));
			
			this.addChild(card);
		}
		tweenArray.push(BetweenAS3.func(cardDealComplete));
		BetweenAS3.serialTweens(tweenArray).play();
	}
	
	private function cardDealComplete():void 
	{
		scoreViewUpdate();
		_controller.showController(ControllerFlag.PLAYING);
		_startTxt.x = _sw + 100;
		this.addChild(_startSp);
		this.addChild(_startTxt);
		
		_startSp.visible = true;
		_startTxt.visible = true;
		
		BetweenAS3.serial(BetweenAS3.tween(_startSp, { alpha:1 }, { alpha:0 }, .5),
							BetweenAS3.tween(_startTxt, { x:_sw / 2 - _startTxt.width / 2 }, null, .3),
							BetweenAS3.delay(BetweenAS3.tween(_startTxt, { x: -_startTxt.width - 100 }, null, .3), 1.2),
							BetweenAS3.func(endTweenHandler)
							).play();
	}
	
	private function endTweenHandler():void 
	{
		_startSp.visible = false;
		_startTxt.visible = false;
		
		this.addChild(_answerMatchSprite);
		this.addChild(_answerMissSprite);
		this.addChild(_scoreWindow);
		this.addChild(_scoreTxt);
		this.addChild(_limitGauge);
		
		gameStart();
	}
	
	private function scoreViewUpdate():void 
	{
		_controller.scoreUpData(gameCnt + " / " + gameCntMax + " | 総得点 : " + _gameData.score + " | 連鎖 : " + _gameData.combo);
	}
	private function gameStart():void
	{
		gameCnt++;
		scoreViewUpdate();
		
		if (gameCnt <= gameCntMax && !_openingFlag)
		{
			trace(gameCnt + " / " + gameCntMax);
			var i:int = Math.random() * _cardIndex.length >> 0;
			_nowCard = _cardIndex.splice(i, 1);
			_voiceSound = _gameData.voice[_nowCard];
			_voiceSoundChannel = _voiceSound.play();
			_voiceSoundChannel.addEventListener(Event.SOUND_COMPLETE, voicePlayComplete);
			this.addEventListener(Event.ENTER_FRAME, voiceLengthCheck);
			_limitGauge.reset();
			_scoreWindow.visible = false;
			_scoreTxt.visible = false;
			_gameFlag = true;
		}
		else if (gameCnt > gameCntMax)
		{
			trace("ゲーム終了");
			_controller.showController(ControllerFlag.GAME_END);
		}

	}
	private var ratio:Number;
	private function voiceLengthCheck(e:Event):void 
	{
		ratio = _voiceSoundChannel.position / (_voiceSound.length - 200);
		_limitGauge.change(ratio);
	}
	
	private function voicePlayComplete(e:Event):void 
	{
		this.removeEventListener(Event.ENTER_FRAME, voiceLengthCheck);
		_limitGauge.change(1);
		timeUp();
	}
	
	private function timeUp():void
	{
		_gameFlag = false;
		this.addChild(_limitSp);
		BetweenAS3.serial(BetweenAS3.delay(BetweenAS3.func(removeTimeup), 2),
							BetweenAS3.func(gameStart)
							).play();
	}
	
	private function removeTimeup():void
	{
		this.removeChild(_limitSp);		
	}
	
	private function cardClickHandler(e:MouseEvent = null ):void 
	{
		if (_gameFlag)
		{
			this.removeEventListener(Event.ENTER_FRAME, voiceLengthCheck);
			
			var sp:Sprite;
			var tweenArray:Array = [];
			
			if (int(e.target.name.substr( -3, 3)) == _nowCard)
			{
				trace("match");
				_gameData.se[0].play();
				_gameData.combo++;
				//trace(_voiceSoundChannel.position);
				//trace(_voiceSound.length);
				//trace(_gameData.scoreUnit);
				//trace(_gameData.combo);
				
				var score:int = Math.round((1 - _voiceSoundChannel.position / _voiceSound.length) * _gameData.scoreUnit * _gameData.combo);
				_gameData.score += score;
				trace("combo = " + _gameData.combo + " , score = " + score + " , totalScore = " + _gameData.score);
				sp = _answerMatchSprite;
				_scoreTxt.text = "連鎖 : " + _gameData.combo + " , 得点 : " + score;
				_scoreTxt.x = _sw / 2 - _scoreTxt.width / 2;
				_scoreTxt.y = _sh / 2 - _scoreTxt.height / 2;
				
				tweenArray.push(BetweenAS3.tween(e.target, { x:-100 }, null, .5, null));
				_scoreWindow.visible = true;
				_scoreTxt.visible = true;
			}
			else
			{
				trace("miss");
				_gameData.se[1].play();
				_gameData.combo = 0;
				sp = _answerMissSprite;
			}
			sp.x = e.target.x + e.target.width / 2 - sp.width / 2;
			sp.y = e.target.y + e.target.height / 2 - sp.height / 2;
			sp.alpha = 1;
			
			tweenArray.push(BetweenAS3.delay(BetweenAS3.tween(sp, { alpha:0 }, null, 1, null), 1.0), BetweenAS3.func(gameStart));
			BetweenAS3.serialTweens(tweenArray).play();
									
			_gameFlag = false;
			_voiceSoundChannel.stop();
		}
	}
	
	public function clearCard():void 
	{
		//今表示している表示オブジェクトを全消し
		var len:int = this.numChildren;
		for (var i:int = 0; i < len; i++)	this.removeChildAt(0);
	}
	
	public function get gameCnt():int { return _gameCnt; }
	
	public function set gameCnt(value:int):void 
	{
		_gameCnt = value;
	}
}


//LimitGauge
class LimitGauge extends Sprite
{
	private var _frameSp:Sprite;
	private var _gaugeSp:Sprite;
	
	public function LimitGauge(w:int, h:int, color1:int = 0xFF66FF, color2:int = 0xFF0066, color3:int = 0xCC0033) 
	{
		_frameSp = new Sprite();
		_gaugeSp = new Sprite();
		
		var g:Graphics = _gaugeSp.graphics;
		var mtx:Matrix = new Matrix();
		mtx.createGradientBox(w, h, Math.PI / 2);
		g.beginGradientFill(GradientType.LINEAR, [color1, color2, color1], [1, 1, 1], [0, 127, 255], mtx);
		g.drawRect(0, 0, w, h);
		g.endFill();
		
		g = _frameSp.graphics;
		g.lineStyle(2, color3);
		
		g.moveTo(0, 0);
		g.lineTo(w, 0);
		g.lineTo(w, h);
		g.lineTo(0, h);
		g.lineTo(0, 0);
		
		
		var backSP:Sprite = new Sprite();
		g = backSP.graphics;
		g.beginFill(0xFFFFFF, .7);
		g.drawRect(0, 0, w, h);
		g.endFill();
		
		this.addChild(backSP);
		this.addChild(_gaugeSp);
		this.addChild(_frameSp);
	}
	
	public function change(ratio:Number):void 
	{
		_gaugeSp.scaleX = 1 - ratio;
	}
	
	public function reset():void 
	{
		_gaugeSp.scaleX = 1;
	}
}

//GameDataProvider
class GameData extends EventDispatcher
{
	private var _scoreUnit:int = 5000;
	private var _score:int = 0;
	private var _combo:int = 0;
	
	private var _baseURL:String = "http://melancholy.raindrop.jp/flash/wonderfl_1/assets/";
	
	private var _seURL:Array = [];
	private var _se:Array = [];
	
	private var _bgmURL:Array = [];
	private var _bgm:Array = [];
	
	private var _voiceURL:Array = [];
	private var _voice:Array = [];
	
	private var _cardURL:Array = [];
	private var _card:Array = [];
	
	private var _indexArray:Array = [];	//インデックスナンバーを保持しておくだけ
	
	private var _num:int;	//用意する(読み込む)カード等の最大数
	private var _cnt:int;
	private var _loader:Loader;
	private var _urlReq:URLRequest;
	private var _loadFlag:String;
	
	
	private var _loadNumCnt:int = 0;	//現在読み込んだファイル数
	private var _loadNumCntMax:int = 0;	//読み込むファイル数
	
	public function GameData(startNow:Boolean = false) 
	{
		_num = 20;
		_cnt = 0;
		
		Security.loadPolicyFile("http://melancholy.raindrop.jp/crossdomain.xml");
		
		_urlReq = new URLRequest();
		_loader = new Loader();
		_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, partsLoadComplete);
		_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, partsLoadError);
		_loadFlag = "card";
		
		if (startNow)
		{
			loadStart();
		}
		
	}
	
	public function loadStart():void 
	{
		URLCreate();
		for (var i:int = 0; i < _num; i++)
		{
			_indexArray[i] = i;
		}
		assetsLoad();
	}
	
	public function getIndexNumbers(num:int):Array 
	{
		var arr:Array = shuffle_new(_indexArray);
		var retrunArray:Array = [];
		for (var i:int = 0; i < num; i++)
		{
			retrunArray[i] = arr[i];
		}
		return retrunArray;
	}
	
	private function partsLoadError(e:IOErrorEvent):void 
	{
		throw new Error(e);
	}
	
	private function assetsLoad():void
	{
		_loadNumCnt++;
		
		switch (_loadFlag) 
		{
			case "card":
				_urlReq.url = _cardURL[_cnt];
				_loader.load(_urlReq);
				break;
			case "voice":
				_voice[_cnt] = new Sound();
				_voice[_cnt].addEventListener(Event.COMPLETE, partsLoadComplete);
				_urlReq.url = _voiceURL[_cnt];
				_voice[_cnt].load(_urlReq);
				break;
			case "se":
				_se[_cnt] = new Sound();
				_se[_cnt].addEventListener(Event.COMPLETE, partsLoadComplete);
				_urlReq.url = _seURL[_cnt];
				_se[_cnt].load(_urlReq);
				break;
			case "bgm":
				_bgm[_cnt] = new Sound();
				_bgm[_cnt].addEventListener(Event.COMPLETE, partsLoadComplete);
				_urlReq.url = _bgmURL[_cnt];
				_bgm[_cnt].load(_urlReq);
				break;
		}
	}
	
	private function partsLoadComplete(e:Event):void 
	{
		switch (_loadFlag) 
		{
			case "card":
				this.dispatchEvent(new DataEvent(GameDataLoadEvent.PROGRESS, false, false, LoaderInfo(e.target).url + " Load Complete"));
				var sp:Sprite = new Sprite();
				sp.mouseChildren = false;
				sp.name = "card_" + fillZero(_cnt, 3);
				sp.addChild(LoaderInfo(e.target).content);
				sp.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void { e.target.dispatchEvent(new MouseEvent("cardClick", true))});
				_card.push(sp);
				_cnt++;
				if (_cardURL.length > _cnt)
				{
					assetsLoad();
				}
				else
				{
					e.target.removeEventListener(Event.COMPLETE, partsLoadComplete);
					_loadFlag = "voice";
					_cnt = 0;
					assetsLoad();
				}
				break;
			case "voice":
				this.dispatchEvent(new DataEvent(GameDataLoadEvent.PROGRESS, false, false, Sound(e.target).url + " Load Complete"));
				e.target.removeEventListener(Event.COMPLETE, partsLoadComplete);
				_cnt++;
				if (_voiceURL.length > _cnt)
				{
					assetsLoad();
				}
				else
				{
					_loadFlag = "se";
					_cnt = 0;
					assetsLoad();
				}
				break;
			case "se":
				this.dispatchEvent(new DataEvent(GameDataLoadEvent.PROGRESS, false, false, Sound(e.target).url + " Load Complete"));
				e.target.removeEventListener(Event.COMPLETE, partsLoadComplete);
				_cnt++;
				if (_seURL.length > _cnt)
				{
					assetsLoad();
				}
				else
				{
					_loadFlag = "bgm";
					_cnt = 0;
					assetsLoad();
				}
				break;
			case "bgm":
				this.dispatchEvent(new DataEvent(GameDataLoadEvent.PROGRESS, false, false, Sound(e.target).url + " Load Complete"));
				e.target.removeEventListener(Event.COMPLETE, partsLoadComplete);
				_cnt++;
				if (_bgmURL.length > _cnt)
				{
					assetsLoad();
				}
				else
				{
					this.dispatchEvent(new DataEvent(GameDataLoadEvent.COMPLETE, false, false, "All Data Load Complete"));
				}
				break;
		}
	}
	
	
	private function URLCreate():void
	{
		_loadNumCntMax = 0;
		
		for (var i:int = 0; i < _num; i++)
		{
			_voiceURL[i] = _baseURL + "voice/voice_" + fillZero((i + 1), 3) + ".mp3";
			_cardURL[i] = _baseURL + "card/card_" + fillZero((i + 1), 3) + ".png";
			_loadNumCntMax += 2;
		}
		
		_seURL.push(_baseURL + "se/se_001.mp3");	_loadNumCntMax++;
		_seURL.push(_baseURL + "se/se_002.mp3");	_loadNumCntMax++;
		_seURL.push(_baseURL + "se/se_003.mp3");	_loadNumCntMax++;
		
		_bgmURL.push(_baseURL + "bgm/bgm_001.mp3");	_loadNumCntMax++;
		
	}
	
	private function fillZero(num:int, cnt:int):String
	{
		var str:String = num.toString();
		for (var i:int = 0; i < cnt-1; i++) str = "0" + str;
		
		return str.substr( -cnt, cnt);
	}
	
	//1行でArrayを偏り無くシャッフルする
	//http://wonderfl.net/code/28b05287faaf74d35294d2d63dafba6265c6430b
	public function shuffle_new(array:Array):Array
	{
		for(var j:int, t:Number, i:int = array.length, a:Array = array.slice();i; j = Math.random() * i, t = a[--i], a[i] = a[j], a[j] = t);return a;
	}
		
	
	//getter/setter
	public function get se():Array { return _se; }
	
	public function set se(value:Array):void 
	{
		_se = value;
	}
	
	public function get bgm():Array { return _bgm; }
	
	public function set bgm(value:Array):void 
	{
		_bgm = value;
	}
	
	public function get voice():Array { return _voice; }
	
	public function set voice(value:Array):void 
	{
		_voice = value;
	}
	
	public function get card():Array { return _card; }
	
	public function set card(value:Array):void 
	{
		_card = value;
	}
	
	public function get score():int { return _score; }
	
	public function set score(value:int):void 
	{
		_score = value;
	}
	
	public function get scoreUnit():int { return _scoreUnit; }
	
	public function get combo():int { return _combo; }
	
	public function set combo(value:int):void 
	{
		_combo = value;
	}
	
	public function get loadNumCnt():int { return _loadNumCnt; }
	public function get loadNumCntMax():int { return _loadNumCntMax; }
	
}


//イベントの名前だけ
class GameDataLoadEvent
{
	public static const PROGRESS:String = "gameDataLoadProgress";
	public static const COMPLETE:String = "gameDataLoadComplete";
	
}



//畳クラス(BitmapData)
class Tatami extends BitmapData
{
	private var _noiseBmpd:BitmapData;
	
	public function Tatami(w:int, h:int, columns:int = 20) 
	{
		//判りやすいように赤色にしてるだけなんで、色は気にしないでください。
		super(w, h, false, 0xFF0000);
		
		//初期化
		_noiseBmpd = new BitmapData(w / columns, h);
		
		//ストライプを作成(1列分)
		var mtx:Matrix = new Matrix();
		mtx.createGradientBox(w/columns, h);
		var stripeSp:Sprite = new Sprite();
		var ratio:Number = 255 / 5;
		stripeSp.graphics.beginGradientFill(GradientType.LINEAR,
											[0xBBBBBB, 0xFFFFFF, 0xFFFFFF, 0xBBBBBB],
											[1, 1, 1, 1],
											[0, ratio * 1, ratio * 4, 255],
											mtx);
		stripeSp.graphics.drawRect(0, 0, w / columns, h);
		stripeSp.graphics.endFill();
		

		
		//for分で左から一列ずつ書いていく
		for (var i:int = 0; i < columns; i++)
		{
			//上で作ったストライプのスプライトを、所定の位置に描く
			this.draw(stripeSp, new Matrix(1, 0, 0, 1, w / columns * i, 0));
			
			//ランダムでノイズを描く
			_noiseBmpd.noise(Math.random() * 1000 >> 0, 0, 255, 7, true);
			//ノイズをブレさせる
			_noiseBmpd.applyFilter(_noiseBmpd, new Rectangle(0, 0, w / columns, h), new Point(0, 0), new BlurFilter(20, 1, 2));
			//ブレたノイズをストライプを描いた場所にBlendMode.MULTIPLYで描く
			this.draw(_noiseBmpd, new Matrix(1, 0, 0, 1, w / columns * i, 0), new ColorTransform(1.6, 1.6, 1.6, 1, -40, -30, -80, 0), BlendMode.MULTIPLY);
		}
		
		//なんとなく全体が混ざったっぽくなった気がするフィルター
		//(いらないかもしれないけど、なかったら「はっきりくっきりのっぺり」で気持ち悪い気もする)
		this.applyFilter(this, new Rectangle(0, 0, w, h), new Point(0, 0), new BlurFilter(1.1, 1.1, 2));
	}
}





class GameButton extends Sprite
{
	private var _backSp:Sprite;
	private var _rollOverSp:Sprite;
	private var _mouseDownSp:Sprite;
	
	private var _tf:TextField;
	private var _tFormat:TextFormat;
	private var _labelText:String;
	private var _id:String;
	private var _width:Number;
	private var _height:Number;
	private var _color1:int;
	private var _color2:int;
	private var _roundRadius:Number;
	
	public function GameButton(labelText:String, name:String = null, width:Number = 80, height:Number = 20, roundRadius:Number = 5, tFormat:TextFormat = null, color1:int = 0x000000, color2:int = 0x333333) 
	{
		//引数の取得・設定
		_labelText = labelText;
		if (name != null) this.name = name;
		_width = width;
		_height = height;
		_tFormat = tFormat;
		_roundRadius = roundRadius;
		_color1 = color1;
		_color2 = color2;
		
		//テキスト設定
		_tf = new TextField();
		_tf.autoSize = TextFieldAutoSize.LEFT;
		_tf.antiAliasType = AntiAliasType.ADVANCED;
		if (tFormat == null) _tf.defaultTextFormat = new TextFormat(null, null, 0xFFFFFF);
		else _tf.defaultTextFormat = tFormat;
		
		//初期化、表示リスト追加、リスナー追加
		_backSp = new Sprite();
		_rollOverSp = new Sprite();
		_mouseDownSp = new Sprite();
		
		addChild(_backSp);
		addChild(_mouseDownSp);
		addChild(_rollOverSp);
		addChild(_tf);
		
		this.addEventListener(MouseEvent.ROLL_OVER, onRollOverHandler);
		this.addEventListener(MouseEvent.ROLL_OUT, onRollOutHandler);
		this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler);
		this.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
		
		createBtn();
	}
	
	//ボタン形状の描画
	private function createBtn():void
	{
		_tf.text = _labelText;
		_width = (_width >= _tf.width) ? _width : _tf.width;
		
		backSpDraw();
		rollOverSpDraw();
		mouseDownDraw();
		
		_tf.x = _width / 2 - _tf.width / 2;
		_tf.y = _height / 2 - _tf.height / 2;
		
		this.mouseChildren = false;
		this.buttonMode = true;
		
		_rollOverSp.visible = false;
		_mouseDownSp.visible = false;
	}
	
	//平常時のボタングラフィック
	private function backSpDraw():void
	{
		var _mtx:Matrix = new Matrix();
		_mtx.createGradientBox(_width, _height, Math.PI / 2);
		_backSp.graphics.beginGradientFill(GradientType.LINEAR,[_color1, _color2, _color1], [1,1,1],[0,126,255],_mtx);
		_backSp.graphics.drawRoundRect(0, 0, _width, _height, _roundRadius, _roundRadius);
		_backSp.graphics.endFill();
	}
	
	//ロールオーバ-したとき時のボタングラフィック
	private function rollOverSpDraw():void
	{
		_rollOverSp.graphics.beginFill(0xFFFFFF, .3);
		_rollOverSp.graphics.drawRoundRect(0, 0, _width, _height, _roundRadius, _roundRadius);
		_rollOverSp.graphics.endFill();
	}
	
	//ボタンを押した時のボタングラフィック
	private function mouseDownDraw():void
	{
		var _mtx:Matrix = new Matrix();
		_mtx.createGradientBox(_width, _height, Math.PI / 2);
		_mouseDownSp.graphics.beginGradientFill(GradientType.LINEAR,[_color2, _color1, _color2], [1,1,1],[0,126,255],_mtx);
		_mouseDownSp.graphics.drawRoundRect(0, 0, _width, _height, _roundRadius, _roundRadius);
		_mouseDownSp.graphics.endFill();
	}
	
	//MouseEvent.ROLL_OVER時の描画変更
	private function onRollOverHandler(e:MouseEvent):void 
	{
		_rollOverSp.visible = true;
	}
	
	//MouseEvent.ROLL_OUT時の描画変更
	private function onRollOutHandler(e:MouseEvent):void 
	{
		_rollOverSp.visible = false;
		_mouseDownSp.visible = false;
	}
	
	//MouseEvent.MOUSE_DOWN時の描画変更
	private function onMouseDownHandler(e:MouseEvent):void 
	{
		_mouseDownSp.visible = true;
	}
	
	//MouseEvent.MOUSE_UP時の描画変更
	private function onMouseUpHandler(e:MouseEvent):void 
	{
		_mouseDownSp.visible = false;
	}
	
	
	
	
	//getter/setter
	public function get labelText():String { return _labelText; }
	
	public function set labelText(value:String):void 
	{ 
		_labelText = value;
		createBtn();
	}
	
	public function get id():String { return _id; }
	
	public function set id(value:String):void 
	{
		_id = value;
	}
}