正月なので百人一首 (でも時間と気力がなくて二十人一首)
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/
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;
}
}