1. 程式人生 > >用as3.0寫的簡單的三消遊戲demo

用as3.0寫的簡單的三消遊戲demo

在學習as十一天之後<span style="font-family: Arial, Helvetica, sans-serif;">(其實是從一開始就直接開始寫,然後邊寫邊學)</span>,這是一個三消類遊戲,在400*300大小的區域內隨機生成8*6個小方格(顏色隨機)。目前實現了移動,消除,填充。
遊戲現在還有bug,其一是方塊在下落的過程中不能移動其他方塊,否則會停止移動或則其他狀態(解決方案是,當方塊在下落的時候,用一個標記標記方塊正在下落,例如is_down,當標記標記在下落時,則不能進行其他操作),其二是右下角的那一個方塊不能夠移動,只能夠被移動和消除(我也不知道是什麼原因,邊境問題?看了好久程式碼都發現什麼問題,有大神有空的話可以幫忙找一下<img alt="大笑" src="http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif" />)。對於這一行來說,有bug就是不行的——嚴謹。但是遊戲還是能玩,只要心平氣和的玩。
下面提供原始碼吧,註釋我也寫的挺多的,希望大家能夠指出我的錯誤,謝謝。希望和我一樣的小白,大家一起學習!!<img alt="奮鬥" src="http://static.blog.csdn.net/xheditor/xheditor_emot/default/struggle.gif" /><img alt="奮鬥" src="http://static.blog.csdn.net/xheditor/xheditor_emot/default/struggle.gif" /><img alt="奮鬥" src="http://static.blog.csdn.net/xheditor/xheditor_emot/default/struggle.gif" />
ps:如果重新填充後出現了可以消除的,需要滑鼠點選方塊區域才能消失(沒寫出來補齊後再消除)
pps:下面有個連結,裡面的文章對我有一定的啟發作用,希望能幫助大家!
///////////-----------我是分割線--------------------//////////////
<pre name="code" class="html">package
{
	import com.greensock.TweenLite;
	
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.text.TextField;

	public class ClearGame extends Sprite
	{
		private const mapHeigth:int=6;//方塊y軸上的個數
		private const mapWeigth:int=8;//方塊 x軸上的個數
		private var colorArray:Array=[0xff0000,0xff9900,0xffff00,0x00ff00,0x00ffff,0x0000ff];//顏色陣列,建立方塊時隨機填充顏色
		private var colorNum:int;//顏色的編號
		private var R:int=48;//方塊的邊長
		private var objectVector:Vector.<Object>=new Vector.<Object>;//存放方塊顏色
		private var visitedColorArray:Array=new Array();//存放移動過的顏色
		private var visitedPathArray:Vector.<Point>=new Vector.<Point>;//存放欲動過的陣列位子
		private var clearArray:Vector.<Point>=new Vector.<Point>;//存放要消除的方塊的座標
		private var rectObject:Array=new Array();//方塊物件
		private var zero:int=10;//如果方塊被消除,那麼將他的name賦值為zero
		private var sorce:int=0;//初始化分數為0
		//private var is_complete:Boolean=true;//重新生成是否完成

		public function ClearGame()
		{
			//設定舞臺為左上角對齊
			stage.align=StageAlign.TOP_LEFT;
			//迴圈建立方塊
			for(var i:int=0;i<mapWeigth;i++){
				objectVector[i]=new Vector.<Object>;
				for(var j:int=0;j<mapHeigth;j++){
					draw(i,j);
					//i,j值對應方塊的座標,objectVector存放顏色資訊
					objectVector[i][j]=colorNum;
				}
			}
			//開始消除
			clear();
			//trace("第一個消除");
			//新增滑鼠監聽事件
			stage.addEventListener(MouseEvent.MOUSE_DOWN,rectEvent);
			stage.addEventListener(MouseEvent.MOUSE_UP,rectEvent);
		}
		//建立方塊
		private function draw(i:int,j:int):int
		{
			var rect:Sprite=new Sprite();//小方塊
			//隨機生成1-mapHeigth,代表顏色,用來判定顏色是否相同
			colorNum=Math.ceil(Math.random()*mapHeigth-1);
			rect.graphics.beginFill(colorArray[colorNum]);
			rect.graphics.drawRect(0,0,R,R);
			rect.x=50*i;
			rect.y=50*j;
			rect.graphics.endFill();
			rect.buttonMode=true;
			addChildAt(rect,(mapHeigth*i+j));
			rectObject.push(rect);
			return colorNum;
		}
		//變換方塊位子函式
		private function rectEvent(e:Event):void
		{
			//獲得方塊的陣列座標
			var i:Number=Math.ceil((mouseX-50)/50);
			var j:Number=Math.ceil((mouseY-50)/50);
			if(e.type==MouseEvent.MOUSE_DOWN){
				rectObject[mapHeigth*i+j].startDrag();
				//將第一個位子座標存入
				if(visitedPathArray.length==0||visitedPathArray[visitedPathArray.length-1].x!=i||visitedPathArray[visitedPathArray.length-1].y!=j){
					visitedPathArray.push(new Point(i,j));
				}
				//將方塊的顏色值存入
				visitedColorArray.push(objectVector[i][j]);
			}
			if(e.type==MouseEvent.MOUSE_UP){
				//使對應的方塊可以移動
				rectObject[mapHeigth*i+j].stopDrag();
				//獲得第二個方塊的陣列座標
				var m:Number=Math.ceil((mouseX-50)/50);
				var n:Number=Math.ceil((mouseY-50)/50);
				//比較兩次滑鼠點選的位子,如果沒有變化,方塊不移動
				if(visitedPathArray[0].x==m && visitedPathArray[0].y==n){
					removeChild(rectObject[m*mapHeigth+n]);
					afterDraw(m,n,objectVector[m][n]);
				}
				else{
					//將第二個位子座標存入
					if(visitedPathArray.length==0||visitedPathArray[visitedPathArray.length-1].x!=m||visitedPathArray[visitedPathArray.length-1].y!=n){
						visitedPathArray.push(new Point(m,n));
					}
					//將方塊的顏色值存入
					visitedColorArray.push(objectVector[m][n]);
					//只能將方塊上下左右個移動一格
					if( isClose(visitedPathArray[0].x,visitedPathArray[0].y,visitedPathArray[1].x,visitedPathArray[1].y)==true ){
						//移除兩個將要交換的方塊
						removeChild(rectObject[mapHeigth*visitedPathArray[0].x+visitedPathArray[0].y]);
						removeChild(rectObject[mapHeigth*visitedPathArray[1].x+visitedPathArray[1].y]);
						//根據座標和顏色重新繪製方塊
						afterDraw(visitedPathArray[0].x,visitedPathArray[0].y,visitedColorArray[1]);
						afterDraw(visitedPathArray[1].x,visitedPathArray[1].y,visitedColorArray[0]);
					}else{
						//讓拖動的方塊回到原位
						removeChild(rectObject[mapHeigth*visitedPathArray[0].x+visitedPathArray[0].y]);
						afterDraw(visitedPathArray[0].x,visitedPathArray[0].y,visitedColorArray[0]);
					}
					//判斷移動後可以消除才能拖動方塊交換位子
					if(isClearX()==false && isClearY()==false){
					//trace("不能交換位子!");
					//移除兩個將要交換的方塊
					removeChild(rectObject[mapHeigth*visitedPathArray[0].x+visitedPathArray[0].y]);
					removeChild(rectObject[mapHeigth*visitedPathArray[1].x+visitedPathArray[1].y]);
					//根據座標和顏色重新繪製方塊
					afterDraw(visitedPathArray[0].x,visitedPathArray[0].y,visitedColorArray[0]);
					afterDraw(visitedPathArray[1].x,visitedPathArray[1].y,visitedColorArray[1]);	
					}	
				}
				//消除顏色相同的方塊
				//trace("準備消除");
				clear();
				//trace("第二個消除");
				//重置戰士存放方塊資訊的空間
				visitedPathArray=new Vector.<Point>;
				visitedColorArray=new Array;
			}
		}
		//判斷兩個小方塊是否是臨接的
		private function isClose(x1:int,y1:int,x2:int,y2:int):Boolean
		{
			var flag:int=0;//設定標示
			if((x1==x2&&y1==y2-1)||(x1==x2&&y1==y2+1)||(x1==x2-1&&y1==y2)||(x1==x2+1&&y1==y2)){
				flag=1;
			}
			if(flag==1)
				return true;
			else
				return false;
		}
		//判斷x方向上是否可以消除,可以消除返回true
		private function isClearX():Boolean
		{
			var flag:int=0;//設定標誌位
			for(var j:int=0;j<mapHeigth;j++){
				for(var i:int=0;i<mapWeigth-2;i++){
					if(objectVector[i][j]==objectVector[i+1][j] && objectVector[i][j]==objectVector[i+2][j]){
						flag=1;
						break;
					}
				}
			}
			if(flag==1)
				return true;
			return false;
		}
		//判斷y方向上是否可以消除,可以消除返回true
		private function isClearY():Boolean
		{
			var flag:int=0;//設定標誌位
			for(var i:int=0;i<mapWeigth;i++){
				for(var j:int=0;j<mapHeigth-2;j++){
					if(objectVector[i][j]==objectVector[i][j+1] && objectVector[i][j]==objectVector[i][j+2]){
						flag=1;
						break;
					}
				}
			}
			if(flag==1)
				return true;
			return false;
		}
		//根據方塊座標建立方塊物件
		private function afterDraw(i:int,j:int,color:int):void
		{
			var rect:Sprite=new Sprite();
			rect.graphics.beginFill(colorArray[color]);
			rect.graphics.drawRect(0,0,R,R);
			rect.graphics.endFill();
			rect.x=50*i;
			rect.y=50*j;
			rect.buttonMode=true;
			addChildAt(rect,(mapHeigth*i+j));
			rectObject[mapHeigth*i+j]=rect;
			objectVector[i][j]=color;
		}
		private function sorceNum(a:Vector.<Point>):void
		{
			//基礎得分,每一個格子加一分
			sorce+=a.length;	
			//額外得分
			if(clearArray.length>=4)
				sorce+=1;
			if(clearArray.length>=5)
				sorce+=1;
			if(clearArray.length>=6)
				sorce+=1;
			var myText:TextField=new TextField();
			myText.x=500;
			myText.y=50;
			myText.text=String(sorce);
			addChild(myText);
		}
		//將待消除的方塊與陣列中的方塊比較,如果不相同則存入
		private function compare(x:int,y:int):void
		{
			//trace("開始對比");
			//如果當前陣列為空,則直接可以存入待消陣列
			if(clearArray.length==0){
				clearArray.push(new Point(x,y));
				//trace("第一個數");
			}
			else{
				var flag:int=1;
				for(var m:int=0;m<clearArray.length;m++){
					if(clearArray[m].x==x && clearArray[m].y==y){
						flag=0;
						break;
					}
				}
				while(flag==1){
					clearArray.push(new Point(x,y));
					//trace("存入");
					break;
				}	
			}
			for(var a:int=0;a<clearArray.length;a++){
				//trace(clearArray[a]);
			}
		}
		//對比方塊,三個顏色相同就將其放入待消除陣列中
		private function check():void
		{
			//將y方向上的連續三個相同的方塊存入待消除陣列
			for(var i:int=0;i<mapWeigth;i++){
				for(var j:int=0;j<mapHeigth-2;j++){
					if(objectVector[i][j]==objectVector[i][j+1] && objectVector[i][j]==objectVector[i][j+2]){
						compare(i,j);
						compare(i,j+1);
						compare(i,j+2);
						//trace("y");
					}
				}
			}
			//將x方向上的連續三個相同的方塊存入待消除陣列
			for(var j:int=0;j<mapHeigth;j++){
				for(var i:int=0;i<mapWeigth-2;i++){
					if(objectVector[i][j]==objectVector[i+1][j] && objectVector[i][j]==objectVector[i+2][j]){
						compare(i,j);
						compare(i+1,j);
						compare(i+2,j);
						//trace("x");
					}
				}
			}		
		}
		//消除函式
		private function clear():void
		{
			//查詢橫,豎三個及以上顏色相同的方塊,存入待消除陣列
			check();
			for(var m:int=0;m<clearArray.length;m++){
				removeChild(rectObject[mapHeigth*clearArray[m].x+clearArray[m].y]);
				//將消除了的方塊的顏色標誌置zero
				objectVector[clearArray[m].x][clearArray[m].y]=zero;
				//trace("消除");
			}
			//清空待消除數組裡面的元素
			sorceNum(clearArray);
			clearArray=new Vector.<Point>;
			rectDown();
		}
		//方塊下落函式和方塊補齊函式
		private function rectDown():void
		{
			var rectDownNum:int=0;
			for(var i:int=0;i<mapWeigth;i++){
				if(objectVector[i][mapHeigth-1]==zero)
					rectDownNum+=1;
				for(var j:int=mapHeigth-2;j>=0;j--){
					if(objectVector[i][j]==zero){
						rectDownNum+=1;
					}
					else{
						//緩動操作,使方塊下落
						TweenLite.to(rectObject[mapHeigth*i+j],1,{y:50*rectDownNum+rectObject[mapHeigth*i+j].y});
						rectObject[mapHeigth*i+j+rectDownNum]=rectObject[mapHeigth*i+j];
						objectVector[i][j+rectDownNum]=objectVector[i][j];
					}
				}
				//補齊下落後上面空著的方塊
				for(var m:int=0;m<rectDownNum;m++){
					var num:int=Math.ceil(Math.random()*6-1);
					TweenLite.delayedCall(1,afterDraw,[i,m,num]);
					objectVector[i][m]=num;
				}
				rectDownNum=0;
			}
		}
	}
}