AS3拼图游戏解析

 

看了份拼图游戏代码,挺有收获。

 

基本原理:

  • 读取一张图片,切割成小片,按顺序排上位置(XY)。然后打乱
  • 监视MOUSEDOWN事件,当鼠标按下时判断和该切片相连的其他切片,找出来后加到drag数据
  • 监视MOUSEMOVE时间,drag数组中的切片跟随鼠标移动,造成拖拽效果
  • 监视MOUSEUP时间,将DRAG数据中切片移动到设定网格内(类似粘合效果)
  • 通过判断切片们的位置判断游戏结束

难点在于有效的算法求出与某切片相连接的其他切片的集合。

 

切割图片代码:

var bitmap:Bitmap = new Bitmap(new BitmapData(w,h));
var rectangle:Rectangle = new Rectangle(x,y,w,h);
bitmap.bitmapData.copyPixels(fromBitmapData,rectangle,new Point(0,1));
//添加到sprite
sprite.addChild(bitmap);

 

判断相连切片合集,看了好久才弄懂。

 首先求出其他切片与被求切片I的距离,推进数组。

 由大致小排序,妙。

 设置标记为假,开始循环

 -- 依次取出切片(按距离由大到小),判断上下左右4方向是否有标记为DRAG的切片连接

 -- 如果存在,推入DRAG数组,移除在被循环数组的位置,设置标记为真

 -- 标记为真,继续循环

 

 由于是从大到小的顺序,如果存在相连切片,推入DRAG的顺序肯定是先找到和原始切片连接的,然后再一层层找到与之连接的切片。比我想到的用搜索的笨方法简便了许多,赞。

		// find pieces that should move together
		public function findLockedPieces(clickedPiece:uint, clickLoc:Point) {
			// get list of puzzle objects sorted by distance to the clicked object
			var sortedObjects:Array = new Array();
			for (var i in puzzleObjects) {
				if (i == clickedPiece) continue;
				sortedObjects.push({dist: Point.distance(puzzleObjects[clickedPiece].loc,puzzleObjects[i].loc), num: i});
			}
			sortedObjects.sortOn("dist",Array.DESCENDING);
			
			// loop until all linked piece found
			do {
				var oneLinkFound:Boolean = false;
				// look at each object, starting with closest
				for(i=sortedObjects.length-1;i>=0;i--) {
					var n:uint = sortedObjects[i].num; // actual object number
					// get the position relative to the clicked object
					var diffX:int = puzzleObjects[n].loc.x - puzzleObjects[clickedPiece].loc.x;
					var diffY:int = puzzleObjects[n].loc.y - puzzleObjects[clickedPiece].loc.y;
					// see if this object is appropriately placed to be locked to the clicked one
					if (puzzleObjects[n].piece.x == (puzzleObjects[clickedPiece].piece.x + pieceWidth*diffX)) {
						if (puzzleObjects[n].piece.y == (puzzleObjects[clickedPiece].piece.y + pieceHeight*diffY)) {
							// see if this object is adjacent to one already selected
							if (isConnected(puzzleObjects[n])) {
								// add to selection list and set offset
								beingDragged.push(puzzleObjects[n]);
								puzzleObjects[n].dragOffset = new Point(clickLoc.x - puzzleObjects[n].piece.x, clickLoc.y - puzzleObjects[n].piece.y);
								// move to top sprite
								selectedPieces.addChild(puzzleObjects[n].piece);
								// link found, remove from array
								oneLinkFound = true;
								sortedObjects.splice(i,1);
							}
						}
					}
				}
			} while (oneLinkFound);
		}
		
		// takes an object and determines if it is directly next to one already selected
		public function isConnected(newPuzzleObject:Object):Boolean {
			for(var i in beingDragged) {
				var horizDist:int = Math.abs(newPuzzleObject.loc.x - beingDragged[i].loc.x);
				var vertDist:int = Math.abs(newPuzzleObject.loc.y - beingDragged[i].loc.y);
				if ((horizDist == 1) && (vertDist == 0)) return true;
				if ((horizDist == 0) && (vertDist == 1)) return true;
			}
			return false;
		}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值