Beautifl - Flash Gallery

Thumbnail : Number touch
Number touch
bkzen 2010-07-30 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

package  
{
    import com.bit101.components.Label;
    import com.bit101.components.PushButton;
    import com.bit101.components.Style;
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.display.StageDisplayState;
    import flash.geom.Matrix;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
    import flash.net.navigateToURL;
    import flash.net.URLRequest;
    import net.wonderfl.score.basic.BasicScoreForm;
    import net.wonderfl.score.basic.BasicScoreRecordViewer;
    /**
     * 1~25までを順にクリックするだけのゲーム。
     * 自分で作っておいてめっちゃ遅いという現実
     * @author jc at bk-zen.com
     */
    [SWF (backgroundColor = "0xFFFFFF", width = "465", height = "465", frameRate = "60")]
    public class Test5 extends Sprite
    {
        private var start:PushButton;
        private var label:Label;
        private var buttons: Buttons;
        private var lastTime: int;
        private var baseTime: int;
        private const phaseCountDown: uint = 0;
        private const phaseGameMain:  uint = 1;
        private const phaseGameClear: uint = 2;
        private var phase: uint = phaseCountDown;
        private var numbers: Array;
        private var effectSh: Shape;
        private var effectCount: uint;
        private var clearTime: int = 0;
        private var effectMatrix: Matrix;
        private var effectTarget: BitmapData;
        private var timeLabel: Label;
        private var tweet:PushButton;
        private var bestTime:int = int.MAX_VALUE;
        
        public function Test5() 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            //
            
            label = new Label(this, 0, 0, "1~25までの数字を順に\nクリックするだけゲーム");
            var textFormat: TextFormat = new TextFormat("MS P ゴシック", 15, 0x777777, true);
            textFormat.align = TextFormatAlign.CENTER;
            label.textField.defaultTextFormat = textFormat;
            label.textField.embedFonts = false;
            label.draw();
            start = new PushButton(this, 0, 0, "start", onClickStart);
            start.draw();
            label.x = stage.stageWidth - label.width >> 1;
            start.x = stage.stageWidth - start.width >> 1;
            label.y = stage.stageHeight / 2 - 100;
            start.y = stage.stageHeight / 2 + 50;
            numbers = [];
            var tmp: Label = new Label();
            for (var i:int = 0; i < 5; i++) 
            {
                tmp.text = "" + (i + 1);
                tmp.draw();
                var bmd: BitmapData = new BitmapData(tmp.textField.width << 2, tmp.textField.height << 2, true, 0);
                bmd.draw(tmp, new Matrix(4, 0, 0, 4));
                numbers.unshift(bmd);
            }
            tmp.text = "GO!";
            tmp.draw();
            bmd = new BitmapData(tmp.textField.width << 2, tmp.textField.height << 2, true, 0);
            bmd.draw(tmp, new Matrix(4, 0, 0, 4));
            numbers.push(bmd);
            effectSh = new Shape();
            effectMatrix = new Matrix();
            effectSh.x = stage.stageWidth / 2;
            effectSh.y = stage.stageHeight / 2;
            cerateFullScreenBtn();
            tweet = new PushButton(this, 0, 0, "tweet best lap", sendTweet);
            tweet.enabled = false;
            
            tweet.move(stage.stageWidth - tweet.width, stage.stageHeight - tweet.height);
        }
        
        private function sendTweet(e: Event):void
        {
            if (bestTime == int.MAX_VALUE) return;
            
            navigateToURL(new URLRequest("http://twitter.com/?status=Number touch : "+(bestTime / 1000)+" [sec] http://wonderfl.net/c/2A9V %23wonderfl"));
        }
        
        private function onClickStart(e: Event = null):void
        {
            while (numChildren > 0) removeChildAt(0);
            if (buttons == null)
            {
                buttons = new Buttons(onClear, onMiss, this);
                buttons.x = stage.stageWidth - buttons.width >> 1;
                buttons.y = stage.stageHeight - buttons.height >> 1;
                timeLabel = new Label(this);
                timeLabel.y = buttons.y + buttons.height;
            }
            buttons.reset();
            
            timeLabel.text = "00:00:00";
            timeLabel.x = stage.stageWidth - timeLabel.width >> 1;
            buttons.visible = false;
            buttons.shuffle();
            baseTime = lastTime = new Date().getTime();
            phase = phaseCountDown;
            addChild(buttons);
            addChild(timeLabel);
            addChild(effectSh);
            addChild(tweet);
            removeEventListener(Event.ENTER_FRAME, loop);
            addEventListener(Event.ENTER_FRAME, loop);
        }
        
        private function loop(e:Event):void 
        {
            var t: int = new Date().getTime();
            if (lastTime > t) 
            {
                buttons.reset();
                removeEventListener(Event.ENTER_FRAME, loop);
                label.text = "時間の変化を感知しました。\n一度リセットします。";
                addChild(label);
                addChild(start);
                baseTime = 0;
                phase = phaseCountDown;
                effectCount = 0;
                effectSh.graphics.clear();
                return;
            }
            var c: int;
            switch (phase)
            {
                case phaseCountDown:
                    while (lastTime < t)
                    {
                        if (lastTime - baseTime == 1000) setEffect(numbers[0]);
                        if (lastTime - baseTime == 2000) setEffect(numbers[1]);
                        if (lastTime - baseTime == 3000) setEffect(numbers[2]);
                        if (lastTime - baseTime == 4000) setEffect(numbers[3]);
                        if (lastTime - baseTime == 5000) setEffect(numbers[4]);
                        if (lastTime - baseTime == 6000) setEffect(numbers[5]);
                        if (lastTime - baseTime == 7000) 
                        {
                            phase = phaseGameMain;
                            baseTime = lastTime;
                            buttons.visible = true;
                        }
                        ++lastTime;
                    }
                break;
                case phaseGameMain:
                    lastTime = t;
                    c = (lastTime - baseTime) / 10;
                break;
                case phaseGameClear:
                    
                    c = clearTime / 10;
                break;
            }
            drawEffect();
            var time: String = "";
            for (var i:int = 0; i < 8; i++) 
            {
                if (i % 3 == 2) time = ":" + time;
                else if (i == 4) time = (c % 6) + time, c /= 6;
                else time = (c % 10) + time, c /= 10
            }
            timeLabel.text = time;
            timeLabel.x = stage.stageWidth - timeLabel.width >> 1;
        }
        
        private function drawEffect():void
        {
            if (effectCount == 0) return;
            -- effectCount;
            var g: Graphics = effectSh.graphics;
            g.clear();
            if (effectCount == 0)
            {
                
                return;
            }
            effectMatrix.a = effectMatrix.d = effectMatrix.tx = effectMatrix.ty = 0;
            var w: int = effectTarget.width, h: int = effectTarget.height;
            effectMatrix.a = effectMatrix.d = (w + (30 - effectCount) * (w / 80) * 2) / w;
            effectMatrix.tx = - w * effectMatrix.a / 2;
            effectMatrix.ty = - h * effectMatrix.d / 2;
            g.beginBitmapFill(effectTarget, effectMatrix);
            g.drawRect(effectMatrix.tx, effectMatrix.ty, w * effectMatrix.a, h * effectMatrix.d);
        }
        
        private function setEffect(bmd: BitmapData): void
        {
            effectTarget = bmd;
            effectCount = 31;
        }
        
        private function onMiss():void
        {
            // ペナルティはめんどいから無し
        }
        
        private function onClear():void
        {
            clearTime = lastTime - baseTime;
            bestTime = clearTime < bestTime ? clearTime : bestTime;
            phase = phaseGameClear;
            tweet.enabled = true;
            new MyScoreForm(this, 
                stage.stageWidth - BasicScoreForm.WIDTH >> 1,
                stage.stageHeight - BasicScoreForm.HEIGHT >> 1,
                clearTime, _showRanking
            );
        }
        
        private function _showRanking():void
        {
            new MyRanking(this, 
                stage.stageWidth - BasicScoreRecordViewer.WIDTH >> 1, 
                stage.stageHeight - BasicScoreRecordViewer.HEIGHT >> 1, 
                99, false, onClickStart
            ).defaultColor = 0;
        }
        
        private function cerateFullScreenBtn():void {
            var btn:Sprite = new Sprite();
            btn.buttonMode = true;
            btn.graphics.beginFill(0x808080, 0);
            btn.graphics.drawRect(0, 0, 60, 40);
            btn.graphics.endFill();
            btn.graphics.beginFill(0x808080, 0.5);
            btn.graphics.drawRect(6, 6, 49, 29);
            btn.graphics.endFill();
            btn.graphics.lineStyle(1, 0x808080, 0.5);
            btn.graphics.drawRect(0.5, 0.5, 60, 40);
            btn.x = 5;
            btn.y = 5;
            btn.addEventListener(MouseEvent.CLICK, btn_clickHandler);
            addChild(btn);
        }
        
        private function btn_clickHandler(event:MouseEvent):void {
            stage.displayState = stage.displayState == StageDisplayState.FULL_SCREEN
                ? StageDisplayState.NORMAL
                : stage.displayState = StageDisplayState.FULL_SCREEN;
        }
    }
}
import com.bit101.components.Component;
import com.bit101.components.HBox;
import com.bit101.components.InputText;
import com.bit101.components.PushButton;
import com.bit101.components.Style;
import com.bit101.components.VBox;
import flash.events.Event;
import flash.display.DisplayObjectContainer;
import org.libspark.betweenas3.tweens.ITween;

