習作:ブロック崩し

by fumix
♥0 | Line 216 | Modified 2012-11-26 21:44:10 | MIT License
play

ActionScript3 source code

/**
 * Copyright fumix ( http://wonderfl.net/user/fumix )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/bCOq
 */

package {
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.utils.getTimer;

    public class Game extends Sprite {
        private var _ball : Sprite;
        private var _ballSpeed : Number;
        private var _ballSpeedX : Number;
        private var _ballSpeedY : Number;
        private var _tickBefore:Number;
        private var _scoreTextField : TextField;
        private var _score : int;
        private var _bar : Sprite;
        private var _blocks : Array;
        private var _firstBlocks : Blocks;
        private var _bleakBlockCount : int;
        
        public function Game() : void {
            if (stage) _initialize();
            else addEventListener(Event.ADDED_TO_STAGE, _initialize);
        }

        /**
         * _initialize
         */
        private function _initialize(e : Event = null) : void {
            removeEventListener(Event.ADDED_TO_STAGE, _initialize);


            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;

            // ボール
            _ball = new Sprite();
            _ball.graphics.beginFill(0xFF0000);
            _ball.graphics.drawCircle(0, 0, 8);
            _ball.graphics.endFill();
            addChild(_ball);
            // ボール初期設定
            _ballSpeed = 0.50;
            _ballSpeedX = Math.cos(45 * Math.PI / 180) * _ballSpeed;
            _ballSpeedY = Math.sin(45 * Math.PI / 180) * _ballSpeed;
            _ball.x = 50;
            _ball.y = 320;

            // スコア
            _scoreTextField = new TextField();
            score = 10;
            addChild(_scoreTextField);

            // バー
            _bar = new Sprite();
            _bar.graphics.beginFill(0x999999);
            _bar.graphics.drawRect(-40, -10, 80, 20);
            _bar.graphics.endFill();
            addChild(_bar);
            _bar.y = 400;

            // ブロック
            _bleakBlockCount = 0;
            var offsetX : int = 40+13;
            var offsetY : int = 40;
            var margin : int = 0;
            var blockNo:int = 0;
            var old:Blocks;
            _blocks = new Array();
            for (var dx : int = 0; dx < 14; dx++) {
                for (var dy : int = 0; dy < 4; dy++) {
                    var block : Sprite = new Sprite();
                    block.graphics.lineStyle(1, 0x999999);
                    block.graphics.beginFill(0xCCCCCC);
                    block.graphics.drawRect(-13, -19, 27, 38);
                    block.graphics.endFill();
                    block.x = dx * block.width + offsetX + margin;
                    block.y = dy * block.height + offsetY + margin;
                    block.name = 'block'+blockNo;
                    //ナンバー
                    var tf:TextField = new TextField();
                    tf.selectable = false;
                    tf.autoSize = TextFieldAutoSize.LEFT;
                    tf.text = String(blockNo);
                    block.addChild(tf);
                    //ブロックをリンクリストに代入
                    var b:Blocks = new Blocks();
                    b.block = block;
                    _blocks.push(b);
                    if(_firstBlocks == null){
                        old = _firstBlocks = b;
                    }else{
                        old.next = b;
                        old = b;
                    }

                    addChild(block);
                    blockNo++;
                }
            }

            stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
        }

        private function onStageMouseDown(event : MouseEvent) : void {
            stage.removeEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
            addEventListener(Event.ENTER_FRAME, _updateHandler);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDownChangeFPS);
        }

        private function onStageMouseDownChangeFPS(event : MouseEvent) : void {
            if(stage.frameRate < 60) {
                stage.frameRate = 60;
            }else{
                stage.frameRate = 30;                
            }
        }


        private function _updateHandler(e : Event) : void {
            _interaction();
            _draw();
        }

        /**
         * インタラクションの反映
         */
        private function _interaction() : void {
            // バーの移動アクション
            moveBar();
            // ボールの反射アクション
            moveBall();
            // ゲームエンド判定
            checkGameEnd();
        }
        /**
         * ゲームエンド判定
         */
        private function checkGameEnd() : void {
            //ブロック全部消せた?
            if (_bleakBlockCount >= _blocks.length) {
                removeEventListener(Event.ENTER_FRAME, _updateHandler);
            //スコアがマイナス?
            }else if(score < 0){
                removeEventListener(Event.ENTER_FRAME, _updateHandler);
            }
        }
        /**
         * ボールの反射判定
         */
        private function moveBall() : void {
            //壁への反射判定
            if (stage.stageWidth - _ball.width * 0.5 < _ball.x ) {
                _ball.x = stage.stageWidth - _ball.width * 0.5;
                _ballSpeedX = -_ballSpeedX;
            }
            if (_ball.width * 0.5 > _ball.x) {
                _ball.x = _ball.width * 0.5;
                _ballSpeedX = -_ballSpeedX;
            }
            if (stage.stageHeight - _ball.height * 0.5 < _ball.y ) {
                _ball.y = stage.stageHeight - _ball.height * 0.5;
                _ballSpeedY = -_ballSpeedY;
                //下に逃した場合はスコアマイナス
                score = score - 5;
            }
            if (_ball.height * 0.5 > _ball.y) {
                _ball.y = _ball.height * 0.5;
                _ballSpeedY = -_ballSpeedY;
            }
            //バーへの反射判定
            if (_ball.hitTestObject(_bar)) {
                if(_ball.y < _bar.y) {
                    _ball.y = _bar.y - _ball.height * 0.5 - _ball.height * 0.5;                    
                }else{
                    _ball.y = _bar.y + _ball.height * 0.5 + _ball.height * 0.5;                                        
                }
                
                var rad : Number = Math.atan2(_ball.y - _bar.y, _ball.x - _bar.x);
                _ballSpeedX = Math.cos(rad) * _ballSpeed;
                _ballSpeedY = Math.sin(rad) * _ballSpeed;
            }
            //ブロックへの反射判定
            var b:Blocks = _firstBlocks;
            var flg:Boolean = true;//ブロックの当たり判定は1個しかしない
            do {
                if(_ball.hitTestObject(b.block) && b.visible && flg){
                    //ブロックを非表示に
                    b.block.visible = false;
                    b.visible = false;
                    flg = false;
                    //スコアをアップ
                    score++;
                    //壊れたブロック数をカウントアップ
                    _bleakBlockCount++;
                    //左上に当たった場合
                    if(_ball.x < b.block.x-b.block.width * 0.5+_ball.width * 0.5 &&
                    _ball.y < b.block.y-b.block.height * 0.5+_ball.height * 0.5){
                        _ballSpeedX = -Math.cos(45 * Math.PI / 180) * _ballSpeed;
                        _ballSpeedY = -Math.sin(45 * Math.PI / 180) * _ballSpeed;                        
                    }
                    //右上に当たった場合
                    else if(_ball.x > b.block.x+b.block.width * 0.5-_ball.width * 0.5 &&
                    _ball.y < b.block.y-b.block.height * 0.5+_ball.height * 0.5){
                        _ballSpeedX = Math.cos(45 * Math.PI / 180) * _ballSpeed;
                        _ballSpeedY = -Math.sin(45 * Math.PI / 180) * _ballSpeed;                        
                    }
                    //左下に当たった場合
                    else if(_ball.x < b.block.x-b.block.width * 0.5+_ball.width * 0.5 &&
                    _ball.y > b.block.y+b.block.height * 0.5-_ball.height * 0.5){
                        _ballSpeedX = -Math.cos(45 * Math.PI / 180) * _ballSpeed;
                        _ballSpeedY = Math.sin(45 * Math.PI / 180) * _ballSpeed;                                            
                    }
                    //右下に当たった場合
                    else if(_ball.x > b.block.x+b.block.width * 0.5-_ball.width * 0.5 &&
                    _ball.y > b.block.y+b.block.height * 0.5-_ball.height * 0.5){
                        _ballSpeedX = Math.cos(45 * Math.PI / 180) * _ballSpeed;
                        _ballSpeedY = Math.sin(45 * Math.PI / 180) * _ballSpeed;                                            
                    }
                    //上に当たった場合
                    else if(_ball.y < b.block.y-b.block.height * 0.5+_ball.height * 0.5){
                        _ballSpeedY = -_ballSpeedY;                        
                    }
                    //下に当たった場合
                    else if(_ball.y > b.block.y+b.block.height * 0.5-_ball.height * 0.5){
                        _ballSpeedY = -_ballSpeedY;                        
                    }
                    //左に当たった場合
                    else if(_ball.x < b.block.y-b.block.width * 0.5+_ball.width * 0.5){
                        _ballSpeedX = -_ballSpeedX;                        
                    }
                    //右に当たった場合
                    else if(_ball.x > b.block.x+b.block.width * 0.5-_ball.width * 0.5){
                        _ballSpeedX = -_ballSpeedX;                        
                    }
                }
            } while (b = b.next);
            
        }

        /**
         * バーの移動
         */
        private function moveBar() : void {
            _bar.x = mouseX;
        }

        /**
         * 描画
         */
        private function _draw() : void {
            var tick: int = getTimer();
            var t: int = tick - _tickBefore;
            _tickBefore = tick;
            _ball.x += _ballSpeedX*t;
            _ball.y += _ballSpeedY*t;
        }

        public function get score() : int {
            return _score;
        }

        public function set score(score : int) : void {
            _score = score;
            _scoreTextField.text = String(_score);
        }
    }
}
import flash.display.Sprite;


//ブロック配列用
class Blocks
{
    public var visible:Boolean;
    public var block:Sprite;
    public var next:Blocks;
    public function Blocks()
    {
        visible = true;
        block = null;
    }
}