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

テトリス3D

↑ :回転 Rotation
→ :右移動 Go right
← :左移動 Go left
↓ :早く落ちる Down speed up
Z :視点変更 
   マウスポインタの位置で変わります
        Change view point to move 
         mouse position
Z+SHIFT:視点変更 Change view point
Z+CTRL :視点変更
Get Adobe Flash player
by Kihara 24 Feb 2011
/**
 * Copyright Kihara ( http://wonderfl.net/user/Kihara )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/48bt
 */

package
{
    import caurina.transitions.Tweener;
    
    import fl.transitions.Tween;
    
    import flash.display.BlendMode;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.filters.BlurFilter;
    import flash.filters.GlowFilter;
    import flash.ui.Keyboard;
    import flash.ui.Mouse;
    
    import org.papervision3d.core.effects.BitmapColorEffect;
    import org.papervision3d.core.effects.BitmapLayerEffect;
    import org.papervision3d.events.InteractiveScene3DEvent;
    import org.papervision3d.lights.PointLight3D;
    import org.papervision3d.materials.ColorMaterial;
    import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
    import org.papervision3d.materials.special.Letter3DMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.primitives.Cube;
    import org.papervision3d.objects.primitives.Plane;
    import org.papervision3d.typography.Text3D;
    import org.papervision3d.typography.fonts.HelveticaBold;
    import org.papervision3d.view.BasicView;
    import org.papervision3d.view.layer.BitmapEffectLayer;
    
    [SWF(backgroundColor=0,frameRate="25", width=465, height=465)]//FPSは30
    public class tetris extends Sprite
    {
        private var cubeFlag:Boolean=false,downFlag:Boolean=false,rotateFlag:Boolean=false;
        private var gameOverFlag:Boolean=false,replayFlag:Boolean=false;
        private var bv1:BasicView,bv2:BasicView,menu_bv:BasicView;
        private var map:Vector.<Vector.<Map>>=new Vector.<Vector.<Map>>();  //map、ボードの中に関する配列
        private var kabe_cube:Vector.<Cube>=new Vector.<Cube>;//周りの壁
        private var light:PointLight3D;//光源
        private var block:Vector.<Block>=new Vector.<Block>;
        private var move_cube:Vector.<MoveCube>=new Vector.<MoveCube>;//積み上げられているブロックを入れる配列
        private var now_block:Vector.<BlockCube>=new Vector.<BlockCube>;//実際にキーボードで操作できるブロックを入れる配列
        private var count:uint=0;//ゲーム開始したらカウントする
        private var block_id:uint=0;
        private var keys:Array=[];//キーボード入力
        private var time:int=30;//ブロックが下に着いてから動ける時間
        private var late:int=15;//どのくらいのスピードで落ちるか
        private var bakuhatu:Vector.<Bakuhatu>=new Vector.<Bakuhatu>;//爆発のエフェクト
        private var y_num:uint=0;
        private var gameOver_count:uint=0;
        private var bfx:BitmapEffectLayer;//エフェクトレイヤー
        private var word:Text3D,word2:Text3D,word3:Text3D;//画面に出てくる文字
        private var menu_plane:Plane;//CLICK MEの下にあるplane
        private var score:uint=0;//点数
        private var line:uint=0;//消えたラインの数
        private var scoreText:Text3D;//点数を画面に表示するためのText3D
        private var lineText:Text3D;//消えたラインを表示するためのText3D
        private var targetZ:Number=300;//カメラのZ軸の目標値
        private var chain:uint=1,chain_num:uint=1;//点数の増加に関するもの
        private var next:Vector.<uint>=new Vector.<uint>;
        
        private const number_text:String=new String("0123456789");
        private const w:Number=465,h:Number=465;//画面の高さと横
        private const map_width:uint=12;//ボードの端から端までのブロックの数
        private const map_height:uint=22;
        private const cube_N:Number=20;//ブロックの一辺の長さ 立方体なので全部同じ
        private const sukima:Number=cube_N + (cube_N / 5);     //cubeとcubeの間隔
        private const board_x:Number=-40+sukima * (map_width / 2);//ボードのx軸
        private const board_y:Number=-100+sukima * (map_height / 2);//ボードのy軸
        
        //光の当たる部分と当たらない部分の色
        private const color1:Array = [0x000000,0x55FFFF,0x5555FF,0xFF9922,0xFF55FF,0x55FF55,0xFFFF55,0xFF5555];
        private const color2:Array = [0x000000,0x116666,0x111166,0x663311,0x661166,0x116611,0x666611,0x661111];
        
        //ブロックの相対座標
        private var array_block:Array=[
            [[0.0],[0, 0], [0, 0], [0, 0]],       //null
            [[0.0],[0, 1], [0, -1], [0, -2]],     //bou 
            [[0,0],[-1, 1], [-1, 0], [1, 0]],     //L 
            [[0,0],[1, 1], [-1, 0], [1, 0]],      //L 
            [[0,0],[-1, 0], [0, 1], [1, 1]],      //key 
            [[0,0],[1, 0], [0, 1], [-1, 1]],      //key 
            [[0,0],[0, 1], [1, 0], [-1, 0]],      //T 
            [[0,0],[1, 0], [0, 1], [1, 1]]];      //square 
        
        public function tetris()
        {
            //BasicViewの設定
            bv1=new BasicView(w,h,true,false);
            bv2=new BasicView(w,h,true,false);
            
            
            //エフェクトレイヤーの作成
            bfx=new BitmapEffectLayer(bv1.viewport,465,465);
            bfx.addEffect(new BitmapColorEffect(1,1,1,0.8));
            bv1.viewport.containerSprite.addLayer(bfx);
            
            //BasicViewのカメラ設定
            bv1.camera.z = 300;
            bv1.camera.y = -150;
            bv2.camera.z = 300;
            bv2.camera.y = -150;
            
            //bv1の透明度を0.5にする
            bv1.alpha=0.6;
            
            //初期設定
            init_board();
            init_cube();
            draw_scores();
            draw_text();
            
            addChild(bv1);//画面にBasicViewを追加する
            addChild(bv2);
            menu_init();//メニュー画面の表示
            
            bv1.startRendering();//レンダリング開始
            bv2.startRendering();
            
            //キーボード操作ができるようにする
            stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDown);
            stage.addEventListener(KeyboardEvent.KEY_UP,keyUp);
        }
        public function draw_text():void{//右下にある、SCOREとLINEの設定
            var fonts:HelveticaBold=new HelveticaBold();
            var mat:Letter3DMaterial=new Letter3DMaterial(0xFFFFFF);
            
            mat.doubleSided=true;
            var ws:Text3D=new Text3D("SCORE",fonts,mat);
            var wl:Text3D=new Text3D("LINE",fonts,mat);
            ws.x=-160;
            wl.x=-160;
            ws.y=-80;
            wl.y=-120;
            ws.scale=0.2;
            wl.scale=0.2;
            ws.rotationY=180;
            wl.rotationY=180;
            bv1.scene.addChild(ws);
            bv1.scene.addChild(wl);
        }
        //一番最初の画面の設定
        public function menu_init():void{
            menu_bv=new BasicView(w,h,true,true);
            menu_bv.viewport.interactive=true;
            
            var fonts:HelveticaBold=new HelveticaBold();
            var mat:Letter3DMaterial=new Letter3DMaterial(0x0000FF, 0.5);
            var pm:ColorMaterial=new ColorMaterial(0x3388FF, 0.5);
            
            pm.interactive=true;
            if(!replayFlag)//一回もプレイしたなかったらCLICK ME!と表示する
                word=new Text3D("CLICK ME!", fonts, mat);
            else if(replayFlag){//一回でもゲームオーバーになっていたら点数を表示して、REPLAYと表示
                var mat2:Letter3DMaterial=new Letter3DMaterial(0xFFFFFF, 0.6);
                word2=new Text3D("YOUR SCORE IS",fonts,mat2);
                word3=new Text3D(score.toString(),fonts,mat2);
                word=new Text3D("REPLAY",fonts,mat);
                word2.y=300;
                word3.y=200;
                score=0;
                line=0;
                bv1.scene.removeChild(scoreText);
                bv1.scene.removeChild(lineText);
                draw_scores();
                menu_bv.scene.addChild(word2);
                menu_bv.scene.addChild(word3);
            }
            word.scaleX=0.7;
            menu_plane=new Plane(pm,400,200,1,1);
            //planeにマウスイベントを追加する
            menu_plane.addEventListener(InteractiveScene3DEvent.OBJECT_OUT,MouseOut);
            menu_plane.addEventListener(InteractiveScene3DEvent.OBJECT_OVER,MouseOver);
            menu_plane.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK,Click);
            
            menu_bv.scene.addChild(word);
            menu_bv.scene.addChild(menu_plane);
            
            menu_bv.startRendering();//menu_bvのレンダリング開始
            addChild(menu_bv);//画面にmenu_bvを追加
        }
        
        
        //オブジェクトがクリックされたら
        public function Click(e:InteractiveScene3DEvent):void{
            //メニュー画面を全部消して、ゲームを開始する
            menu_bv.scene.removeChild(word);
            menu_bv.scene.removeChild(menu_plane);
            if(replayFlag){
                menu_bv.scene.removeChild(word2);
                menu_bv.scene.removeChild(word3);
            }
            menu_plane.removeEventListener(InteractiveScene3DEvent.OBJECT_CLICK,Click);
            menu_plane.removeEventListener(InteractiveScene3DEvent.OBJECT_OUT,MouseOut);
            menu_plane.removeEventListener(InteractiveScene3DEvent.OBJECT_OVER,MouseOver);
            menu_bv.stopRendering();
            removeChild(menu_bv);
            addEventListener(Event.ENTER_FRAME,onEnterFrame);//ゲーム開始
        }
        //マウスの位置がオブジェクトから離れたら
        public function MouseOut(e:InteractiveScene3DEvent):void{
            Tweener.addTween(word, {scaleX: 0.7, time: 1.0, transition: "easeOutElastic"});
            Tweener.addTween(menu_plane, {scaleX: 1, time: 1.0, transition: "easeOutElastic"});
        }
        //マウスの位置がオブジェクトの上にあったら
        public function MouseOver(e:InteractiveScene3DEvent):void{
            Tweener.addTween(word, {scaleX: 1.5, time: 1.0, transition: "easeOutElastic"});
            Tweener.addTween(menu_plane, {scaleX: 2, time: 1.0, transition: "easeOutElastic"});
        }
        
        //ブロックの定義
        public function init_cube():void{
            cubeFlag=true;
            var block_n:uint=array_block.length;
            for(var i:uint=0;i<block_n;i++){
                var b:Block=new Block(array_block[i]);
                block.push(b);
            }
        }
        //もしキーボードから離れたら
        public function keyUp(e:KeyboardEvent):void{
            keys[e.keyCode]=false;
        }
        
        //もしキーボードで何か押されたら
        public function keyDown(e:KeyboardEvent):void{
            keys[e.keyCode]=true;
        }
        
        //ボードの設定
        public function init_board():void
        {
            //光源の設定
            light=new PointLight3D(true, false);
            light.z = 50;
            light.y = 0;
            light.x = 0;
            
            //外枠のキューブの質感に関する設定
            var kabe_material:FlatShadeMaterial=new FlatShadeMaterial(light, 0xBBBBBB, 0x111111, 60);
            var kabe_material_list:MaterialsList=new MaterialsList({all: kabe_material});
            
            
            for (var x:uint=0; x < map_width; x++)
            {
                map[x] = new Vector.<Map>();
                for (var y:uint=0; y < map_height; y++)
                {    
                    //外枠
                    if (x == 0 || y == 0 || x == map_width - 1 || y == map_height - 1)
                    {
                        var cube1:Cube=new Cube(kabe_material_list, cube_N, cube_N, cube_N, 1, 1, 1);
                        cube1.x=(x * sukima) - board_x; 
                        cube1.y=(y * sukima) - board_y;
                        cube1.z=0;
                        bv1.scene.addChild(cube1);
                        bfx.addDisplayObject3D(cube1);
                        kabe_cube.push(cube1);
                        map[x][y]=new Map(true,(x * sukima) - board_x,(y * sukima) - board_y);//外枠の座標のときは全てtrue
                    }
                        //内側
                    else map[x][y]=new Map(false,(x * sukima) - board_x,(y * sukima) - board_y);//内側は全部false        
                }
            }
        }
        
        //ボードの上の方にブロックを作って置く
        public function put_cube(type:uint):void{
            var cube_material:FlatShadeMaterial=new FlatShadeMaterial(light,color1[type],color2[type],60);
            var cube_material_list:MaterialsList= new MaterialsList({all:cube_material});
            for(var i:uint=0;i<4;i++){
                var c:Cube = new Cube(cube_material_list,cube_N,cube_N,cube_N,1,1,1);
                //初期位置は上の真ん中辺り
                c.x=block[type].position[i].p_x*sukima-sukima+40;
                c.y=block[type].position[i].p_y*sukima+100-sukima*3+sukima*map_height/2;
                now_block.push(new BlockCube(true,c,block[type].position[i].p_x,block[type].position[i].p_y,type));
                bv1.scene.addChild(now_block[i].cube);
                bfx.addDisplayObject3D(now_block[i].cube);
            }
            for(i=0;i<4;i++){
                get_id(now_block[i].cube.x,now_block[i].cube.y,i);//追加したブロックがmap上のどこにあるか取得
                if(map[now_block[i].px_id][now_block[i].py_id].flag){//ブロックを置いて、すでにそこにブロックがあったらゲームオーバー
                    cubeFlag=false;
                    gameOver();
                }
            }
        }
        
        public function gameOver():void{//ゲームオーバーになったらonEnterFrameを画面からけして、Frameを変える
            addEventListener(Event.ENTER_FRAME,gameOverFrame);
            removeEventListener(Event.ENTER_FRAME,onEnterFrame);
        }
        
        //ゲームオーバーになったときの動作
        public function gameOverFrame(e:Event):void{
            gameOver_count++;
            if(gameOver_count%2==0){//下から順に消していく
                y_num++;
                for(var i:uint=0;i<move_cube.length;i++){
                    if(move_cube[i].py_id==y_num){
                        bv1.scene.removeChild(move_cube[i].cube);
                        //消えるときのエフェクト
                        for(var bnum:uint=0;bnum<3;bnum++){
                            var b:Bakuhatu=new Bakuhatu(//弾みたいなものの位置はブロックの位置
                                move_cube[i].cube.x,
                                move_cube[i].cube.y,
                                move_cube[i].cube.z);
                            b.shape.useOwnContainer=true;//フィルターを画面に反映させる
                            b.shape.filters = [new GlowFilter(color1[move_cube[i].type],1,8,8,6),new BlurFilter(2,2)];//フィルターの設定
                            b.shape.blendMode=BlendMode.ADD;//加算描写する
                            bakuhatu.push(b);//配列に追加
                            bv2.scene.addChild(bakuhatu[bakuhatu.length-1].shape);//画面に追加
                        }
                        move_cube.splice(i--,1);//消えているので配列からも消去
                    }
                }
            }
            moveBakuhatu();//エフェクトを動かす
            if(y_num>map_height && bakuhatu.length==0)//全部消えたらリセットする
                reset();
        }
        
        public function reset():void{//いままでのものをリセットする
            for (var x:uint=1; x < map_width-1; x++)
                for (var y:uint=1; y < map_height-1; y++)
                    map[x][y].flag=false;
            
            y_num=0;
            gameOver_count=0;
            count=0;
            cubeFlag=true;
            replayFlag=true;
            
            for(x=0;x<now_block.length;x++){
                bv1.scene.removeChild(now_block[x].cube);
                now_block.splice(x--,1);
            }
            removeEventListener(Event.ENTER_FRAME,gameOverFrame);
            menu_init();
        }
        
        //今ブロックがそれぞれmap上の座標でどこにあるか調べる
        //debug用
        public function get_id(nx:Number,ny:Number,i:uint):void{
            for(var x:uint=0;x<map_width;x++){
                for(var y:uint=0;y<map_height;y++){
                    if(ny+cube_N/2 < map[x][y]._y+sukima/2 && ny-cube_N/2 > map[x][y]._y-sukima/2){
                        if(nx+cube_N/2 < map[x][y]._x+sukima/2 && nx-cube_N/2 > map[x][y]._x-sukima/2){
                            now_block[i].px_id=x;
                            now_block[i].py_id=y;
                        }
                    }
                }
            }
        }
        
        
        public function check():void{
            //var i:uint=0;
            //for(i=0;i<4;i++)
                //get_id(now_block[i].cube.x,now_block[i].cube.y,i);//今ブロックがどこにあるか調べる
            
            right_check();   //右に進めるか
            left_check();   //左に進めるか
            
            rotation_check(); //回転できるか
            down_check();   //下に壁やブロックはないか
            delete_line();   //一列揃ってたら消す
        }
        
        public function right_check():void{
            //キーボードで右が押されていたら
            if(keys[Keyboard.RIGHT]){
                var right_block_flag:Boolean=true;
                
                
                //右隣に壁やブロックがあるとfalse
                for(var j:uint=0;j<4;j++){
                    if(map[now_block[j].px_id-1][now_block[j].py_id].flag){
                        right_block_flag=false;
                    }
                }

                //右に何もなかったら右隣に動く
                if(right_block_flag){
                    for(var k:uint=0;k<4;k++){
                        if(count%2==0){
                            now_block[k].cube.x=map[now_block[k].px_id-1][now_block[k].py_id]._x;
                            now_block[k].px_id--;
                        }
                    }
                }
            }
        }
        public function left_check():void{
            if(keys[Keyboard.LEFT]){
                var left_block_flag:Boolean=true;
                
                //左隣に壁やブロックがあるとfalse
                for(var j:uint=0;j<4;j++){
                    if(map[now_block[j].px_id+1][now_block[j].py_id].flag){
                        left_block_flag=false;
                    }
                }
                
                //左に何もなかったら左隣に動く
                if(left_block_flag){
                    for(var k:uint=0;k<4;k++){
                        if(count%2==0){
                            now_block[k].cube.x=map[now_block[k].px_id+1][now_block[k].py_id]._x;
                            now_block[k].px_id++;
                        }
                    }
                }
            }
        }
        
        public function rotation_check():void{
            if(rotateFlag && keys[Keyboard.UP]){
                var ok_flag:Boolean=true;//一回押されたら一回転させるためのフラグ
                var dx:Vector.<int>=new Vector.<int>,dy:Vector.<int>=new Vector.<int>;
                var ux:Vector.<int>=new Vector.<int>,uy:Vector.<int>=new Vector.<int>;
                for(var i:uint=0;i<4;i++){
                    var nx:int,ny:int;
                    
                    nx=now_block[i].px;//ブロックの相対座標を一時的に保存
                    ny=now_block[i].py;
                    
                    dx.push(-ny);  //一次変換した座標をいれる
                    dy.push(nx);
                    ux.push(-ny-nx);//変換した座標までどうやっていくか
                    uy.push(nx-ny);
                    if(now_block[i].px_id+ux[i] >= 1 && now_block[i].px_id+ux[i] <= 10 && now_block[i].py_id+uy[i] >= 1){//移動先にブロックや壁があったら回転できない
                        if(map[now_block[i].px_id+ux[i]][now_block[i].py_id+uy[i]].flag)
                            ok_flag=false;
                    }
                    //移動先が壁、もしくは壁の外だったら回転できない
                    if(now_block[i].px_id+ux[i] < 1 || now_block[i].px_id+ux[i] > 10 || now_block[i].py_id+uy[i] < 1)
                        ok_flag=false;
                }
                
                if(ok_flag){//もしも回転してよかったら回転する
                    for(i=0;i<4;i++){
                        now_block[i].px=dx[i];//それぞれの相対座標を更新する
                        now_block[i].py=dy[i];
                        now_block[i].px_id+=ux[i];
                        now_block[i].py_id+=uy[i];
                        now_block[i].cube.x=ux[i]*sukima+now_block[i].cube.x;//実際に移動
                        now_block[i].cube.y=uy[i]*sukima+now_block[i].cube.y;
                        
                    }
                }
                rotateFlag=false;
            }
            //一回キーが押されたら、キーが離れるまでは回転させない
            if(!keys[Keyboard.UP]){
                rotateFlag=true;
            }
        }
        
        public function down_check():void{
            var ok_flag:Boolean=true;
            if(keys[Keyboard.DOWN])//下キーを押していたら早く落ちる
                late=1;
            else late=15;
            
            for(var j:uint=0;j<4;j++){
                if(map[now_block[j].px_id][now_block[j].py_id-1].flag) //もし一個下のマスが壁、もしくはブロックがあったら下に動けない
                {
                    ok_flag=false;
                    downFlag=true;
                    break;
                }
                else downFlag=false;
            }
            if(ok_flag){//下に移動しても良かったら一マス分、下に移動する
                for(var i:uint=0;i<4;i++){
                    if(count%late==0){
                        now_block[i].cube.y-=sukima;
                        now_block[i].py_id--;
                    }
                }
            }
        }
        //動いてるブロックがそれ以上下に行けなくなったら止める
        public function end_move():void{
            for(var k:uint=0;k<4;k++){
                now_block[k].cube.y=map[now_block[k].px_id][now_block[k].py_id]._y;//ブロック固定
                
                //そのマスのflagをtrueにする
                map[now_block[k].px_id][now_block[k].py_id].flag=true;      
                //固定されたブロックを違う配列に追加する
                move_cube.push(new MoveCube(true,now_block[k].cube,now_block[k].px_id,now_block[k].py_id,now_block[k].type));
                bv1.scene.removeChild(now_block[k].cube);//動いていたブロックを消す
                bfx.removeDisplayObject3D(now_block[k].cube);//エフェクトレイヤーからも消す
                bv1.scene.addChild(move_cube[move_cube.length-1].cube);//違う配列に追加されたものを画面にも追加
                bfx.addDisplayObject3D(move_cube[move_cube.length-1].cube);//エフェクトレイヤーにも追加
            }
            downFlag=false;
            cubeFlag=true;
            
            for(k=0;k<4;k++)//動いていた配列をすべて消去
                now_block.pop();
        }
        
        public function delete_line():void{
            var bakuFlag:Boolean=false;//全てのラインをチェックした後、どこか消えるのかどうか
            var line_num:int=0;
            
            for(var y:uint=1;y<map_height-1;y++){
                var line_flag:Boolean=true;
                for(var x:uint=1;x<map_width-1;x++){
                    if(!map[x][y].flag){//一つでも隙間があればfalse
                        line_flag=false;
                        break;
                    }
                }
                
                if(line_flag){//もし、一つのラインが全て埋まっていたら
                    bakuFlag=true;
                    var del_count:Vector.<int>=new Vector.<int>;
                    for(var i:uint=0;i<move_cube.length;i++){
                        if(move_cube[i].py_id==y){//何番目の要素が消えるかを保存
                            del_count.push(i);
                        }
                    }
                    
                    for(var j:uint=0;j<del_count.length;j++){//実際に消す
                        bv1.scene.removeChild(move_cube[del_count[j]].cube);
                        bfx.removeDisplayObject3D(move_cube[del_count[j]].cube);
                        //消えるときのエフェクト
                        for(var bnum:uint=0;bnum<3;bnum++){
                            var b:Bakuhatu=new Bakuhatu(
                                move_cube[del_count[j]].cube.x,
                                move_cube[del_count[j]].cube.y+line_num*sukima,
                                move_cube[del_count[j]].cube.z);
                            b.shape.useOwnContainer=true;
                            b.shape.filters = [new GlowFilter(color1[move_cube[del_count[j]].type],1,8,8,6),new BlurFilter(1,1)];
                            b.shape.blendMode=BlendMode.ADD;
                            bakuhatu.push(b);
                        }
                    }
                    //現在のmapの情報を記憶する
                    var temp:Vector.<Vector.<Boolean>>=new Vector.<Vector.<Boolean>>();
                    for(var s:uint=0;s<map_width;s++){
                        temp[s]= new Vector.<Boolean>();
                        for(var t:uint=0;t<map_height;t++){
                            if(map[s][t].flag)temp[s][t]=true;
                            else temp[s][t]=false;
                        }
                    }
                    
                    //一つ上の情報を持ってくる
                    for(var x2:uint=1;x2<map_width-1;x2++)
                        for(y2=y;y2<map_height-2;y2++)
                            map[x2][y2].flag=temp[x2][y2+1];
                    
                    //一番上のラインをfalseにする
                    for(j=1;j<map_width-1;j++)
                        map[j][map_height-2].flag=false;
                    
                    //実際に一つ分下にずらす
                    for(var y2:uint=y+1;y2<map_height-1;y2++){
                        for(i=0;i<move_cube.length;i++){
                            if(move_cube[i].py_id==y2){
                                move_cube[i].cube.y-=sukima;
                                move_cube[i].py_id=y2-1;
                            }
                        }
                    }
                    
                    var n:uint=del_count.length;
                    //画面から消去したものを配列からも消す
                    for(var k:uint=0;k<n;k++)
                        move_cube.splice(del_count[n-1-k],1);
                    
                    y--;
                    line_num++;    //一回に消えたラインの数を保存
                }
            }
            if(bakuFlag){//エフェクトを画面内に追加
                for(bnum=0;bnum<bakuhatu.length;bnum++)
                    bv2.scene.addChild(bakuhatu[bnum].shape);
            }
            
            //ラインが消えたら点数を増やす
            //1段、2段、3段、4段、の順で消すと点数が増える また、毎回同じ段数消しても通常よりも点数が増える
            if(line_num){
                if(line_num==chain+1)chain_num*=2;
                else if(line_num>=2 && line_num==chain)chain_num++;
                else chain_num=1;
                chain=line_num;
                score+=line_num*line_num*chain_num*10;
                line+=line_num;
                bv1.scene.removeChild(scoreText);
                bv1.scene.removeChild(lineText);
                draw_scores();//点数やラインの消去数を表示する
            }
        }
        
        //消えるときのエフェクト。実際に弾みたいなのを動かす
        public function moveBakuhatu():void{
            for(var i:uint=0;i<bakuhatu.length;i++){
                bakuhatu[i].move();
                if(bakuhatu[i].shape.alpha<0){
                    bv2.scene.removeChild(bakuhatu[i].shape);
                    bakuhatu.splice(i--,1);
                }
            }
        }
        //点数やラインの消去数を表示する
        public function draw_scores():void{
            var fonts:HelveticaBold=new HelveticaBold();
            var mat:Letter3DMaterial=new Letter3DMaterial(0xFFFFFF);
            mat.doubleSided=true;
            var s:String=score.toString();
            var l:String=line.toString();
            scoreText=new Text3D(s,fonts,mat);
            lineText=new Text3D(l,fonts,mat);
            scoreText.scale=0.2;
            lineText.scale=0.2;
            scoreText.rotationY=180;
            lineText.rotationY=180;
            scoreText.x =-160;
            scoreText.y=-100;
            lineText.x=-160;
            lineText.y=-140;
            bv1.scene.addChild(scoreText);
            bv1.scene.addChild(lineText);
        }
        //カメラの動き
        public function move_camera():void{
            var rateX:Number=mouseX/w;
            var rateY:Number=mouseY/h;
            var targetX:Number=-1500*(rateX-0.5);
            var targetY:Number=-1500*(rateY-0.5);
            if(keys[Keyboard.SHIFT])//SHIFTキーが押されていたら離れる
                targetZ+=20;
            if(keys[Keyboard.CONTROL])//CTRLキーが押されていたら近づく
                targetZ-=20;
            //イージングを使ってカメラを滑らかに動かす
            bv1.camera.x+=(targetX-bv1.camera.x)*0.2;
            bv1.camera.y+=(targetY-bv1.camera.y)*0.2;
            bv1.camera.z+=(targetZ-bv1.camera.z)*0.2;
            bv2.camera.x+=(targetX-bv2.camera.x)*0.2;
            bv2.camera.y+=(targetY-bv2.camera.y)*0.2;
            bv2.camera.z+=(targetZ-bv2.camera.z)*0.2;
        }
        
        public function onEnterFrame(e:Event):void{
            count++;
            //ブロック生成
            if(cubeFlag){
                var type:uint=Math.random()*7+1;
                put_cube(type);
                cubeFlag=false;
            }
            //ブロックのチェック
            check();
            //下にブロックや壁があってもちょっとの間動く
            if(downFlag){
                if(time<0)
                    end_move();
                time--;
            }
            else time=15;

            
            //エフェクトを動かす
            moveBakuhatu();    
            
            //もしZキーが押されていたらカメラを動かす
            if(keys[90]){
                move_camera();
            }
        }
    }
}