class Buttons extends Component
{
    private var btns: Array/*PushButton*/ = [];
    private var now: int;
    private var compHandler: Function;
    private var missHandler: Function;
    
    function Buttons(compHandler: Function, missHandler: Function, parent:DisplayObjectContainer = null)
    {
        this.compHandler = compHandler;
        this.missHandler = missHandler;
        super(parent, 0, 0);
    }
    
    override protected function addChildren():void 
    {
        var btn: PushButton;
        var size: int = Style.fontSize;
        Style.fontSize = 12;
        for (var i:int = 0; i < 25; i++) 
        {
            btns[i] = btn = new PushButton(this, 0, 0, "" + (i + 1), onClickButton);
            btn.setSize(80, 80);
            btn.tag = i;
        }
        Style.fontSize = size;
        //shuffle();
        setSize(80 * 5, 80 * 5);
    }
    
    public function sort(): void
    {
        var btn: PushButton;
        for (var i:int = 0; i < 25; i++) 
        {
            btn = btns[i];
            btn.x = (i % 5) * 80;
            btn.y = (i / 5 | 0) * 80;
        }
    }
    
    public function shuffle(): void
    {
        for (var i:int = 0; i < 20; i++) _shuffle();
        sort();
    }
    
    private function _shuffle():void
    {
        var i: int = 25, j: int, t: PushButton;
        while (i)
        {
            j = Math.random() * i;
            t = btns[--i];
            btns[i] = btns[j];
            btns[j] = t;
        }
    }
    
