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

forked from: 星屑ブロック崩し

リセットボタン追加
ランキング表示機能追加
Twitterに投稿されている点数からランキングを計算

普通のブロック崩しです。
最初からあるボールが落ちるとGameOverです。
高得点目指して頑張ってください。
結果はTwitterでつぶやけます。

アイテム
星: 星型のボールになります。
ハート: 反射バーの大きさの変更
/**
 * Copyright iflex4 ( http://wonderfl.net/user/iflex4 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/u8H1
 */

// forked from matsu4512's 星屑ブロック崩し
/*
   リセットボタン追加
   ランキング表示機能追加
   Twitterに投稿されている点数からランキングを計算

   普通のブロック崩しです。
   最初からあるボールが落ちるとGameOverです。
   高得点目指して頑張ってください。
   結果はTwitterでつぶやけます。

   アイテム
   星: 星型のボールになります。
   ハート: 反射バーの大きさの変更
 */

package
{
    import __AS3__.vec.Vector;
    import com.adobe.serialization.json.JSON;
    import com.bit101.components.PushButton;
    import net.wonderfl.utils.SequentialLoader;
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.media.SoundChannel;
    import flash.media.SoundTransform;
    import flash.net.*;
    import flash.system.Security;
    import flash.text.*;
    import flash.utils.escapeMultiByte;
    
    import org.si.sion.*;

    [SWF(backgroundColor=0x00f0f, width=465, height=465, frameRate=60)]
    public class BreakBlock extends Sprite
    {
        
        //背景画像読み込み用    
        private var imageArray:Array=[];
        private var imageUrl:String="http://assets.wonderfl.net/images/related_images/1/16/162f/162fabe272eae4e0e084575ac63ac9545f4e2bd2";
        //private var imageUrl:String="pic3.jpg";
        //private var imageLoader:Loader;

        //Twitter用
        private var postUrl:String="http://twitter.com/home?status=";
        private var wonderflUrl:String="http://bit.ly/9xsPLp %23StardustBreakout";
        //状態 0:ゲーム中、1:Not Clear, 2:Clear
        public var status:int;

        public static const W:Number=388; // ゲームステージの幅
        public static const H:Number=465; // ゲームステージの高さ
        public static const ITEM_PROBABILITY:Number=0.3; //アイテムの出る確率
        public static const STAR_PROBABILITY:Number=0.7;
        public static const HEART_PROBABILITY:Number=0.3;
        public static const FAIL:String="fail"; //FAILイベント
        public static const CLEAR:String="clear"; //clearイベント
        public static const block_row:int=10; // ブロックの行数
        public static const block_column:int=10; // ブロックの列数
        public static const block_width:Number=38.9; // ブロックの幅
        public static const block_height:Number=15.5; //ブロックの高さ
        public static const bar_width:Number=62; //反射バーの幅
        public static const bar_height:Number=15.5; //反射バーの高さ
        public static const ball_size:Number=4; //ボールのサイズ
        private static const SPEED:Number=6; //メインの球のスピード
        private static const BLOCK_COLOR:uint=0x0000ff; //ブロックの色

        private var score:int=0; //スコア
        private var ball_bmp:Bitmap; // 表示用Bitmap
        private var block_bmp:Bitmap; //Blockを描くBitmap
        private var block_bmpData:BitmapData;
        private var ball_bmpData:BitmapData; // canvasの内容を記録するためのBitmapData
        private var counter:TextField; // カウントフィールド
        private var message:TextField; // メッセージフィールド
        private var scoreTxt:TextField; //スコアフィールド
        private var clickStart:TextField; //クリックスタート
        private var rankTxt:TextField;
        private var remainBall:int;
        private var block_count:int;
        public var ball_canvas:Sprite; // Ballなどを描画するSprite
        public var block_canvas:Sprite; //Blockを描くSprite
        public var BlockList:Vector.<Block>; // ブロック格納配列
        public var bar:Bar // ボード

        public var ballNum:int;
        public var soundDriver:SiONDriver;
        //BGM
        private var data:SiONData;
        private var bgm:SoundChannel;
        //効果音
        public var se:SiONData;


        //キラキラのためのもの
        private var glow_bmpData:BitmapData;
        private var glowMtx:Matrix;
        private var particle_bmpData:BitmapData;
        //キラキラパーティクルを格納する配列
        public var particleList:Vector.<Particle>;

        //ランキングの取得用
        //現在読み込んでいるページ数
        private var page:int=1;
        //1ページの要素数
        private var rpp:int=100;
        private var twitterLoader:URLLoader;
        private var rankUrl:String = "http://search.twitter.com/search.json?q=%23StardustBreakout";
        private var ary:Array=[];

        private var rank:int=0;
        private var userNum:int=0;

        private var resetBtn:PushButton;
        private var twitBtn:PushButton;
        public var expFlg:int=0;

        public function BreakBlock()
        {
            status=0;
            ballNum=0;
            soundDriver=new SiONDriver();

            //コンパイル
            data=soundDriver.compile("t80o7l8r10[g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b<g>b<f+>b<d>b<e>b<f+>b<e>b<d>b<e>b]10");
            se=soundDriver.compile("t300 l8 <<b<e");

            //背景絵を設定
        //    imageLoader=new Loader();
        //    imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
        //    imageLoader.load(new URLRequest(imageUrl));
            SequentialLoader.loadImages([imageUrl], imageArray, onLoaded);
        }

        private function onLoaded():void
        {
                var loader:Loader=imageArray.pop();
                var backData:BitmapData = new BitmapData(W, H);
                backData.draw(loader);
                var back:Bitmap=new Bitmap(backData);
            //var back:Bitmap=event.target.content as Bitmap;
            back.width=W;
            back.height=H;
            addChild(back);
            // BitmapDataの作成
            ball_bmpData=new BitmapData(W, H, true, 0x0);
            // BitmapDataの内容からBitmapを生成
            ball_bmp=new Bitmap(ball_bmpData);
            // Bitmapを表示
            addChild(ball_bmp);
            ball_canvas=new Sprite;

            // BitmapDataの作成
            block_bmpData=new BitmapData(W, H, true, 0x0);
            // BitmapDataの内容からBitmapを生成
            block_bmp=new Bitmap(block_bmpData);
            // Bitmapを表示
            addChild(block_bmp);
            block_canvas=new Sprite;

            //キラキラの準備
            particle_bmpData=new BitmapData(W, H, true, 0xFF000000);
            addChild(new Bitmap(particle_bmpData));
            glow_bmpData=new BitmapData(W / 4, H / 4, false, 0x0);
            var bm:Bitmap=addChild(new Bitmap(glow_bmpData, PixelSnapping.NEVER, true)) as Bitmap;
            bm.scaleX=bm.scaleY=4;
            bm.blendMode=BlendMode.ADD;
            glowMtx=new Matrix(0.25, 0, 0, 0.25);

            particleList=new Vector.<Particle>();

            // バーの作成
            bar=new Bar(this, W / 2, H - 50, 0x0000FF, bar_width, bar_height);
            ball_canvas.addChild(bar);

            // カウントフィールドの作成
            counter=createField();
            counter.x=W;
            addChild(counter);

            // メッセージフィールド作成
            message=createField();

            rankTxt=createField();

            scoreTxt=createField();
            scoreTxt.x=W;
            scoreTxt.y=50;
            addChild(scoreTxt);

            clickStart=createField();
            
            addEventListener(FAIL, notClear);
            addEventListener(CLEAR, clear);
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
            create();
        }

        private function create():void
        {
            // 要素の型がBlockのVectorを作成
            BlockList=new Vector.<Block>();

            // ブロック作成
            var color:uint=BLOCK_COLOR;
            var b:Block;
            var item:Item;
            var type:int; // アイテムタイプ
            var item_color:uint;
            var rand:Number; // 乱数格納
            for (var i:int=0; i < block_row; i++)
            {
                color+=0xf;
                for (var j:int=0; j < block_column; j++)
                {
                    b=new Block(this, j * block_width, i * block_height, color, block_width, block_height);
                    // ball_canvas上に表示(画面上に見えない)
                    block_canvas.addChild(b);
                    // 配列に追加
                    BlockList.push(b);
                }
            }

            block_bmpData.draw(block_canvas);
            ball_bmpData.draw(ball_canvas);

            rankTxt.text="";
            scoreTxt.text="Score:\n0";
            clickStart.text="Click Start!!";
            clickStart.x=W / 2 - clickStart.width / 2;
            clickStart.y=H / 2 - clickStart.height / 2;
            addChild(clickStart);

            stage.addEventListener(MouseEvent.CLICK, start);
        }

        private function start(event:MouseEvent):void
        {
            if (event.target != stage)
                return;
            expFlg=0;
            status=0;
            var theta:Number=Math.random() * Math.PI;
            if (theta < Math.PI / 6)
                theta=Math.PI / 6;
            else if (theta > 5 * Math.PI / 6)
                theta=5 * Math.PI / 6;
            // ボールの作成
            var ball:Ball=new Ball(this, W / 2, H - 100, SPEED * Math.cos(theta), -SPEED * Math.sin(theta), 0.0, 0xFFFFFF, ball_size);
            ball_canvas.addChild(ball);

            stage.removeEventListener(MouseEvent.CLICK, start);
            removeChild(clickStart);

            //bgmを再生
            bgm=soundDriver.play(data);
            var st:SoundTransform=new SoundTransform();
            st.volume=0.2;
            bgm.soundTransform=st;
        }

        //スコアの加算
        public function addScore(value:int):void
        {
            if (status != 0)
                return;
            score+=value;
            scoreTxt.text="Score:\n" + score.toString();
        }

        // テキストフィールド作成関数
        private function createField():TextField
        {
            var tf:TextField=new TextField;
            // フォント、サイズ、色を決める
            tf.defaultTextFormat=new TextFormat("Swis721 BdRndBT", 20, 0xFFFFFF);
            tf.autoSize=TextFieldAutoSize.LEFT;
            return tf;
        }

        private function displayMessage(str:String):void
        {
            ball_bmpData.lock();
            ball_bmpData.fillRect(ball_bmpData.rect, 0x0);
            ball_bmpData.unlock();
            message.text=str;
            // ゲームステージの中央に合わせる
            message.x=W / 2 - message.width / 2;
            message.y=H / 2 - message.height / 2;
            addChild(message);
        }

        //クリア出来なかった
        private function notClear(event:Event):void
        {
            remainBall=block_count;
            if (status != 0)
                return;
            status=1;
            displayMessage("Game Over!!");

            createButton();
        }

        //クリア
        private function clear(event:Event):void
        {
            if (status != 0)
                return;
            status=2;
            ary=[];
            page=1;
            userNum=0;
            rank = 0;
            displayMessage("THANK YOU FOR PLAYING\nCONGRATULATION!!");
            twitterLoader = new URLLoader(new URLRequest(rankUrl + "&rpp="+rpp.toString()+"&page=" + page.toString()));
            twitterLoader.addEventListener(Event.COMPLETE, onLoadTwitter);
            twitterLoader.addEventListener(IOErrorEvent.IO_ERROR, error);
        }
        
        //検索結果の取得
        private function onLoadTwitter(event:Event):void{
            var str:String = event.target.data;
            var obj:Object = JSON.decode(str);
            if((obj.results as Array).length == rpp){
                page++;
                twitterLoader.load(new URLRequest(rankUrl + "&rpp="+rpp.toString()+"&page=" + page.toString()));
                ary = ary.concat(obj.results as Array);
                return;
            }
            
            ary = ary.concat(obj.results as Array);
            
            var exp1:RegExp = /(\[星屑ブロック崩し\]|\[星空ブロック崩し\])Clearおめでとう! あなたのスコアは[0-9]+点です。/;
            var exp2:RegExp = /[0-9]+/;
            var exp3:RegExp = /RT|QT/;
            var resultMap:Object = {};
            for(var i:int = 0; i < ary.length; i++){
                var tmp:String = ary[i].text;
                var user:String = ary[i].from_user;
                if(exp3.exec(tmp) != null) continue;
                tmp = exp1.exec(tmp);
                tmp = exp2.exec(tmp);
                if(resultMap[user] == undefined){
                    resultMap[user] = tmp;
                }
                else{
                    if(int(tmp) > int(resultMap[user])){
                        resultMap[user] = tmp;
                    }
                }
            }
            for each(i in resultMap){
                if(i < score) rank++;
                userNum++;
            }
            rank = userNum-rank+1;
            userNum++;
            rankTxt.text = userNum.toString() + "人中" + rank.toString() + "位";
            rankTxt.x = W/2 - rankTxt.width/2;
            rankTxt.y = H/2 - rankTxt.height/2 + message.height;
            addChild(rankTxt);
            createButton();
        }

        private function error(event:IOErrorEvent):void
        {
            createButton();
        }

        private function createButton():void
        {
            twitBtn=new PushButton(this, W / 2, H / 2 + message.height + rankTxt.height, "Twitter", twitter);
            twitBtn.x-=twitBtn.width / 2;
            resetBtn=new PushButton(this, W / 2, twitBtn.y + twitBtn.height + 10, "Restart", reset);
            resetBtn.x-=resetBtn.width / 2;
        }



        private function reset(event:MouseEvent):void
        {
            score=0;
            ballNum=0;
            expFlg=1;
            removeChild(twitBtn);
            removeChild(resetBtn);
            removeChild(message);
            for (var i:int=0; i < BlockList.length; i++)
            {
                BlockList[i].explosion();
            }
            create();
        }

        //Twitterに投稿
        private function twitter(event:MouseEvent):void
        {
            var url:String
            if (status == 2)
            {
                url=postUrl + escapeMultiByte("[星屑ブロック崩し]Clearおめでとう! あなたのスコアは") + score.toString() + escapeMultiByte("点です。");
                if (rankTxt.text != "")
                    url+=escapeMultiByte(userNum.toString() + "人中" + rank.toString() + "位")
            }
            else if (status == 1 && block_count == 0)
            {
                url=postUrl + escapeMultiByte("[星屑ブロック崩し]ブロック全消しおめでとう!だけどGame Overだよ!!");
            }
            else if (status == 1)
            {
                url=postUrl + escapeMultiByte("[星屑ブロック崩し]Game Over あなたは残り") + remainBall.toString() + escapeMultiByte("個のブロックを残して力尽きました。");
            }
            url+=wonderflUrl;
            navigateToURL(new URLRequest(url));
        }

        private function onEnterFrame(event:Event):void
        {
            block_count=BlockList.length;
            counter.text="Block数:\n" + block_count;

            glow_bmpData.fillRect(glow_bmpData.rect, 0x0);
            particle_bmpData.fillRect(particle_bmpData.rect, 0x00000000);
            particle_bmpData.lock();

            //キラキラパーティクルを動かすよ
            var i:int=particleList.length;
            while (i--)
            {
                var p:Particle=particleList[i];
                particle_bmpData.setPixel32(p.x, p.y, p.color);
                p.update();
                if (p.y > H)
                {
                    particleList.splice(i, 1);
                }
            }

            //描画
            particle_bmpData.unlock();
            glow_bmpData.draw(particle_bmpData, glowMtx);

            block_bmpData.fillRect(block_bmpData.rect, 0x0);
            block_bmpData.draw(block_canvas);

            ball_bmpData.draw(ball_canvas);
            ball_bmpData.colorTransform(ball_bmpData.rect, new ColorTransform(1.5, 1.0, 1.5, 0.85));
        }
    }
}

