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: ZSTetris

Z, Sが交互に落ちてきます
145 blocks まではいけた

参考サイト - http://www.nhk.or.tv/kow/program/program_121.php
Get Adobe Flash player
by mapache 02 Mar 2011
// forked from yambian's ZSTetris
// forked from motioneditor's forked from: forked from: forked from: 普通のテトリス - Tetris
// forked from motioneditor's forked from: forked from: 普通のテトリス - Tetris
// forked from kanariia's forked from: 普通のテトリス - Tetris
// forked from rsakane's 普通のテトリス - Tetris

// Z, Sが交互に落ちてきます
// 145 blocks まではいけた

package
{
    /*
     * 参考サイト - http://www.nhk.or.tv/kow/program/program_121.php
     */
    
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.geom.Matrix;
    import flash.utils.ByteArray;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.text.TextFieldAutoSize;
    import flash.ui.Keyboard;
    import frocessing.color.ColorHSV;
       import mx.controls.Alert;
    import flash.media.*;
    import flash.net.*;
    
    [SWF(width="465", height="465", frameRate="30", backgroundColor="0x393939")]
    public class Main extends Sprite
    {
        private var block:Array;
        private var field:Array;
        private var px:int = 4;
        private var py:int = 0;
        private var frameCount:int = 0;
        private var blockType:int;
        private var nextBlock:int;
        private var nextDrawBlock:Array;
        private var lines:int = 0;
        private var blocks:int = 0;
        private var linesText:TextField;
        private var blocksText:TextField;
        private var gameoverText:TextField;
        private var h:int = 11;
        private var s:Number = 0.5;
        private var v:Number = 0.3;
        private var stop:Boolean = false;
        private var gameover:Boolean = false;
        private var seq:Array = new Array(3,4);
        private var bgm:Boolean;
        private var effects:Array;
        private var snd:Sound;
        private var channel:SoundChannel;
        private var fieldStack:Array;
        private var linesStack:Array;
        private var blocksStack:Array;
                
        public function Main()
        {
            Wonderfl.capture_delay(25);
            nextBlock = seq[0];
            createTextField(null, "Next:", 270, 35, 20);
            createTextField(null, "Move", 270, 200, 20);
            createTextField(null, "[A, S, D], [←, ↓, →]", 270, 220, 13);
            createTextField(null, "Rotate", 270, 250, 20);
            createTextField(null, "W, ↑, Enter, Space", 270, 270, 13);
            createTextField(null, "黒いラインを越えたらGame Over", 270, 350, 13);
            createTextField(null, "RでRestart,Pでモード切り替え", 270, 370, 13);
            createTextField(null, "一回、画面をクリックしないと", 270, 400, 13);
            createTextField(null, "キーが反応しないかもしれません", 270, 420, 13);
            
            linesText = createTextField(null, "lines: 0", 270, 120, 20);
            blocksText = createTextField(null, "blocks: 0", 270, 150, 20);
            gameoverText = createTextField(null, "", 270, 300, 20, 0xFF0000);
            block = new Array(21);
            for (var i:int = 0; i < block.length; i++) block[i] = new Array(12);
            initField();            
            
            fieldStack = new Array();
            linesStack = new Array();
            blocksStack = new Array();

            bgm = true;
            snd = new Sound();
                      //from http://upload.wikimedia.org/wikipedia/en/f/fe/Korobeiniki.mid
                      snd.load(new URLRequest("http://yambi.mydns.jp/resource/Korobeiniki.mp3"));        
                      channel = snd.play(0, int.MAX_VALUE);
                    
                    effects = new Array();
                    effects.push(new Sound());
                    //http://utm-game-web.hp.infoseek.co.jp/free-sound.htm
                    effects[0].load(new URLRequest("http://yambi.mydns.jp/resource/patu_mod.mp3"));
                    
            createBlock();
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
        }
        
        private function initField():void{
            for (var y:int = 0; y < 21; y++){
                for (var x:int = 0; x < 12; x++){
                    if (y == 20 || x == 0 || x == 11) block[y][x] = 9;
                    else block[y][x] = 0;
                }
            }
            field = clone(block);    
        }
        
        private function onEnterFrame(event:Event):void
        {
            if (frameCount++ % 15 == 0 && !stop && !gameover){
                if (checkOverlap(py + 1, px)) lockBlock(), createBlock();
                else moveBlock(py + 1, px);
            }
            draw();
        }
        
        private function draw():void
        {
            graphics.clear();
            var hsv:ColorHSV = new ColorHSV();
            var matrix:Matrix = new Matrix();
            var color:int; // 変数定義、重複避け
            matrix.createGradientBox(20, 20, 45 * Math.PI / 180);
            

            for (var y:int = 0; y < 21; y++)
            {
                for (var x:int = 0; x < 12; x++)
                {
                    matrix.createGradientBox(20, 20, 45 * Math.PI / 180, x * 20, y * 20);
                    if (block[y][x] == 0)
                    {
                        if(y>=h){
                            graphics.beginGradientFill("linear", [0xEEEEEE, 0xCCCCCC], [1.0, 1.0], [0, 255], matrix);
                            graphics.drawRect(x * 20, y * 20, 20, 20);
                            graphics.endFill();
                        }else{
                            graphics.beginGradientFill("linear", [0x999999, 0x777777], [1.0, 1.0], [0, 255], matrix);
                            graphics.drawRect(x * 20, y * 20, 20, 20);
                            graphics.endFill();            
                        }
                    }
                    else if (block[y][x] == 9)
                    {
                        //graphics.beginGradientFill("linear", [0xFF556F, 0xFF979C], [1.0, 1.0], [0, 255], matrix);
                        graphics.beginGradientFill("linear", [0x777777, 0x333333], [1.0, 1.0], [0, 255], matrix);
                        graphics.drawRect(x * 20, y * 20, 20, 20);
                        graphics.endFill();
                    }
                    else
                    {
                        color = Block.color[block[y][x] - 1];
                        hsv.r = color >> 16 & 0xFF, hsv.g = color >> 8 & 0xFF, hsv.b = color & 0xFF;
                        hsv.s = s;
                        hsv.v = v;
                        graphics.beginGradientFill("linear", [hsv.value, Block.color[block[y][x] - 1]], [1.0, 1.0], [0, 255], matrix);
                        //graphics.beginFill(hsv.value);
                        graphics.drawRect(x * 20, y * 20, 20, 20);
                        graphics.endFill();
                    }
                }
            }
            

            graphics.beginFill(0x000000);
            graphics.drawRect(0,20*h,240,2);
            graphics.endFill();
            
            color = Block.color[nextBlock];
            hsv.r = color >> 16 & 0xFF, hsv.g = color >> 8 & 0xFF, hsv.b = color & 0xFF;
            hsv.s = s;
            hsv.v = v;
            
            
            for (y = 0; y < 4; y++)
            {
                for (x = 0; x < 4; x++)
                {
                    if (nextDrawBlock[y][x])
                    {
                        matrix.createGradientBox(20, 20, 45 * Math.PI / 180, 350 + x * 20, 10 + y * 20);
                        graphics.beginGradientFill("linear", [hsv.value, Block.color[nextBlock]], [1.0, 1.0], [0, 255], matrix);
                        graphics.drawRect(350 + x * 20, 10 + y * 20, 20, 20);
                        graphics.endFill();
                    }
                }
            }
            linesText.text = "lines: " + String(lines);
            gameoverText.text = gameover?"Game Over!!":"";
        }
        
        private function createBlock():void
        {
            py = 0;
            px = 4;
            
            blockType = nextBlock;
            nextBlock = seq[++blocks%seq.length];
            nextDrawBlock = clone(Block.block[nextBlock]);
            //nextBlock = Math.random() * Block.block.length;

            blocksText.text = "blocks: " + blocks;
            
            for (var y:int = 0; y < 4; y++)
            {
                for (var x:int = 0; x < 4; x++)
                {
                    if (Block.block[blockType][y][x] && block[py + y][px + x]){
                         gameover = true;
                    }
                    block[py + y][px + x] += Block.block[blockType][y][x];
                }                
            }
        }
        
        private function moveBlock(yy:int, xx:int):void
        {
            if(gameover) return;
            for (var y:int = 0; y < 4; y++)
            {
                for (var x:int = 0; x < 4; x++)
                {
                    block[py + y][px + x] -= Block.block[blockType][y][x];
                }                
            }
            
            py = yy;
            px = xx;
            
            for (y = 0; y < 4; y++)
            {
                for (x = 0; x < 4; x++)
                {
                    block[py + y][px + x] += Block.block[blockType][y][x];
                }                
            }
            
            draw();
        }
        
        private function checkOverlap(yy:int, xx:int):Boolean{
            for (var y:int = 0; y < 4; y++){
                for (var x:int = 0; x < 4; x++)    {
                    if (Block.block[blockType][y][x]){
                        if (field[yy + y][xx + x] != 0) return true;
                    }
                }                
            }
            return false;
        }
        
        private function lockBlock():void
        {
            fieldStack.push(clone(field));
            linesStack.push(lines);
            blocksStack.push(blocks);
            
            for (var y:int = 0; y < 21; y++)
            {
                for (var x:int = 0; x < 12; x++)
                {
                    field[y][x] = block[y][x];
                }
            }
            
            checkLines();
            
            for (y = 0; y < 21; y++)
            {
                for (x = 0; x < 12; x++)
                {
                    block[y][x] = field[y][x];
                    if(y<h&&field[y][x]>0&&field[y][x]<9){
                        gameover = true;
                    }
                }
            }            
        }
        
        private function controlBlock(yy:int, xx:int):void
        {
            if (!checkOverlap(py + yy, px + xx)) moveBlock(py + yy, px + xx)
            else if (yy>0) lockBlock(), createBlock();
        }
        
        private function onKeyDown(event:KeyboardEvent):void
        {
            if (event.keyCode == 37) controlBlock(0, -1); // ←
            if (event.keyCode == 40) controlBlock(1,  0); // ↓
            if (event.keyCode == 39) controlBlock(0,  1); // →
            if (event.keyCode == 38) turnBlock(); // ↑
            if (event.keyCode == 65) controlBlock(0, -1); // A
            if (event.keyCode == 68) controlBlock(0,  1); // D
            if (event.keyCode == 83) controlBlock(1,  0); // S
            if (event.keyCode == 87) turnBlock(); // W
            if (event.keyCode == 82) restart();//R
            if (event.keyCode == 80) pause();//P
            if (event.keyCode == 77) toggleBGM();//M
            if (event.keyCode == 85) undo(); 
            if (event.keyCode == Keyboard.SPACE) turnBlock();
            if (event.keyCode == Keyboard.ENTER) turnBlock();
        }
        
        private function undo():void{
            if(fieldStack.length==0)return;
            field = fieldStack.pop();
            block = clone(field);
            lines = linesStack.pop();
            blocks = blocksStack.pop()-1;
            gameover = false;
            createBlock();
        }
        
        private function toggleBGM():void{
            var cp:int = channel.position;
            if(bgm)channel.stop();
            else channel = snd.play(cp,int.MAX_VALUE);
            bgm = !bgm;
        }
        private function playEffect(num:int):void{
            effects[num].play();
        }
        
        private function restart():void{
            gameover = false;
            lines = 0;
            blocks = 0;    
            nextBlock = seq[0];
            initField();

            fieldStack = new Array();
            linesStack = new Array();
            blocksStack = new Array();
            createBlock();
        }
        
        private function pause():void{
            stop = !stop;
        }
        
        private function turnBlock():void
        {
            if(gameover)return;
            var temp:Array = clone(Block.block[blockType]);
            for (var y:int = 0; y < 4; y++)
            {
                for (var x:int = 0; x < 4; x++)
                {
                    Block.block[blockType][y][x] = temp[3 - x][y];
                }
            }
            
            if (checkOverlap(py, px))
            {
                Block.block[blockType] = clone(temp);
                return;
            }
            
            for (y = 0; y < 4; y++)
            {
                for (x = 0; x < 4; x++)
                {
                    block[py + y][px + x] -= temp[y][x];
                    block[py + y][px + x] += Block.block[blockType][y][x];
                }
            }
                    
            draw();
        }
        
        private function checkLines():void
        {
            var found:Boolean;
            
            for (var y:int = 19; y >= 0; y--)
            {
                found = true;
                for (var x:int = 1; x <= 11; x++)
                {
                    if (field[y][x] == 0)
                    {
                        found = false;
                        break;
                    }
                }
                if (found)
                {
                    playEffect(0);
                    for (var xx:int = 1; xx <= 11; xx++) field[y][xx] == 0;
                    for (var yy:int = y; yy >= 1; yy--)
                    {
                        for (xx = 1; xx <= 11; xx++)
                        {
                            field[yy][xx] = field[yy - 1][xx];
                        }
                    }
                    y++;
                    lines++;
                }
            }
        }
        
        private function createTextField(parent:Sprite = null, text:String = "", x:int = 0, y:int = 0, fontSize:int = 13,c:uint=0xFFFFFF):TextField
        {
            var tf:TextField = new TextField();
            tf.x = x, tf.y = y;
            tf.defaultTextFormat = new TextFormat("_typeWriter", fontSize, c);
            tf.text = text;
            tf.selectable = false;
            tf.autoSize = TextFieldAutoSize.LEFT;
            if (parent) parent.addChild(tf);
            else this.addChild(tf);
            
            return tf;
        }
        
        private function clone(arg:*):*
        {
            var b:ByteArray = new ByteArray();
            b.writeObject(arg);
            b.position = 0;
            return b.readObject();
        }
    }
}

