俄罗斯方块程序分析

来源:互联网 发布:淘宝卖的最贵的东西 编辑:程序博客网 时间:2024/06/03 08:18
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)
        }
    }    
}
原创粉丝点击