    public function reset(): void
    {
        var btn: PushButton;
        for (var i:int = 0; i < 25; i++) 
        {
            btn = btns[i];
            btn.enabled = true;
        }
        now = 0;
        visible = false;
        shuffle();
    }
    
    private function onClickButton(e: Event):void
    {
        var btn: PushButton = PushButton(e.target);
        if (btn.tag == now)
        {
            btn.enabled = false;
            
            if (++now == 25)
            {
                now = 0;
                compHandler();
            }
        }
        else 
        {
            missHandler();
        }
    }
}import com.adobe.serialization.json.JSON;
import com.bit101.components.Label;
import com.bit101.components.PushButton;
import flash.display.DisplayObjectContainer;
import flash.display.Loader;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import net.wonderfl.score.basic.BasicScoreForm;
import net.wonderfl.score.basic.BasicScoreRecordViewer;
import net.wonderfl.score.basic.Window;
import org.libspark.betweenas3.BetweenAS3;

class MyScoreForm extends BasicScoreForm {
    private var _confirm:Window;
    private var _onFadeOutComplete:Function;
    
    public function MyScoreForm($parent:DisplayObjectContainer = null, $xpos:Number = 0, $ypos:Number = 0, $score:int = 0, $onFadeOutComplete:Function = null) {
        _onFadeOutComplete = $onFadeOutComplete;
        // changing the texts used in the labels
        super($parent, $xpos, $ypos, $score, 'LAP TIME');
        
        // add icon to the score form
        var iconURL:String = this.root.loaderInfo.parameters["viewer.iconURL"];
        
        if (iconURL) {
            var ldr:Loader = new Loader;
            ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, function ():void {
                ldr.scaleX = ldr.scaleY = 0.5;
            });
            ldr.load(new URLRequest(iconURL));
            ldr.y = _lblYourScore.y;
            ldr.x = 10;
            _lblYourName.x += 20;
            _lblYourScore.x += 20;
            _lblScore.x += 20;
            _userNameField.x += 20;
            _window.addChild(ldr);
        }
        