import flash.display.Sprite;

import org.papervision3d.core.render.sort.NullSorter;
import org.papervision3d.materials.special.VectorShapeMaterial;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.objects.special.Graphics3D;
import org.papervision3d.objects.special.VectorShape3D;

class Block extends Sprite{
    public var position:Vector.<Position>=new Vector.<Position>;
    public function Block(b:Array):void{
        for(var i:uint=0;i<4;i++)
            position.push(new Position(b[i]));
    }
}

class Position extends Sprite{
    public var p_x:int;
    public var p_y:int;
    public function Position(b:Array):void{
        p_x=b[0];
        p_y=b[1];
    }
}
class BlockCube extends Sprite{
    public var flag:Boolean;
    public var cube:Cube;
    public var px:Number;
    public var py:Number;
    public var px_id:int=-1;
    public var py_id:int=-1;
    public var type:int;
    public function BlockCube(f:Boolean,c:Cube,px:int,py:int,type:int):void{
        flag=f;
        cube=c;
        this.px=px;
        this.py=py;
        this.type=type;
    }
}

class MoveCube extends Sprite{
    public var flag:Boolean;
    public var cube:Cube;
    public var px_id:int;
    public var py_id:int;
    public var type:int;
    public function MoveCube(f:Boolean,c:Cube,px:int,py:int,type:int):void{
        flag=f;
        cube=c;
        px_id=px;
        py_id=py;
        this.type=type;
    }
}

class Map extends Sprite{
    public var flag:Boolean;
    public var _x:int;
    public var _y:int;
    public function Map(f:Boolean,x:int,y:int):void{
        flag=f;
        _x=x;
        _y=y;
    }
}

class Bakuhatu extends Sprite{
    public var vx:Number=Math.random()*10-5;
    public var vy:Number=Math.random()*10-5;
    public var vz:Number=Math.random()*10-5;
    private var r:Number=3*Math.random()+1;
    private var mat:VectorShapeMaterial=new VectorShapeMaterial();
    public var shape:VectorShape3D=new VectorShape3D(mat);
    public function Bakuhatu(x:Number,y:Number,z:Number):void{
        var g:Graphics3D=shape.graphics;
        g.beginFill(0xFFFFFF);
        g.drawCircle(x,y,r,8);
    }
    
    public function move():void{
        this.shape.x+=vx;
        this.shape.y+=vy;
        this.shape.z+=vz;
        this.shape.alpha-=0.1;
    }
    
}