import __AS3__.vec.Vector;
import flash.display.Shape;
import flash.events.Event;
import flash.filters.GlowFilter;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.tweens.ITween;
import flash.filters.GlowFilter;
import flash.geom.Matrix;
import flash.display.Sprite;
import flash.geom.Point;

class Obj extends Shape
{
    protected var field:BreakBlock;
    protected var color:uint;

    public function Obj(field:BreakBlock)
    {
        this.field=field;
    }

    protected function enterFrame(event:Event):void
    {
        if (field.expFlg)
            explosion();
        update();
    }

    //画面上から消す
    public function deleteObj():void
    {
        removeEventListener(Event.ENTER_FRAME, enterFrame);
        parent.removeChild(this);
    }

    protected function update():void
    {
    }

    protected function draw():void
    {
    }

    public function explosion():void
    {
        var num:int=width * height / 10;
        //キラキラパーティクルの発生
        for (var i:int=0; i < num; i++)
        {
            var p:Particle=new Particle(x + width / 2, y + height / 2, Math.random() * 10 - 5, Math.random() * 10 - 5, color);
            field.particleList.push(p as Particle);
        }
        deleteObj();
    }
}

//通常のボールクラス
class Ball extends Obj
{
    //Blockの参照
    protected var blocks:Vector.<Block>;
    //Barの参照
    private var bar:Bar;
    protected var value:int; //基礎点
    protected var vx:Number; // x方向の移動量
    protected var vy:Number; // y方向の移動量
    protected var vz:Number;
    protected var va:Number; // alphaの変化量
    protected var r:Number; // 半径
    protected var heaven:int; //貫通モードフラグ
    protected var judgeLine1:Number; //ブロックとの判定が必要になる境界線
    protected var judgeLine2:Number; //バーとの判定が必要になる境界線