        // scaling & adding units to the score
        // note : this does not affect the actual value
        // registered in the database. the score is treated
        // as integer in the database.
        _lblScore.text = $score / 1000 + ' [sec]';
        // changing the texts used in the labels
        _lblYourScore.text = 'LAP TIME :';
        _lblYourName.text = 'PLAYER :';
        // changing the labels used in the button
        _btnSend.label = 'REGISTER';
    }
    
    override protected function onSendClick($event:MouseEvent):void 
    {
        super.onSendClick($event);
        // changing the text when button is pressed
        _btnSend.label = 'REGISTERING...';
    }
    
    override protected function onError($errorMessage:String):void 
    {
        super.onError($errorMessage);
        _btnSend.label = 'REGISTER';
    }
    
    override protected function onComplete():void 
    {
        super.onComplete();
        _btnSend.label = 'FINISH';
        
        _onCloseClick(saveComplete);
    }
    
    override protected function _onCloseClick($didSendComplete:Boolean):void 
    {
        if ($didSendComplete) {
            _closeWindow(null);
        } else {
            if (_confirm) {
                _confirm.x = _confirm.y = 0;
                addChild(_confirm);
            } else {
                _confirm = new Window(this, 0, 0, 'CONFIRM', _closeWindow);
                _confirm.setSize(280, 160);
                new PushButton(_confirm, 30, 100, 'CANCEL', _onConfirmCancel);
                new PushButton(_confirm, 150, 100, 'OK', _closeWindow);
                new Label(_confirm, 40, 60, 'CLOSING THIS DIALOG...');
            }
        }
    }
    
    private function _onConfirmCancel(e:MouseEvent):void
    {
        removeChild(_confirm);
    }
    
    private function _closeWindow(e:MouseEvent = null):void
    {
        BetweenAS3.serial(
            BetweenAS3.to(this, {alpha:0}, 0.6),
            BetweenAS3.removeFromParent(this),
            BetweenAS3.func(
                _onFadeOutComplete
            )
        ).play();
    }
}

class MyRanking extends BasicScoreRecordViewer {
    private var _defaultColor:uint;
    private var _closeHandler: Function;
    public function MyRanking($parent:DisplayObjectContainer = null, $xpos:Number = 0, $ypos:Number = 0, $limit:int = 20, $descend:Boolean = true, closeHandler: Function = null) {
        alpha = 0;
        _closeHandler = closeHandler;
        super($parent, $xpos, $ypos, 'LAP TIME RANKING', $limit, $descend, _onCloseClick);
    }
    
    private function _onCloseClick():void
    {
        var t: ITween = BetweenAS3.serial(
            BetweenAS3.to(this, { alpha:0 }, 0.6),
            BetweenAS3.removeFromParent(this)
        );
        t.onComplete = _closeHandler;
        t.play();
    }
    
    override protected function onComplete($data:Array):void 
    {
        alpha = 0;
        // scaling & adding units to the score
        // note : this does not affect the actual value
        // registered in the database. The score is treated
        // as integer in the database.
        $data
        .forEach(
            function ($item:Object, $index:int, $array:Array):void {
                $item.score = ($item.score / 1000) + ' [sec]';
            }
        );
        
        super.onComplete($data);
        _list.defaultColor = _defaultColor;
        BetweenAS3.to(this, { alpha:1 }, 0.9).play();
    }
    
    public function get defaultColor():uint { return _defaultColor; }
    //
    public function set defaultColor(value:uint):void 
    {
        _defaultColor = value;
        if (_list) _list.defaultColor = value;
    }
}