forked from: 8 Arrows
forked from 8 Arrows (diff: 1)
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);
}
}
}
}