    public function Ball(field:BreakBlock, x:Number, y:Number, vx:Number, vy:Number, va:Number, c:uint, r:Number)
    {
        super(field);
        field.ballNum++;
        value=100;
        this.field=field;
        this.blocks=field.BlockList;
        this.bar=field.bar;
        this.heaven=0;
        this.color=c;
        this.x=x;
        this.y=y;
        this.vx=vx;
        this.vy=vy;
        this.va=va;
        this.vz=0;
        this.r=r;
        draw();
        filter();
        judgeLine1=BreakBlock.block_height * BreakBlock.block_row + height / 2;
        judgeLine2=field.bar.y - height / 2 - field.bar.height / 2;
        addEventListener(Event.ENTER_FRAME, enterFrame);
    }

    //描画
    override protected function draw():void
    {
        //(0,0)を中心に円を描画
        graphics.beginFill(color);
        graphics.drawCircle(0, 0, r);
        graphics.endFill();
    }

    protected function filter():void
    {
        if (heaven)
        {
            filters=[new GlowFilter(0xFF0000, 1, 16, 16, 4)];
        }
        else
        {
            filters=[new GlowFilter(0xFF0000, 1, 8, 8, 2)];
        }
    }

    override protected function update():void
    {
        if (field.status == 2)
        {
            vz=-10;
            field.addScore(2000);
        }
        if (heaven)
        {
            x+=vx * 1.5;
            y+=vy * 1.5;
            z+=vz * 1.5;
        }
        else
        {
            x+=vx;
            y+=vy;
            z+=vz;
        }

        if (y + vy < judgeLine1)
            checkBlockCollision();
        if (y + vy > judgeLine2)
            checkBarCollision();
        checkStageCollision();
        checkInField();
    }

