`
qiqishou
  • 浏览: 85221 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【原创】连连看Flex版设计与实现

    博客分类:
  • flex
阅读更多

      前一阵子为了练手,写了一个连连看的小游戏,主要的设计为棋盘类,位置类,棋子类,核心算法包,一些自定义事件和资源类。我称连连看中被点击的按钮为棋子,下面那个看不见的布局要用的东西我成为棋盘。这样设计一个小游戏主要也是为了降低耦合性,每个部分可以比较独立的变化而不影响其他的部分。比如,棋子随意变,棋盘也可以变为圆形,甚至五角星的,只要改变一个字段就可以方便的更改棋子的皮肤或者音乐。

      核心算法主要写了一个随机分配的算法,就是保证每次玩的时候最后都要正好能全部消灭。连连看的死局这里暂时没有考虑。还有一个就是把判断两个棋子是否可以消除,我没有用网上介绍的递归算法,我用的“十字通路法”,我自己起的名字哈。我想这样来解释会清楚一些:

十字通路:

每个棋子拥有一个十字通路,就是它可以到达的上下左右,可以到达的意思就是路过的位置是空的或者是不可见的,类似一个十字一样。当然也可能不是“十”字,或者是个"T",总之就是遍历上下左右,碰壁为止,并整理记录下来X轴通路和Y轴通路。

判断两个棋子是否可以消除的条件:

1.两个棋子的图案必须要相同。

2.两个棋子最多通过两次“拐弯”可以到达。理解成我所谓的十字通路就是两个棋子的X(Y)轴通路可以直线相连。

以下是我用来测试的代码

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
				creationComplete="init()"
				layout="vertical"
				width="100%"
				height="100%"
				backgroundGradientAlphas="[0.8, 0.9]"
				backgroundGradientColors="[#736D6D, #070707]"
				xmlns:ns1="*"
				xmlns:ns2="com.chess.*"
				xmlns:ns3="com.board.*">
				<mx:Style source="myCSS.css"/>
	<mx:Script>
		<![CDATA[
			import mx.events.CloseEvent;
			import mx.core.UIComponent;
			import mx.controls.Alert;
			import com.coreAlg.CheckBoard;
			import com.coreAlg.connect.Connect;
			import com.coreAlg.connect.GetCross;
			import embed.embedImage.EtImage;
			import com.board.Board;
			import com.chess.Chess;
			import mx.containers.HBox;
			import MyEvent.MyClickEvent;
			import com.position.Position;
			import mx.containers.Canvas;
			import embed.embedSound.HappySound;
			//private var position:Position;
			private var board:Board=new Board();
			public var eee:EtImage=EtImage.getInstance(); //图片资源类
			//程序里有个缓冲区
			private var firstImageSource:Class=null; //上一个棋子的图片源
			private var firstX:int=-1; //上一个棋子的X坐标
			private var firstY:int=-1; //上一个棋子的Y坐标
			private var tempImageSource:Class=null; //储存刚刚点击棋子的图片源
			private var tempX:int=-1; //储存刚刚点击棋子的X坐标
			private var tempY:int=-1; //储存刚刚点击棋子的Y坐标
			private var getc:GetCross=GetCross.getInstance();
			private var conn:Connect=Connect.getInstance();
			private var check:CheckBoard=CheckBoard.getInstance();
			private var pan:UIComponent=new UIComponent(); //画路径的画笔
			private var sound:HappySound=HappySound.getInstance();
			private var pathArray:Array;
			private var pathPan:UIComponent=new UIComponent();
			private var pathTimer:Timer=new Timer(50);
			private var myTimer:Timer=new Timer(1000);
			private var totalTime:int=0;
			private var xN:int = 6;
			private var yN:int = 5;

			//private var board:Board;
			private function init():void
			{
				board.xNum=xN; //宽
				board.yNum=yN; //高
				board.nkind=5; //图案种数
				board.x=0;
				board.y=0;
				myCanvas.addChild(board);
				myCanvas.addChild(pan);
				MyClickEvent.dispatcher.addEventListener(MyClickEvent.CLICK_IMAGE, clickHandler);
				this.addEventListener(MyClickEvent.CLICK_IMAGE, clickHandler);
				myTimer.start();
				myTimer.addEventListener(TimerEvent.TIMER, onTimer);
			}

			private function onTimer(event:TimerEvent):void
			{
				totalTime++;
			}

			private function alertClickHandler(event:CloseEvent):Boolean
			{
				if (event.detail == Alert.OK)
				{
					xN += 2;
					yN += 2;
					if(xN > 10)
					{
						Alert.show('thank u 4 play~!');
						return false;
					}
					myTimer.stop();
					myTimer.start();
					myCanvas.removeChild(board);
					board=new Board();
					trace('board.chessCompleted:'+board.chessCompleted);
					board.xNum=xN; //宽
					board.yNum=yN; //高
					board.nkind=xN; //图案种数
					board.x=0;
					board.y=0;
					myCanvas.addChild(board);
					return true;
				}
				return true;
			}

			private function clickHandler(event:MyClickEvent):void
			{
				tempX=event.x;
				tempY=event.y;
				var firPosition:Position=new Position(firstX, firstY);
				var secPosition:Position=new Position(tempX, tempY);
				//查看当前点击的通路数组
				/* trace('xCross:');
				var tttArray:Array=(getc.getCross((board.chessArray[event.y][event.x] as Chess), board)).getItemAt(0) as Array;
				for (var ttt:int=0; ttt < tttArray.length; ttt++)
				{
					trace((tttArray[ttt] as Position).xPosition + '  ' + (tttArray[ttt] as Position).yPosition);
				}
				tttArray=(getc.getCross((board.chessArray[event.y][event.x] as Chess), board)).getItemAt(1) as Array;
				trace('yCross:');
				for (ttt=0; ttt < tttArray.length; ttt++)
				{
					trace((tttArray[ttt] as Position).xPosition + '  ' + (tttArray[ttt] as Position).yPosition);
				} */
				tempImageSource=(board.chessArray[event.y][event.x] as Chess).imageSource;
				//如果缓存ID不为空 且 缓存ID和点击的目标不是同一个 且 缓存ID和目标ID有通路
				if ((isValidPosition(firstX, firstY)) && (!equalPosition(tempX, tempY, firstX, firstY)) && (conn.connect(board, firPosition, secPosition)))
				{

					//画出路径,并消除那两个棋子,再清空路径数组
					clearIcons.play([this]);
					(board.chessArray[tempY][tempX] as Chess).disAppearState();
					(board.chessArray[firstY][firstX] as Chess).disAppearState();
					board.chessCompleted += 2; 
					drawPath();
					//清空缓存
					firstX=-1;
					firstY=-1;
					firstImageSource=null;
					board.pathArray=new Array(); //清空path
					if (check.checkComplete(board))
					{
						mx.controls.Alert.show("congratulations~,难度"+xN+'乘以'+yN+"    一共用时" + totalTime+'秒', '', Alert.OK, this, alertClickHandler);
					}
				}
				else
				{
					//trace('最终匹配不成功');
					//trace('*************************************************');
					//没有匹配成功刷新缓存
					if (firstX != -1 && !equalPosition(tempX, tempY, firstX, firstY))
					{
						(board.chessArray[firstY][firstX] as Chess).normalState();
					}
					firstImageSource=tempImageSource;
					firstX=tempX;
					firstY=tempY;
						//	}
				}
			}

			private function equalImageSource(tm:Class, fir:Class):Boolean
			{
				if (tm == fir)
				{
					//trace('图片相等');
					return true;
				}
				//trace('图片不相等');
				return false;
			}

			private function isValidPosition(tx:int, ty:int):Boolean
			{
				if (tx >= 0 && ty >= 0)
				{
					//trace('横纵坐标都大于0');
					return true;
				}
				//trace('坐标小于0');
				//trace('firstX:'+firstX+'   '+'firstY:'+firstY);
				return false;
			}

			private function equalPosition(tx:int, ty:int, firx:int, firy:int):Boolean
			{
				if (tx == firx && ty == firy)
				{
					//trace('坐标相等');
					return true;
				}
				//trace('坐标不相等');
				return false;
			}

			private function drawPath():void
			{
				trace('board.pathArray.length:' + board.pathArray.length);
				pathTimer.start();
				pathArray=board.pathArray;
				board.pathArray=null;
				var step:Position=pathArray.shift() as Position;
				trace('path.length:' + pathArray.length);
				myCanvas.addChild(pathPan);
				pathPan.graphics.clear();
				pathPan.graphics.lineStyle(2, 0xFF0000);
				pathPan.graphics.moveTo(board.x + board.leftGap + (step.xPosition + 1) * (board.chessWidth + 2) - board.chessWidth / 2, board.y + board.topGap + (step.yPosition + 1) * (board.chessHeight + 2) - board.chessHeight / 2);

				pathTimer.addEventListener(TimerEvent.TIMER, drawLine)
				//pathPan.addEventListener(Event.ENTER_FRAME,drawLine);
			}

			private function drawLine(event:Event):void
			{
				if (pathArray.length > 0)
				{
					var step:Position=pathArray.shift() as Position;
					pathPan.graphics.lineTo(board.x + board.leftGap + (step.xPosition + 1) * (board.chessWidth + 2) - board.chessWidth / 2, board.y + board.topGap + (step.yPosition + 1) * (board.chessHeight + 2) - board.chessHeight / 2);
				}
				else
				{
					pathTimer.stop();
					//pathPan.removeEventListener(Event.ENTER_FRAME,drawLine);
					myCanvas.removeChild(pathPan);
				}
			}
		]]>
	</mx:Script>
	<mx:Canvas id="myCanvas"
			   width="100%"
			   height="100%">

	</mx:Canvas>
	<mx:SoundEffect id="clearIcons"
					duration="2000"
					source="{sound.clearSound}"/>
</mx:Application>

 

附件是测试对应的.swf,资源都内嵌了

3
1
分享到:
评论
7 楼 gglhappy 2014-08-22  
410631059@qq.com  楼主能给一下源码么
6 楼 gglhappy 2014-08-22  
楼主能给一下源码么 邮箱:410631059@qq.com
5 楼 chen024 2014-06-27  
求源码:我的邮箱chenfang65811395#126。com,(#=@  &&   。=.)
4 楼 htmldai 2012-06-21  
是我的邮箱。打错了。但是确实是无毒的。
3 楼 htmldai 2012-06-21  
求代码!!!楼主好人!!!无毒邮箱:395193253@qq.com
2 楼 qiqishou 2010-11-02  
QQ联系 649723623
1 楼 guowei422 2010-10-28  
你好,可以把这个连连看的源码发给我不?我现在有急用!谢谢! 邮箱是:guowei422@163.com

相关推荐

Global site tag (gtag.js) - Google Analytics