package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.utils.Timer;
import flash.geom.Point;
import flash.events.TimerEvent;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard
import flash.text.TextField;
import flash.events.MouseEvent;
[SWF (height = '600', width = '420')]
public class main extends MovieClip
{
private var nextBgkuan:uint=4//下一个图片显示背景宽格数
private var nextBggao:uint=4//下一个图型显示背景高格数
private var nextBgbc:uint=14//下一个图型显示背景边长
private var a:uint=20//方块边长
private var kuan:uint=18//宽格数
private var gao:uint=30//高格数
private var type:Array=[]//各种方块类型
private var nextGrid:Array//下一个方块容器
private var nextSp:Sprite//下一模块
private var usingGrid:Array//当前方块容器
private var usingSp:Sprite//当前模块
private var usingPosition:Point//当前位置
private var rongqi:Array=[]//容器
private var rongqiNext:Array=[]//下一个图型容器
private var timer:Timer=new Timer(500)
private var txt:TextField//用于显示分数的文本框
private var score:uint=0//分数(通关行数)
private var levelUp:uint=10//每通关多少行升级
public function main()
{
init()//初始化地图
reDraw()//绘制地图
getType()//创建所有方块类型
createGrid()//随机创建一个方块,加入到预备
startGrid()//将一个预备中的方块转为正在使用的方块
timer.start()//定时下沉
timer.addEventListener(TimerEvent.TIMER,onTimer)
stage.addEventListener(KeyboardEvent.KEY_DOWN,onDown)//侦听键盘事件
stage.addEventListener(MouseEvent.CLICK,togglePause)
txt=new TextField
txt.x=370
txt.y = 150
this.addChild(txt)
txt.text="0"
txt.selectable=false
}
private function onDown(e:KeyboardEvent):void{//键盘事件
switch(e.keyCode)
{
case Keyboard.LEFT:left()//向左
break
case Keyboard.UP:roll()//旋转方块
break
case Keyboard.RIGHT:right()//向右
break
case Keyboard.DOWN:down()//向下
break
}
}
private function togglePause(e:MouseEvent):void{//点击暂停游戏
if(timer.running)timer.stop()
else timer.start()
stage.removeEventListener(KeyboardEvent.KEY_DOWN,onDown)
}
//初始化背景
private function init()
{
var i:int,j:int
for(i=0;i<kuan;i++)
{// 绘制背景方块
rongqi[i]=[]
for(j=0;j<gao;j++)
{
rongqi[i][j]=0
}
}
for(i=0;i<nextBgkuan;i++){// 绘制下一个图型背景方块
rongqiNext[i]=[]
for(j=0;j<nextBggao;j++){
rongqiNext[i][j]=0
}
}
}
private function addScore(){
score++
txt.text=score.toString()
if(score%levelUp==0){//行数增加,游戏提速
var level:uint=score/levelUp
level=level>9?9:level
timer.stop()
timer.removeEventListener(TimerEvent.TIMER,onTimer)
timer=new Timer(1000-level*1000)
timer.addEventListener(TimerEvent.TIMER,onTimer)
timer.start()//定时下沉
}
}
//绘制网格
private function drawAGrid(mc:Sprite,i:int,j:int,zbpyx:int,zbpyy:int,bc:int,aa:int,color:uint):void
{
//填充颜色
mc.graphics.beginFill(color)
//绘制方格
mc.graphics.drawRect(i*bc+zbpyx,j*bc+zbpyy,aa,aa)
//结束填充
mc.graphics.endFill()
}
private function left():void
{
usingPosition.x--
if(hit(usingGrid))
{//检测下一状态是否碰撞,如发生碰撞则不允向左
usingPosition.x++
return
}
else{
usingSp.x=usingPosition.x*a
}
}
private function right():void{
usingPosition.x++
if(hit(usingGrid)){//检测下一状是否碰撞,如发生碰撞则不允许向右
usingPosition.x--
return
}
else{
usingSp.x=usingPosition.x*a
}
}
private function down(){
usingPosition.y++
if(hit(usingGrid)){//检测下一状是否碰撞,如发生碰撞则方块锁定位置
usingPosition.y--
lockPlace()
}
usingSp.y=usingPosition.y*a
}
private function lockPlace():void{
var max:uint=usingGrid.length
var i:int,j:int
for(i=0;i<max;i++){
for(j=0;j<max;j++){
if(usingGrid[i][j]){
rongqi[usingPosition.x+i][usingPosition.y+j]=1
}
}
}
for(i=0;i<kuan;i++){//绘制背景方块
for(j=0;j<gao;j++){
if(rongqi[i][j]){
drawAGrid(this,i,j,0,0,a,a,0xff00ff)
}
}
}
usingSp.graphics.clear()
this.removeChild(usingSp)
usingSp=null
for(j=0;j<max;j++){
checkLine(usingPosition.y+j)
}
startGrid()
}
private function checkLine(index:uint):void{//检查某行是否通了,如果通了,则消除
for(var i:uint=0;i<kuan;i++){//检测是否已通,不通就直接返回
if(!rongqi[i][index])return
}
for(i=0;i<kuan;i++){//通则处理掉这一行
rongqi[i].splice(index,1)
rongqi[i].unshift(0)
}
addScore()
reDraw()
}
private function reDraw():void{//发生通行时,重绘地图
this.graphics.clear()
var i:int,j:int
for(i=0;i<kuan;i++)
{// 绘制背景方块
for(j=0;j<gao;j++)
{
if(rongqi[i][j])
drawAGrid(this,i,j,0,0,a,a,0xffff00)
else
drawAGrid(this,i,j,0,0,a,a-1,0x66ffff)
}
}
for(i=0;i<nextBgkuan;i++)
{// 绘制背景方块
for(j=0;j<nextBggao;j++)
{
if(rongqiNext[i][j])
drawAGrid(this,i,j,360,200,nextBgbc,nextBgbc,0x0bb0bb)
else
drawAGrid(this,i,j,360,200,nextBgbc,nextBgbc-1,0xff00ff)
}
}
}
private function roll():void
{
var ar:Array=[]//产生一个新的,逆时针旋转后的方块
var max:uint=usingGrid.length
var i:uint,j:uint
for(i=0;i<max;i++){
ar[i]=[]
}
for(i=0;i<max;i++){//旋转
for(j=0;j<max;j++){
ar[j][max-i-1]=usingGrid[i][j]
}
}
if(hit(ar))return//检测是否碰撞,如发生碰撞则不允许旋转
usingSp.graphics.clear()
for(i=0;i<max;i++){
for(j=0;j<max;j++){
if(ar[i][j]==1){
drawAGrid(usingSp,i,j,0,0,a,a,0x0000ff)
}
}
}
usingGrid=ar
}
private function hit(ar:Array):Boolean{//碰撞测试
var max:uint=ar.length
var i:int,j:int
for(i=0;i<max;i++){
for(j=0;j<max;j++){
if(ar[i][j]){
if(usingPosition.x+i<0||usingPosition.x+i>=kuan)return true//超出边界,则返回true
if(usingPosition.y+j<0||usingPosition.y+j>=gao)return true
if(rongqi[usingPosition.x+i][usingPosition.y+j])return true //与物体有重叠,则返回true
}
}
}
return false
}
private function getType():void{
type.push([[0,0,1],[1,1,1],[0,0,0]]);//钩子
type.push([[0,0,0],[1,1,1],[0,0,1]]);//倒钩
type.push([[1,1],[1,1]]);//小方块
type.push([[0,0,0,0],[1,1,1,1],[0,0,0,0],[0,0,0,0]]);//长条
type.push([[0,1,0],[1,1,0],[0,1,0]]);//星
type.push([[1,0,0],[1,1,0],[0,1,0]]);//Z字形
type.push([[0,1,0],[1,1,0],[1,0,0]]);//反Z字形
}
private function createGrid():void{//创建一个方块
var h:uint=int(Math.random()*type.length)//随机挑选一个方块类型
var max:uint=type[h].length
nextGrid=[]
while(max-->0){//当前方块等于这个类型(获得数组副本)
nextGrid.unshift(type[h][max].concat())
}
//drawnextBgGrid()//在方块层绘制当前方块
drawnextGrid()
}
private function drawnextGrid():void
{//画出下一方块
nextSp=new Sprite
this.addChild(nextSp)
var i:int,j:int
var max:uint=nextGrid.length
for(i=0;i<max;i++)
{
for(j=0;j<max;j++)
{
if(nextGrid[i][j]==1)
{
nextSp.graphics.beginFill(0x0000ff)
nextSp.graphics.drawRect(i*nextBgbc,j*nextBgbc,nextBgbc,nextBgbc)
nextSp.graphics.endFill()
nextSp.x = 360
nextSp.y = 200
}
}
}
}
private function startGrid():void
{//将一个预备中的方块转为正在使用的方块
usingSp= nextSp
nextSp=null
usingGrid=nextGrid
var i,j:int=0;
var max:uint=usingGrid.length
usingSp.graphics.clear()
for(i=0;i<max;i++){
for(j=0;j<max;j++){
if(usingGrid[i][j]==1){
drawAGrid(usingSp,i,j,0,0,a,a,0x0000ff)
}
}
}
usingPosition=new Point((kuan-usingGrid.length)>>1,0)
usingSp.x=140
usingSp.y=600
createGrid()
if(hit(usingGrid))
{//如果方块一出来就发生碰撞,则判定游戏死亡
timer.stop()
stage.removeEventListener(KeyboardEvent.KEY_DOWN,onDown)
stage.removeEventListener(MouseEvent.CLICK,togglePause)
stage.addEventListener(MouseEvent.CLICK,onRestart)//点击鼠标,重新开始游戏
}
}
private function onTimer(e:Event):void{//自由下落
down()
}
private function onRestart(e:MouseEvent):void{//重新开始游戏
stage.removeEventListener(MouseEvent.CLICK,onRestart)
score=0//积分清零
txt.text="0"
timer=new Timer(1000)
timer.start()
timer.addEventListener(TimerEvent.TIMER,onTimer)
stage.addEventListener(KeyboardEvent.KEY_DOWN,onDown)
init()
reDraw()
stage.addEventListener(MouseEvent.CLICK,togglePause)
}
}
}