    //画面外に出ていないかどうか
    protected function checkInField():void
    {
        if (y > BreakBlock.H)
        {
            removeEventListener(Event.ENTER_FRAME, enterFrame);
            parent.removeChild(this);
            //FAILイベントの発生
            field.dispatchEvent(new Event(BreakBlock.FAIL));
            field.ballNum--;
        }
    }

    //Block衝突判定
    protected function checkBlockCollision():void
    {
        var i:int=blocks.length;
        while (i--)
        {
            var block:Block=blocks[i];
            if (block.hitTestObject(this))
            {
                if (!heaven)
                {
                    if ((y - r) <= (block.y + block.height) || block.y <= (y + r))
                    {
                        vy*=-1;
                        y+=vy;
                    }
                    else if ((x + r) >= block.x || (block.x + block.width) >= (x - r))
                    {
                        vx*=-1;
                        x+=vx;
                    }
                }
                //ブロックにダメージ
                addScore();
                block.deleteBlock();
                blocks.splice(i, 1);
                if (blocks.length == 0)
                {
                    field.dispatchEvent(new Event(BreakBlock.CLEAR));
                }
            }
        }
    }

    //Bar衝突判定
    protected function checkBarCollision():void
    {
        // バーとボールの当たり判定
        if (this.hitTestObject(bar))
        {
            if ((bar.y - bar.height / 2) <= (y + r))
            {
                vy*=-1;
                // バーにボールがめり込むのを防ぐ
                y-=bar.height / 2 + r;
                var radian:Number=Math.atan2(y - bar.y, x - bar.x);

                var point:Point=new Point(vx, vy);
                vx=Math.cos(radian) * point.length;
                vy=Math.sin(radian) * point.length;
            }
            if (radian < -Math.PI / 2 + 0.1 && radian > -Math.PI / 2 - 0.1)
            {
                heaven=1;
                filter();
            }
            else if (heaven)
            {
                heaven=0;
                filter();
            }
        }
    }

