tetris
http://matrix3d.github.io/
@author lizhi
/**
* Copyright lizhi ( http://wonderfl.net/user/lizhi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/zUcu
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
/**
* http://matrix3d.github.io/
* @author lizhi
*/
public class TestTetris extends Sprite
{
private var numRows:int = 21;
private var numCols:int = 14;
private var data:Array = [];
private var groups:Array = [];
private var xadder:int;
private var yadder:int;
private var toEnd:Boolean = false;
private var rotadder:int;
private var frame:int = 0;
public function TestTetris()
{
if(stage)
init();
else
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
newGroup();
addEventListener(Event.ENTER_FRAME, enterFrame);
stage.addEventListener(KeyboardEvent.KEY_DOWN, stage_keyDown);
//alpha = .03;
}
private function addedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
init();
}
private function stage_keyDown(e:KeyboardEvent):void
{
xadder = 0;
yadder = 0;
rotadder = 0;
toEnd = false;
if (e.keyCode==Keyboard.DOWN) {
//yadder = 1;
toEnd = true;
}else if (e.keyCode==Keyboard.LEFT) {
xadder = -1;
}else if (e.keyCode==Keyboard.RIGHT) {
xadder = 1;
}else if (e.keyCode==Keyboard.UP) {
rotadder = 1;
}else if (e.keyCode==Keyboard.UP) {
rotadder = -1;
}else if (e.keyCode==Keyboard.SPACE) {
toEnd = true;
}
}
private function init():void {
for (var y:int = 0; y < numRows; y++ ) {
var arr:Array = [];
data[y] = arr;
for (var x:int = 0; x < numCols; x++ ) {
if ((y==(numRows-1))||(x==0)||(x==(numCols-1))) {
data[y][x] = new Cube;
}
}
}
}
private function newGroup():void {
var g:CubeGroup = new CubeGroup;
g.x = int(numCols / 2);
g.xFloat = g.x;
groups.push(g);
var r:int = Math.random() * 7;
if (r == 0) {//土
g.color = 0xaa0000;
g.createCube(0, 0);
g.createCube(1, 0);
g.createCube(-1, 0);
g.createCube(0, 1);
}else if (r==1) {//方块
g.color = 0xaa00;
g.createCube(0, 0);
g.createCube(1, 1);
g.createCube(1, 0);
g.createCube(0, 1);
}else if (r==2) {//直线
g.color = 0xaa;
g.createCube(0, -1);
g.createCube(0, 0);
g.createCube(0, 1);
g.createCube(0, 2);
}else if (r==3) {//曲线1
g.color = 0xaaaa00;
g.createCube(0, -1);
g.createCube(0, 0);
g.createCube(1, 0);
g.createCube(1, 1);
}else if (r==4) {//曲线2
g.color = 0xaaaa;
g.createCube(1, -1);
g.createCube(0, 0);
g.createCube(1, 0);
g.createCube(0, 1);
}else if (r==5) {//l1
g.color = 0xaa00aa;
g.createCube(0, -1);
g.createCube(0, 0);
g.createCube(0, 1);
g.createCube(1, 1);
}else if (r==6) {//l2
g.color = 0xaaaaaa;
g.createCube(0, -1);
g.createCube(0, 0);
g.createCube(0, 1);
g.createCube(-1, 1);
}
}
private function enterFrame(e:Event):void
{
update();
var g:CubeGroup = groups[groups.length - 1];
if (g&&(g.yFloat-g.y)>=0) {
yadder = 1;
update();
}
if (toEnd) {
do {
yadder = 1;
var isEnd:Boolean = update();
}while(!isEnd)
toEnd = false;
}
frame++;
render();
}
private function update():Boolean {
var ret:Boolean = false;
var g:CubeGroup = groups[groups.length - 1];
if (g) {
if(xadder||yadder||rotadder){
g.x += xadder;
g.y += yadder;
g.rotation += rotadder;
var collision:Boolean = false;
for each(var c:Cube in g.cubes) {
c.updateRotation();
var x:int = g.x + c.x;
var y:int = g.y + c.y;
if (data[y]&&data[y][x]) {
collision = true;
}
}
if (collision) {
g.x -= xadder;
g.y -= yadder;
g.rotation -= rotadder;
for each(c in g.cubes) {
c.updateRotation();
}
if (yadder>0) {
for each(c in g.cubes) {
c.updateRotation();
x = g.x + c.x;
y = g.y + c.y;
if (data[y]) {
var cr:uint=0xff
data[y][x] = c;
var color:Color = new Color;
color.fromHex(c.color);
color.r *= .5;
color.g *= .5;
color.b *= .5;
c.color = color.toHex();
}
}
for (y = numRows-2; y >= 0; y-- ) {
var full:Boolean = true;
for (x = 1; x < numCols-1;x++ ) {
if (data[y][x]==null) {
full = false;
break;
}
}
if (full) {
for (var y2:int = y; y2 > 0; y2-- ) {
for (x = 1; x < numCols - 1; x++ ) {
data[y2][x] = data[y2 - 1][x];
}
}
y++;
}
}
groups.pop();
newGroup();
ret = true;
}
}
xadder = 0;
yadder = 0;
rotadder = 0;
}
var absdx:Number=Math.abs(g.x-g.xFloat)
if (absdx<=.2) {
g.xFloat = g.x;
}else {
var speed:Number = .2 * Math.ceil(absdx);
if (g.xFloat<g.x) {
g.xFloat += speed;
}else {
g.xFloat -= speed;
}
}
g.yFloat += .1;
}
return ret;
}
private function render():void {
var cubeWidth:int = 20;
graphics.clear();
for (x = 0; x < numCols;x++ ) {
for (y = 0; y < numRows; y++ ) {
if (data[y][x]) {
graphics.lineStyle();
graphics.beginFill(data[y][x].color);
}else {
graphics.lineStyle(0,0xeeeeee);
graphics.endFill();
}
graphics.drawRect(x*cubeWidth, y*cubeWidth, cubeWidth, cubeWidth);
}
}
graphics.lineStyle();
for each(var g:CubeGroup in groups) {
for each(var c:Cube in g.cubes) {
graphics.beginFill(c.color);
graphics.drawRect((g.xFloat + c.x) * cubeWidth, (g.yFloat + c.y) * cubeWidth, cubeWidth, cubeWidth);
}
}
}
}
}
class Cube {
public var x:int = 0;
public var y:int = 0;
public var ox:int = 0;
public var oy:int = 0;
public var group:CubeGroup;
public var color:uint = 0x999999;
public function updateRotation():void {
var stats:int = group.rotation%4;
if (stats<0) {
stats = 4+stats;
}
if (stats==0) {
x = ox;
y = oy;
}else if (stats==1) {
x = -oy;
y = ox;
}else if (stats==2) {
x = -ox;
y = -oy;
}else {
x = oy;
y = -ox;
}
}
}
class CubeGroup {
public var x:int = 0;
public var y:int = 0;
public var rotation:int = 0;
public var cubes:Array = [];
public var color:uint = 0xff0000;
//ease缓动
public var xFloat:Number = 0;
public var yFloat:Number = 0;
public function createCube(x:int, y:int):void {
var cube:Cube = new Cube;
cube.x=cube.ox = x;
cube.y =cube.oy= y;
cube.group = this;
cube.color = color;
cubes.push(cube);
}
}
class Color {
public var r:Number;
public var g:Number;
public var b:Number;
public function fromHex(hex:uint=0):void {
r = (hex >> 16) & 0xff;
g = (hex >> 8) & 0xff;
b = hex & 0xff;
}
public function toHex():uint {
return (Math.round(r) << 16) | (Math.round(g) << 8) | Math.round(b);
}
}