class Block
{
    public static var block:Array = [[[0, 0, 0, 0],
                                      [0, 1, 1, 0],
                                      [0, 1, 1, 0],
                                      [0, 0, 0, 0]],
                                     [[0, 0, 2, 0],
                                      [0, 0, 2, 0],
                                      [0, 0, 2, 0],
                                      [0, 0, 2, 0]],
                                     [[0, 0, 0, 0],
                                      [0, 3, 3, 0],
                                      [0, 3, 0, 0],
                                      [0, 3, 0, 0]],
                                     [[0, 0, 4, 0],
                                      [0, 4, 4, 0],
                                      [0, 4, 0, 0],
                                      [0, 0, 0, 0]],
                                     [[0, 5, 0, 0],
                                      [0, 5, 5, 0],
                                      [0, 0, 5, 0],
                                      [0, 0, 0, 0]],
                                     [[0, 0, 0, 0],
                                      [0, 6, 0, 0],
                                      [6, 6, 6, 0],
                                      [0, 0, 0, 0]],
                                     [[0, 0, 0, 0],
                                      [0, 7, 7, 0],
                                      [0, 0, 7, 0],
                                      [0, 0, 7, 0]]];
    
    //
    public static var color:Array = [0xFFFF00, 0x00FFFF, 0x0000FF, 0xFF0000, 0x00FF00, 0xAA00FF, 0xFFA500]; 
    
    public function Block(){}
}