    protected function checkStageCollision():void
    {
        //ステージ全体とボールの当たり判定
        if (x < r || x > BreakBlock.W - r)
        {
            vx*=-1;
            // ステージにめり込むのを防ぐ
            x+=vx;
        }
        else if (y < r)
        {
            vy*=-1;
            // ステージにめり込むのを防ぐ
            y+=vy;
        }
    }

    protected function addScore():void
    {
        var score:int=value;
        score+=(field.ballNum - 1) * 50;
        if (heaven)
            score*=2;
        score*=1.0 / field.bar.scaleX;
        field.addScore(score);
    }
}

//星型のボールクラス
class StarBall extends Ball
{
    public var rv:Number;

    public function StarBall(field:BreakBlock, x:Number, y:Number, vx:Number, vy:Number, va:Number, c:uint, r:Number, rv:Number)
    {
        super(field, x, y, vx, vy, va, c, r);
        this.rv=rv;
        value=200;
    }

    override protected function draw():void
    {
        var r2:Number=r / 2;
        var angle:Number=-90;
        var addtion:Number=360 / 10;
        graphics.beginFill(0xffffff);
        graphics.moveTo(0, -r);
        for (var i:int=0; i < 10; i++)
        {
            angle+=addtion;
            var to_x:Number;
            var to_y:Number;
            var radian:Number=angle * Math.PI / 180;
            if (i % 2)
            {
                to_x=r * Math.cos(radian);
                to_y=r * Math.sin(radian);
            }
            else
            {
                to_x=r2 * Math.cos(radian);
                to_y=r2 * Math.sin(radian);
            }
            graphics.lineTo(to_x, to_y);
        }
        graphics.endFill();
    }

