forked from: 8 Arrows

by raa forked from 8 Arrows (diff: 1)
♥0 | Line 503 | Modified 2016-01-10 07:55:51 | MIT License
play

ActionScript3 source code

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

// forked from greentec's 8 Arrows
package 
{
    import com.bit101.components.Label;
    import com.bit101.components.PushButton;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.utils.ByteArray;
    
    /**
     * ...
     * @author ypc
     */
    [SWF(width=465, height=465, backgroundColor=0x292929, frameRate=60)]
    public class Main extends Sprite 
    {
        public var screenWidth:int = 465;
        public var screenHeight:int = 465;
        
        public var blocks:Array;
        public var blockNumWidth:int = 7;
        public var blockNumHeight:int = 6;
        public var blockWidth:int;
        public var blockHeight:int;
        
        public var blockSprite:Sprite;
        
        public var uiSprite:Sprite;
        public var uiBitmap:Bitmap;
        public var uiBitmapData:BitmapData;
        
        public var initEmptyBlockProb:Number = 0.3;
        
        public var dirs:Array = [[ -1, 0], [ -1, 1], [0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [ -1, -1]];
        public var turn:uint = 0;
        public var score:uint = 0;
        public var hiScore:uint = 0;
        public var hiBlock:uint = 0;
        public var gameOver:Boolean = false;
        public var breakBlockNum:uint = 0;
        
        public var prevIncomingBlockList:Array;
        public var incomingBlockList:Array;
        public var incomingBlockNum:int = 3;
        public var incomingBlockNumMax:int = 3;
        public var emptyBlockArray:Array = [];
        public var selectedBlockArray:Array = [];
        
        public var blockDropBonusScore:int = 10;
        
        public var titleLabel:Label;
        public var hiScoreLabel:Label;
        public var scoreLabel:Label;
        public var breakBlockNumLabel:Label;
        public var incomingLabel:Label;
        public var gameOverLabel:Label;
        
        public var backgroundBitmapData:BitmapData;
        public var backgroundBitmap:Bitmap;
        public var backgroundSprite:Sprite;
        
        public var restartButton:PushButton;
        
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            
            stage.scaleMode = "noScale";
           
            backgroundSprite = new Sprite();
            addChild(backgroundSprite);
            
            backgroundBitmapData = new BitmapData(465, 465, false, 0x292929);
            backgroundBitmap = new Bitmap(backgroundBitmapData);
            backgroundSprite.addChild(backgroundBitmap);
           
            blockSprite = new Sprite();
            addChild(blockSprite);
            
            
            uiBitmapData = new BitmapData(screenWidth, screenHeight, true, 0x00ffffff);
            uiBitmap = new Bitmap(uiBitmapData);
            uiSprite = new Sprite();
            uiSprite.addChild(uiBitmap);
            addChild(uiSprite);
            uiSprite.mouseEnabled = false;
            
            initMap();
            initUI();
            initIncomingBlock();
        }
        
        private function initUI():void
        {
            titleLabel = new Label(this, blockWidth/2, 10, "8 Arrows");
            titleLabel.scaleX = 1.5;
            titleLabel.scaleY = 1.5;
            
            hiScoreLabel = new Label(this, titleLabel.x, titleLabel.y + titleLabel.height * 1.5, "Hi-Score : " + String(hiScore) + " (" + String(hiBlock) + ")");
            scoreLabel = new Label(this, hiScoreLabel.x, hiScoreLabel.y + hiScoreLabel.height - 5, "Score : " + String(score));
            breakBlockNumLabel = new Label(this, scoreLabel.x, scoreLabel.y + scoreLabel.height - 5, "Block : " + String(breakBlockNum));
            
            incomingLabel = new Label(this, 0, titleLabel.y + 5, "Incoming Block ->");
            incomingLabel.x = (blockNumWidth - 2.5) * blockWidth - (incomingLabel.width + 10);
            
            gameOverLabel = new Label(this, -100, -100, "Game Over");
            gameOverLabel.scaleX = gameOverLabel.scaleY = 5;
            gameOverLabel.alpha = 0;
            gameOverLabel.mouseEnabled = false;
            gameOverLabel.x = screenWidth / 2 - gameOverLabel.width * 5 / 2;
            gameOverLabel.y = screenHeight / 2 - gameOverLabel.height * 5 / 2;
            
            restartButton = new PushButton(this, -100, -100, "Restart", onRestart);
            restartButton.alpha = 0;
            restartButton.height = 40;
       }
        
        private function onRestart(e:Event):void
        {
            if (gameOver == true)
            {
                gameOver = false;
                uiBitmapData.fillRect(uiBitmapData.rect, 0x00ffffff);
                restartButton.alpha = 0;
                restartButton.x = -100;
                restartButton.y = -100;
                gameOverLabel.alpha = 0;
                
                hiScore = Math.max(hiScore, score);
                hiBlock = breakBlockNum;
                score = 0;
                breakBlockNum = 0;
                drawScore();
                
                resetAllBlock();
                updateIncomingBlockList();
            }
            
            
        }
        
        private function resetAllBlock():void
        {
            var i:int;
            var j:int;
            var block:Block;
            
            for (i = 0; i < blockNumWidth; i += 1)
            {
                for (j = 0; j < blockNumHeight; j += 1)
                {
                    block = blocks[i][j];
                    block.direction = Math.random() * 8;
                    if (Math.random() < initEmptyBlockProb)
                    {
                        block.direction = -1;
                    }

                    block.draw(block._G.graphics);
                    
                    if (block.direction == -1)
                    {
                        blockSprite.setChildIndex(block, 0);
                    }

                }
            }
        }
        
        private function initIncomingBlock():void
        {
            prevIncomingBlockList = [0, 1, 2];
            incomingBlockList = [];
            var i:int;
            var block:Block;
            for (i = 0; i < incomingBlockNum; i += 1)
            {
                block = new Block(int(Math.random() * 8), blockWidth, blockHeight);
                block.draw(block._G.graphics);
                block.x = (blockNumWidth - i) * blockWidth;
                block.y = 0.75 * blockHeight;
                blockSprite.addChild(block);
                
                incomingBlockList.push(block);
            }
        }
        
        private function updateIncomingBlockList():void
        {
            var i:int;
            var block:Block;
            

           for (i = 0; i < incomingBlockNum; i += 1)
            {
                block = incomingBlockList[i];
                block.direction = Math.random() * 8;
                block.draw(block._G.graphics);
            }
        }
        
        public function clone(source:Object):*
        {
            var myBA:ByteArray = new ByteArray();
            myBA.writeObject(source);

           myBA.position = 0;
            return(myBA.readObject()); 
        }
        
        private function initMap():void
        {
            var i:int;

           var j:int;
            var block:Block;
            
            blockWidth = screenWidth / (blockNumWidth + 1);
            blockHeight = screenHeight / (blockNumHeight + 2);
            
            blocks = [];

           for (i = 0; i < blockNumWidth; i += 1)
            {

               blocks[i] = [];

             for (j = 0; j < blockNumHeight; j += 1)
                {
                    block = new Block(int(Math.random() * 8), blockWidth, blockHeight);
                    if (Math.random() < initEmptyBlockProb)
                    {
                        block.direction = -1;
                    }
                   
                    block.draw(block._G.graphics);
                    block.x = (i + 1) * (blockWidth);
                    block.y = (j + 2) * (blockHeight);
                    block._x = i;
                    block._y = j;
                    block.addEventListener(MouseEvent.MOUSE_OVER, onBlockMouseOver);
                    block.addEventListener(MouseEvent.MOUSE_OUT, onBlockMouseOut);
                    block.addEventListener(MouseEvent.CLICK, onBlockMouseClick);
                   
                    blocks[i].push(block);
                    blockSprite.addChild(block);
                    if (block.direction == -1)
                    {
                        blockSprite.setChildIndex(block, 0);
                    }
                }
            }
        }
        
        private function onBlockMouseOver(e:MouseEvent):void
        {
            var block:Block = e.target.parent as Block;
            if (block.direction != -1 && gameOver == false) //not empty
            {
                e.target.alpha = 0.5;
            }
        }
        
        private function onBlockMouseOut(e:MouseEvent):void
        {
            var block:Block = e.target.parent as Block;
            if (block.direction != -1 && gameOver == false)
            {
                e.target.alpha = 1;
            }
        }
        
        private function onBlockMouseClick(e:MouseEvent):void
        {
            if (gameOver == false)
            {
                var i:int;
                var block:Block = e.target.parent as Block;
                var block2:Block;
                var block3:Block;
                var tempX:int;
                var tempY:int;
                
                if (block.direction != -1) // not empty -> move
                {
                    // out of boundary - drop
                    if (block._x + dirs[block.direction][0] < 0 ||
                        block._x + dirs[block.direction][0] >= blockNumWidth ||
                        block._y + dirs[block.direction][1] < 0 ||
                        block._y + dirs[block.direction][1] >= blockNumHeight)
                    {
                        block.direction = -1;
                        block.draw(block._G.graphics);
                        blockSprite.setChildIndex(block, 0); //empty to bottom display
                        
                        score += blockDropBonusScore;
                        breakBlockNum += 1;
                        drawScore();
                        
                    }
                    else if (blocks[block._x + dirs[block.direction][0]][block._y + dirs[block.direction][1]].direction == -1)
                    {// OR: move to empty
                        block2 = blocks[block._x + dirs[block.direction][0]][block._y + dirs[block.direction][1]];
                        block2.direction = block.direction;
                        block.direction = -1;
                        
                        block.draw(block._G.graphics);
                        blockSprite.setChildIndex(block, 0); //empty to bottom display
                        
                        block2.draw(block2._G.graphics);
                        blockSprite.setChildIndex(block2, blockSprite.numChildren - 1);
                    }
                    else
                    {// OR: switch with other
                        block2 = blocks[block._x + dirs[block.direction][0]][block._y + dirs[block.direction][1]];
                        var temp:int = block.direction;
                        block.direction = block2.direction;
                        block2.direction = temp;
                        
                        block.draw(block._G.graphics);
                        block2.draw(block2._G.graphics);
                    }
                    
                    blockEraseCheck();
                    
                    turn += 1;
                    if (turn % 1 == 0)
                    {
                        for (i = 0; i < selectedBlockArray.length; i += 1)
                        {
                            tempX = emptyBlockArray[selectedBlockArray[i]] % blockNumWidth;
                            tempY = emptyBlockArray[selectedBlockArray[i]] / blockNumWidth;
                            block3 = blocks[tempX][tempY];
                            block3.draw(block3._G.graphics);
                        }
                        
                        addNewBlockToEmptyBlock();
                        updateIncomingBlockList();
                        
                        gameOverCheck();
                    }
                    //else
                    //{
                        //if (selectedBlockArray.length > 0)
                        //{
                            //for (i = 0; i < selectedBlockArray.length; i += 1)
                            //{
                                //tempX = emptyBlockArray[selectedBlockArray[i]] % blockNumWidth;
                                //tempY = emptyBlockArray[selectedBlockArray[i]] / blockNumWidth;
                                //block3 = blocks[tempX][tempY];
                                //block3.draw(block3._G.graphics);
                            //}
                        //}
                    //}
                }
            }
        }
        
        private function addNewBlockToEmptyBlock():void
        {
            var i:int;
            var j:int;
            var block:Block;
            var tempX:int;
            var tempY:int;
            
            emptyBlockArray = [];
            
            for (i = 0; i < blockNumWidth; i += 1)
            {
                for (j = 0; j < blockNumHeight; j += 1)
                {
                    block = blocks[i][j];
                    if (block.direction == -1) //is Empty -> add to emptyBlockArray
                    {
                        emptyBlockArray.push(i + j * blockNumWidth);
                    }
                }
            }
            
            if (emptyBlockArray.length < incomingBlockNum)
            {
                gameOver = true;
            }
            
            selectedBlockArray = printRandomNumber(emptyBlockArray.length, incomingBlockNum);
            
            for (i = 0; i < incomingBlockNum; i += 1)
            {
                tempX = emptyBlockArray[selectedBlockArray[i]] % blockNumWidth;
                tempY = emptyBlockArray[selectedBlockArray[i]] / blockNumWidth;
                block = blocks[tempX][tempY];
                block.direction = incomingBlockList[i].direction;
                block.draw(block._G.graphics);
                block.edgeDraw(block._G.graphics);
                block._G.alpha = 1;
                
                blockSprite.setChildIndex(block, blockSprite.numChildren - 1);
            }
        }
        
        private function gameOverCheck():void
        {
            if (gameOver == true)
            {
                gameOverLabel.alpha = 1;
                uiBitmapData.fillRect(uiBitmapData.rect, 0x80ff0000);
                restartButton.x = screenWidth / 2 - restartButton.width / 2;
                restartButton.y = screenHeight / 2 - restartButton.height / 2 + 50;
                restartButton.alpha = 1;
            }
        }
        
        private function printRandomNumber(n:int, k:int) : Array
        {
            var original:Array=[];
            var result:Array=[];
            var i:int;
            var randInt:int;
            var temp:Object;
            
            for (i = 0; i < n; i += 1)
            {
                original.push(i);
            }
            
            for (i = 0; i < k; i += 1)
            {
                randInt = Math.random()*(n-i) + i;
                temp = original[i];
                original[i] = original[randInt];
                original[randInt] = temp;
                result.push(original[i]);
            }
            
            return result;
        }
        
        private function blockEraseCheck():void
        {
            var i:int;
            var j:int;
            var k:int;
            var block:Block;
            var block2:Block;
            
            for (i = 0; i < blockNumWidth; i += 1)
            {
                for (j = 0; j < blockNumHeight; j += 1)
                {
                    block = blocks[i][j];
                    if (block.direction != -1 && block._marked == false) //not empty - dfs!
                    {
                        var temp:Array = [i + j * blockNumWidth];
                        block._marked = true;
                        var deleteList:Array = searchBlock(i, j, block.direction, temp);
                        if (deleteList.length > 2) // over 3 adjacent blocks same direction - delete!
                        {
                            for (k = 0; k < deleteList.length; k += 1)
                            {
                                block2 = blocks[deleteList[k] % blockNumWidth][int(deleteList[k] / blockNumWidth)];

                               block2.direction = -1;
                                block2.draw(block2._G.graphics);
                                blockSprite.setChildIndex(block2, 0);
                            }
                            
                            score += (Math.pow((deleteList.length + 2), 2) * 10);
                            breakBlockNum += deleteList.length;
                            drawScore();
                        }
                    }
                }
            }
            
            for (i = 0; i < blockNumWidth; i += 1)
            {

               for (j = 0; j < blockNumHeight; j += 1)
                {
                    block = blocks[i][j];
                    block._marked = false;
                }
            }
            
        }
        
        private function searchBlock(i:int, j:int, direction:int, path:Array):Array
        {
            var block:Block;
            if (i - 1 > 0) //left check
            {
                block = blocks[i-1][j];
                if (block.direction == direction && block._marked == false)
                {
                    block._marked = true;
                    path.push(i - 1 + j * blockNumWidth);
                    searchBlock(i - 1, j, direction, path);
                }
            }
            if (i + 1 < blockNumWidth) //right check
            {
                block = blocks[i+1][j];
                if (block.direction == direction && block._marked == false)
                {
                    block._marked = true;
                    path.push(i + 1 + j * blockNumWidth);
                    searchBlock(i + 1, j, direction, path);
                }
            }
            if (j - 1 > 0) //up check
            {
                block = blocks[i][j-1];
                if (block.direction == direction && block._marked == false)
                {
                    block._marked = true;
                    path.push(i + (j - 1) * blockNumWidth);
                    searchBlock(i, j - 1, direction, path);
                }
            }
            if (j + 1 < blockNumHeight) //down check
            {
                block = blocks[i][j+1];
                if (block.direction == direction && block._marked == false)
                {
                    block._marked = true;
                    path.push(i + (j + 1) * blockNumWidth);
                    searchBlock(i, j + 1, direction, path);
                }
            }
            
            return path;
        }
        
        private function drawScore():void
        {
            hiScoreLabel.text = "Hi-Score : " + String(hiScore) + " (" + String(hiBlock) + ")";
            scoreLabel.text = "Score : " + String(score);
            breakBlockNumLabel.text = "Block : " + String(breakBlockNum);
        }
        
        
    }
    
}

