俄罗斯方块

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;
	
	public class grid extends MovieClip {
		
		private var a:uint=20//方块边长
		private var kuan:uint=24//地图宽
		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 timer:Timer=new Timer(1000)
		private var txt:TextField//用于显示分数的文本框
		private var score:uint=0//分数(通关行数)
		private var levelUp:uint=10//每通关多少行升级
		public function grid() {
			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=450
			this.addChild(txt)
			txt.text="0"
			txt.selectable=false
		}
		private function togglePause(e:MouseEvent):void{//点击暂停游戏
			if(timer.running)timer.stop()
			else timer.start()
		}
		private function init(){//初始化地图
			var i:int,j:int
			var l:uint=a-1
			for(i=0;i<kuan;i++){// 绘制背景方块,供测试者观看
				rongqi[i]=[]
				for(j=0;j<gao;j++){					
					rongqi[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*100)
				timer.addEventListener(TimerEvent.TIMER,onTimer)
				timer.start()//定时下沉
			}
		}
		private function drawAGrid(mc:Sprite,i:int,j:int,aa:int,color:uint):void{
			mc.graphics.beginFill(color)
			mc.graphics.drawRect(i*a,j*a,aa,aa)
			mc.graphics.endFill()
		}
		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 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,a,0xffff00)
					}
				}
			}
			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,a,0xffff00)
					else drawAGrid(this,i,j,a-1,0xff0000)
				}
			}
		}
		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,a,0x00ff00)
					}
				}
			}
			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 i:uint=int(Math.random()*type.length)//随机挑选一个方块类型
			var max:uint=type[i].length
			nextGrid=[]
			while(max-->0){//当前方块等于这个类型(获得数组副本)
				nextGrid.unshift(type[i][max].concat())
			}
			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(0x00ff00)
						nextSp.graphics.drawRect(i*a,j*a,a,a)
						nextSp.graphics.endFill()
					}
				}
			}
		}
		private function startGrid():void{//将一个预备中的方块转为正在使用的方块
			usingSp=nextSp
			nextSp=null
			usingGrid=nextGrid
			usingPosition=new Point((kuan-usingGrid.length)>>1,0)
			usingSp.x=usingPosition.x*a
			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)
		}
	}	
}

  

posted @ 2012-11-09 20:09  小糊涂仙儿  阅读(242)  评论(0编辑  收藏  举报