    override protected function filter():void
    {
        if (heaven)
        {
            filters=[new GlowFilter(0xFF0000, 1, 16, 16, 4)];
        }
        else
        {
            filters=[new GlowFilter(color, 1, 8, 8, 2)];
        }
    }

    //画面外に出ていないかどうか
    override protected function checkInField():void
    {
        if (y > BreakBlock.H)
        {
            removeEventListener(Event.ENTER_FRAME, enterFrame);
            parent.removeChild(this);
            field.ballNum--;
        }
    }

    override protected function update():void
    {
        rotation+=rv;
        super.update();
    }
}

//ブロッククラス
class Block extends Obj
{
    public function Block(field:BreakBlock, x:Number, y:Number, c:uint, w:Number, h:Number)
    {
        super(field);
        this.field=field;
        this.x=x;
        this.y=y;
        this.color=c;
        // (1,1)を始点に長方形を描く
        graphics.beginFill(color);
        graphics.drawRect(1, 1, w - 1, h - 1);
        graphics.endFill();
    }

    override public function explosion():void
    {
        var num:int=width * height / 10;
        //キラキラパーティクルの発生
        for (var i:int=0; i < num; i++)
        {
            var p:Particle=new Particle(x + width / 2, y + height / 2, Math.random() * 10 - 5, Math.random() * 10 - 5, x / BreakBlock.W * 0xffffff);
            field.particleList.push(p as Particle);
        }
        deleteObj();
    }

    override public function deleteObj():void
    {
        parent.removeChild(this);
    }

