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: forked from: Tetris3D

// forked from tyrael51's forked from: Tetris3D
// forked from yonatan's Tetris3D
// forked from flashrod's Tetris
package {
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.utils.getTimer;

    import org.papervision3d.materials.*;
    import org.papervision3d.materials.utils.*;
    import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
    import org.papervision3d.lights.PointLight3D;
    import org.papervision3d.objects.*;
    import org.papervision3d.objects.primitives.*
    import org.papervision3d.view.*;
    import org.papervision3d.scenes.Scene3D;

    [SWF(backgroundColor = "0x000000", frameRate = "24")]
    
    public class Tetris extends BasicView {
        private const W:int = 10;
        private const H:int = 20;
        private const UNIT:int = 16;
        private const COLOR:Array =[0x000000, 0x00FFFF, 0xFFFF00, 0x22FF22, 0xFF2222, 0x4444FF, 0xFF8844, 0xFF22FF];
        private const PAT:Array =[
            [[1, 1, 1, 1]],
            [[0, 2, 0], [2, 2, 2]],
            [[3, 3, 0], [0, 3, 3]],
            [[0, 4, 4], [4, 4, 0]],
            [[5, 5], [5, 0], [5, 0]],
            [[6, 6], [0, 6], [0, 6]],
            [[7, 7], [7, 7]]
        ];
        private const SPEED:Array = [30, 20, 10, 5];

        private const VK_H:int = 72; // h
        private const VK_J:int = 74; // j
        private const VK_K:int = 75; // k
        private const VK_L:int = 76; // l
        private const VK_SPC:int = 32; // space

        private var field:Array = [];
        private var piece:Array;
        private var next:Array;
        private var text:TextField = new TextField();
        private var keytable:Array = [];
        private var count:int = 0;
        private var step:int = 0;
        private var px:int;
        private var py:int;

        private var light:PointLight3D;

        public function Tetris() {
            Wonderfl.capture_delay(25);

            light = new PointLight3D(false);
            light.x = 500;
            light.y = -750;
            light.z = 1500;

            text.x = 300;
            text.textColor = 0xFFFFFF;
            text.text="Next:";
            addChild(text);
            var t:TextField = new TextField();
            t.textColor = 0xFFFFFF;
            t.text = "Keys: H, J, K, L, SPACE";
            t.scaleX = t.scaleY = 1.25;
            t.width = 250;

            addChild(t);
            field = new Array(H).map(function():*{
                    return new Array(W).map(function():*{
                            return 0;
                        })
                });
            keytable[VK_H] = function():void {px -= space(px-1, py, piece)};
            keytable[VK_J] = function():void {rotate(true)};
            keytable[VK_K] = function():void {rotate(false)};
            keytable[VK_L] = function():void {px += space(px+1, py, piece)};
            keytable[VK_SPC] = function():void {drop(); pick();};
            stage.addEventListener(KeyboardEvent.KEY_DOWN, function(e:KeyboardEvent):void {
                    if (keytable[e.keyCode]) {
                        var oldpx:int = px;
                        var oldpy:int = py;
                        keytable[e.keyCode]();
                        repaint();
                    }
                });
            pick();
            pick();
            addEventListener(Event.ENTER_FRAME, function(e:Event):void {
                    if (--step < 0) {
                        step=SPEED[int(count/10)];
                        if (space(px, py+1, piece)) {
                            ++py;
                            repaint();
                        } else {
                            drop();
                            pick();
                        }
                    }
                    //repaint();
                });
        }

        private function rotate(clock:Boolean):void {
            var r:Array = new Array(piece[0].length).map(function():*{return [];});
            for (var j:int = 0; j<piece.length; ++j)
            for (var i:int = 0; i < r.length; ++i)
            if (clock)
            r[i][piece.length-1-j] = piece[j][i];
            else
            r[r.length-1-i][j] = piece[j][i];
            if (space(px, py, r))
            piece = r;
        }

        private function repaint():void {
            // TODO:
            // Reuse Scene3D and Cube objects.
            // Don't recreate on every repaint.
            
            scene = new Scene3D;

			for( var x:int = -1; x <= W; x++ ) {
				scene.addChild( cube( x, -1, 0x444444 ) );
				scene.addChild( cube( x, H, 0x444444 ) );
			}
			for( var y:int = -1; y <= H; y++ ) {
				scene.addChild( cube( -1, y, 0x444444 ) );
				scene.addChild( cube( W, y, 0x444444 ) );
			}

            //graphics.clear();
            for (var j:int = 0; j < H; ++j) 
            for (var i:int = 0; i < W; ++i) {
                var g:int = 0;
                if (py <= j && j < (py+piece.length) && px <= i && i < (px+piece[0].length))
                g = piece[j-py][i-px];
                if (g == 0)
                g = field[j][i];
                //graphics.beginFill(COLOR[g]);
                //graphics.drawRect(i*UNIT, j*UNIT, UNIT, UNIT);

                if(g) scene.addChild( cube( i, j, COLOR[g] ) );
            }

            for (j = 0; j < next.length; ++j)
            for (i = 0; i < next[j].length; ++i) {
                g = next[j][i];
                //graphics.beginFill(COLOR[ci]);
                //graphics.drawRect((i+W+1)*UNIT, (j+2)*UNIT, UNIT, UNIT);

                if(g) scene.addChild( cube( i+W , j-H/2+1, COLOR[g], 3, 3 ) );
            }

            camera.z = 300;
            camera.y = -120;
            renderer.renderScene( scene, camera, viewport );
        }

        private function cube( x:int, y:int, c:uint, w:int = W, h:int = H ):Cube {
            var mlist:MaterialsList = new MaterialsList( { all : new FlatShadeMaterial(light,c) } );            
            var ret:Cube = new Cube( mlist, UNIT, UNIT, UNIT );
            ret.x = -(x - w/2) * UNIT * 1.1;
            ret.y = -(y - h/2) * UNIT * 1.1;
            return ret;
        }
        

        private function space(x:int, y:int, p:Array):int {
            for (var j:int = 0; j < p.length; ++j) {
                if (0 > (y+j) || (y+j) >= H)
                return 0;
                for (var i:int = 0; i < p[j].length; ++i) {
                    if (0 > (x+i) || (x+i) >= W)
                    return 0;
                    if (p[j][i] && field[y+j][x+i])
                    return 0;
                }
            }
            return 1;
        }

        private function drop():void {
            for (; space(px, py+1, piece); py++)
            ;
            for (var j:int = 0; j < piece.length; ++j)
            for (var i:int = 0; i < piece[j].length; ++i)
            if (piece[j][i])
            field[py+j][px+i] = piece[j][i];
            for (j=0; j<H; ++j)
            if (field[j].indexOf(0) < 0) {
                field.splice(j, 1);
                field.unshift([]);
                for (i=0; i<W; ++i)
                field[0][i] = 0;
            }

            count++;
            if (count/10 >= SPEED.length)
            count = 0;
        }

        private function pick():void {
            piece = next;
            if (piece != null) {
                px = (W-piece[0].length)/2;
                py = 0;
                if (!space(px, py, piece))
                text.text="GAME OVER";
            }
            next = PAT[int(Math.random()*PAT.length)];
        }
    }
}