Class
{    
    import flash.display.Graphics;
    import flash.display.Sprite;
    /**
     * ...
     * @author ypc
     */
    class Block extends Sprite
    {
        public var _x:int;
        public var _y:int;
        public var direction:int = -1;
        public var _G:Sprite;
        public var colors:Array = [0x8B0000, 0xFF8C00, 0xFFD700, 0x2F4F2F, 0x000080, 0x4B0082, 0xFF00FF, 0x5C4033];
        public var _width:int;
        public var _height:int;
        public var dirs:Array = [[ -1, 0], [ -1, 1], [0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [ -1, -1]];
        public var _marked:Boolean = false;
        
        public function Block(direction:int, _width:int, _height:int) 
        {
            this.direction = direction;
            this._width = _width;
            this._height = _height;
            
            _G = new Sprite();
            addChild(_G);
            
            //draw(_G.graphics);
        }
        
        public function edgeDraw(G:Graphics):void
        {
            G.lineStyle(5, 0x00ff00);
            G.drawRect( -_width / 2, -_height / 2, _width, _height);
        }
        
        public function draw(G:Graphics):void
        {
            G.clear();
            
            if (this.direction == -1) // empty
            {
                G.lineStyle(3, 0x646464);
                G.drawRect( -_width / 2, -_height / 2, _width, _height);
            }
            else
            {
                G.lineStyle(3, 0xffffff);
                G.beginFill(colors[this.direction]);
                G.drawRect( -_width / 2, -_height / 2, _width, _height);
                G.endFill();
                
                //arrow Drawing
                G.beginFill(0xffffff, 0.8);
                G.drawCircle(dirs[this.direction][0] * _width / 3, dirs[this.direction][1] * _height / 3, (_width + _height) / 16);
                G.endFill();
                
                G.lineStyle(1, 0xffffff, 0.8);
                G.moveTo(dirs[this.direction][0] * _width / 3, dirs[this.direction][1] * _height / 3);
                var opposite:int;
                if (this.direction >= 4)
                    opposite = this.direction - 4;
                else
                    opposite = this.direction + 4;
                G.lineTo(dirs[opposite][0] * _width / 3, dirs[opposite][1] * _height / 3);
            }
        }
        
    }

}