    public function deleteBlock():void
    {
        var tween:ITween=BetweenAS3.to(this, {alpha: 0}, 0.3);
        tween.onComplete=function(... onCompleteParams):void
        {
            parent.removeChild(onCompleteParams[0])
        };
        tween.onCompleteParams=[this];
        tween.play();

        //効果音
        field.soundDriver.sequenceOn(field.se);

        var num:int=width * height / 10;
        //キラキラパーティクルの発生
        for (var i:int=0; i < num; i++)
        {
            var p:Particle=new Particle(x + width / 2, y + height / 2, Math.random() * 10 - 5, Math.random() * 10 - 5, Math.random() * 0xffffff);
            field.particleList.push(p as Particle);
        }

        // アイテム作成
        if (Math.random() < BreakBlock.ITEM_PROBABILITY)
        {
            var item:Item;
            if (Math.random() < BreakBlock.STAR_PROBABILITY)
            {
                item=new StarItem(field, x + width / 2, y + height / 2, 0, 4, Math.random() * 0xffffff, 5.4 * Math.random() + 4);
                field.block_canvas.addChild(item as StarItem);
            }
            else
            {
                item=new HeartItem(field, x + width / 2, y + height / 2, 0, 4, Math.round(Math.random()) * 0xffffff, 15.5);
                field.block_canvas.addChild(item as HeartItem);
            }
        }
    }
}

//反射バークラス
class Bar extends Obj
{
    private var w:Number;
    private var h:Number;

    public function Bar(field:BreakBlock, x:Number, y:Number, c:uint, w:Number=50, h:Number=20)
    {
        super(field);
        this.field=field;
        this.x=x;
        this.y=y;
        this.w=w;
        this.h=h;
        draw();

        addEventListener(Event.ENTER_FRAME, enterFrame);
    }

    override protected function draw():void
    {
        // (0,0)を中心とする長方形を描く
        var matrix:Matrix=new Matrix();
        matrix.createGradientBox(w, h, 5);
        graphics.beginGradientFill("linear", [0x0000FF, 0x00FFFF], [1.0, 1.0], [0, 255], matrix);
        graphics.drawRect(-w / 2, -h / 2, w, h);
        graphics.endFill();
    }

    override public function explosion():void
    {
        BetweenAS3.to(this, {scaleX: 1}, 0.5).play();
    }

    override public function deleteObj():void
    {
    }

    override protected function update():void
    {
        x+=(field.mouseX - x) / 8;
        if (x + width / 2 > BreakBlock.W)
            x=BreakBlock.W - width / 2;
        else if (x - width / 2 < 0)
            x=width / 2;
    }
}

//アイテムクラス
class Item extends Obj
{
    protected var vx:Number;
    protected var vy:Number;
    protected var vz:Number;
    protected var size:Number;
    protected var judgeLine:Number;

    public function Item(field:BreakBlock, x:Number, y:Number, vx:Number, vy:Number, color:uint, r:Number)
    {
        super(field);
        this.x=x;
        this.y=y;
        this.vx=vx;
        this.vy=vy;
        this.vz=vx;
        this.color=color;
        this.size=r;
        this.field=field;
        draw();
        this.judgeLine=0;
        addEventListener(Event.ENTER_FRAME, enterFrame);
    }

    override protected function update():void
    {
        if (field.status == 2)
            vz=-10;

        x+=vx;
        y+=vy;
        z+=vz;

        checkInField();
        if (y > judgeLine)
            checkBarCollision();
    }

    //画面外に出ていないかどうか
    protected function checkInField():void
    {
        if (y > BreakBlock.H)
        {
            deleteObj();
        }
    }

    //バーとの接触判定
    protected function checkBarCollision():void
    {
        if (this.hitTestObject(field.bar))
        {
            deleteObj();
        }
    }
}

//星型のアイテムクラス
class StarItem extends Item
{
    public function StarItem(field:BreakBlock, x:Number, y:Number, vx:Number, vy:Number, color:uint, r:Number)
    {
        super(field, x, y, vx, vy, color, r);
    }

    override protected function draw():void
    {
        this.filters=[new GlowFilter(color, 1, 8, 8, 2)];
        var r2:Number=size / 2;
        var angle:Number=-90;
        var addtion:Number=360 / 10;
        graphics.beginFill(0xffffff);
        graphics.moveTo(0, -size);
        for (var i:int=0; i < 10; i++)
        {
            angle+=addtion;
            var to_x:Number;
            var to_y:Number;
            var radian:Number=angle * Math.PI / 180;
            if (i % 2)
            {
                to_x=size * Math.cos(radian);
                to_y=size * Math.sin(radian);
            }
            else
            {
                to_x=r2 * Math.cos(radian);
                to_y=r2 * Math.sin(radian);
            }
            graphics.lineTo(to_x, to_y);
        }
        graphics.endFill();
    }

    override protected function checkBarCollision():void
    {
        if (this.hitTestObject(field.bar))
        {
            deleteObj();
            createBall();
        }
    }

    //ボールの生成
    private function createBall():void
    {
        var newBall:StarBall=new StarBall(field, x, y - field.bar.height, Math.random() * 15 - 7.5, -Math.random() * 5 - 2, 0.0, color, size, Math.random() * 5 + 5);
        field.ball_canvas.addChild(newBall);
    }
}

//バーの大きさを変えるアイテム
class HeartItem extends Item
{
    public function HeartItem(field:BreakBlock, x:Number, y:Number, vx:Number, vy:Number, color:uint, r:Number)
    {
        super(field, x, y, vx, vy, color, r);
    }

    //バーとの衝突判定
    override protected function checkBarCollision():void
    {
        if (this.hitTestObject(field.bar))
        {
            var tween:ITween;
            var toScale:Number;
            vy=0;
            //バーの縮小拡大。色によって効果が違う
            if (color)
            {
                if (field.bar.scaleX < 1)
                    toScale=1;
                else
                {
                    toScale=field.bar.scaleX + 1;
                    if (toScale > 3)
                        toScale=3;
                }
                tween=BetweenAS3.to(field.bar, {scaleX: toScale}, 0.5);
            }
            else
            {
                toScale=field.bar.scaleX / 2;
                if (toScale < 0.25)
                    toScale=0.25;
                tween=BetweenAS3.to(field.bar, {scaleX: toScale}, 0.5);
            }
            tween.play();
            removeEventListener(Event.ENTER_FRAME, enterFrame);
            tween=BetweenAS3.to(this, {alpha: 0, scaleX: 3, scaleY: 3}, 0.5);
            tween.onComplete=deleteObj;
            tween.play();
        }
    }

    override protected function draw():void
    {
        var a:Number=1;
        var b:Number=2;
        var c:Number=0.7;
        var d:Number=1;
        var df:Number=0.01;
        var fmin:Number=-Math.PI / 2;
        var fmax:Number=3 * Math.PI / 2;
        var xx:Vector.<Number>=new Vector.<Number>;
        var yy:Vector.<Number>=new Vector.<Number>;
        var value:Number;
        var max_v:Number=0;
        var min_v:Number=1000000;

        for (var f:Number=fmin; f <= fmax; f+=df)
        {
            var t:Number=b * Math.sqrt(f + Math.PI / 2) - b * Math.sqrt(3 * Math.PI / 2 - f) + (1 - b * Math.sqrt(2 / Math.PI)) * f + b * Math.sqrt(Math.PI / 2);
            var r:Number=a * (1 - Math.sin(t));
            xx.push(size * r * (1 + c * Math.sin(f)) * Math.cos(f));
            value=size * d * r * (1 + c * Math.sin(f)) * Math.sin(f);
            yy.push(value);
            if (value > max_v)
                max_v=value;
            if (value < min_v)
                min_v=value;
        }

        var center:Number=(max_v + min_v) / 2;
        var i:int=xx.length;
        graphics.beginFill(color);
        graphics.moveTo(xx[0], yy[0] - center);
        while (i--)
        {
            graphics.lineTo(xx[i], yy[i] - center);
        }
        graphics.endFill();

        this.rotation+=180;
        this.filters=[new GlowFilter(0xff69b4, 1, 16, 16, 2)];
    }
}

//キラキラの粒子クラス
class Particle
{
    public var x:Number;
    public var y:Number;
    public var vx:Number;
    public var vy:Number;
    public var color:uint;
    public var field:BreakBlock;

    public function Particle(x:Number, y:Number, vx:Number, vy:Number, color:uint)
    {
        this.x=x;
        this.y=y;
        this.vx=vx;
        this.vy=vy;
        this.color=color | 0xFF000000;
    }

    public function update():void
    {
        x+=vx;
        y+=vy;
        vy+=0.2;
    }
}