flash 3.0拼图游戏

 

 

package {
	import flash.display.*;
	import flash.events.*;
	import flash.net.URLRequest;
	import flash.geom.*;
	import flash.utils.Timer;
	
	public class JigsawPuzzle extends MovieClip {
		// 小块数量
		const numPiecesHoriz:int = 8;
		const numPiecesVert:int = 6;
		
		// 小块尺寸
		var pieceWidth:Number;
		var pieceHeight:Number;

		// 游戏小块储存对象
		var puzzleObjects:Array;
		
		// 两类sprite
		var selectedPieces:Sprite;//储存被拖拽的所有小块
		var otherPieces:Sprite;//没被拖拽所有小块
		
		// 被拖拽的小块
		var beingDragged:Array  = new Array();
		
		// 导入图像 设置sprite
		public function startJigsawPuzzle() {
			// 导入图像
			loadBitmap("jigsawimage.jpg");
			
			// 设置两个 sprites
			otherPieces = new Sprite();
			selectedPieces = new Sprite();
			addChild(otherPieces);
			addChild(selectedPieces); // 放在顶部
		}
		
		// 从外部获得位图
		public function loadBitmap(bitmapFile:String) {
			var loader:Loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadingDone);
			var request:URLRequest = new URLRequest(bitmapFile);
			loader.load(request);
		}
		
		// 位图导入完成 切成小块
		private function loadingDone(event:Event):void {
			// 创建新的的图像来放置位图
			var image:Bitmap = Bitmap(event.target.loader.content);
			pieceWidth = Math.floor((image.width/numPiecesHoriz)/10)*10;
			pieceHeight = Math.floor((image.height/numPiecesVert)/10)*10;
			
			// 将导入的位图放入image类中
			var bitmapData:BitmapData = image.bitmapData;
			
			// 切割成拼图小块
			makePuzzlePieces(bitmapData);
			
			// 设置移动和鼠标事件
			addEventListener(Event.ENTER_FRAME,movePieces);
			stage.addEventListener(MouseEvent.MOUSE_UP,liftMouseUp);
		}
		
		// 将位图切成小片
		private function makePuzzlePieces(bitmapData:BitmapData) {
			puzzleObjects = new Array();
			for(var x:uint=0;x<numPiecesHoriz;x++) {
				for (var y:uint=0;y<numPiecesVert;y++) {
					// 创建新的小块bitmap和sprite
					var newPuzzlePieceBitmap:Bitmap = new Bitmap(new BitmapData(pieceWidth,pieceHeight));
					newPuzzlePieceBitmap.bitmapData.copyPixels(bitmapData,new Rectangle(x*pieceWidth,y*pieceHeight,pieceWidth,pieceHeight),new Point(0,0));
					var newPuzzlePiece:Sprite = new Sprite();
					newPuzzlePiece.addChild(newPuzzlePieceBitmap);
					
					// 放置在底部的sprite中(没被拖拽)
					otherPieces.addChild(newPuzzlePiece);
					
					// 创建对象 储存在数组中
					var newPuzzleObject:Object = new Object();
					newPuzzleObject.loc = new Point(x,y); // 拼图中的位置
					newPuzzleObject.dragOffset = null; // 光标偏移量
					newPuzzleObject.piece = newPuzzlePiece;
					newPuzzlePiece.addEventListener(MouseEvent.MOUSE_DOWN,clickPuzzlePiece);
					puzzleObjects.push(newPuzzleObject);
				}
			}
			
			// 随机放置拼图小块
			shufflePieces();
			
		}
		
		// 小块的随机位置
		public function shufflePieces() {
			// 选取随机的x和y
			for(var i in puzzleObjects) {
				puzzleObjects[i].piece.x = Math.random()*400+50;
				puzzleObjects[i].piece.y = Math.random()*250+50;
			}
			// 将所有小块约束在10*10的小格内
			lockPiecesToGrid();
		}
		
		public function clickPuzzlePiece(event:MouseEvent) {
			// 单击位置
			var clickLoc:Point = new Point(event.stageX, event.stageY);
			
			beingDragged = new Array();
			
			//找到点击的小块
			for(var i in puzzleObjects) {
				if (puzzleObjects[i].piece == event.currentTarget) { // this is it
					// 添加到拖拽数组
					beingDragged.push(puzzleObjects[i]);
					// 得到偏移值    (单击位置与小块的距离) 
					puzzleObjects[i].dragOffset = new Point(clickLoc.x - puzzleObjects[i].piece.x, clickLoc.y - puzzleObjects[i].piece.y);
					// 底部移动到顶部
					selectedPieces.addChild(puzzleObjects[i].piece);
					// 找到和当前小块锁定的小块
					findLockedPieces(i,clickLoc);
					break;
				}
			}
		}
		
		// 根据鼠标位置移动所有选择的小块
		public function movePieces(event:Event) {
			for (var i in beingDragged) {
				beingDragged[i].piece.x = mouseX - beingDragged[i].dragOffset.x;
				beingDragged[i].piece.y = mouseY - beingDragged[i].dragOffset.y;
			}
		}

		// 找出一起移动的小块
		public function findLockedPieces(clickedPiece:uint, clickLoc:Point) {
			// 创建一个数组,保存所有小块对象(除了被单击的小块),以距离排序
			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);
			
			// 直到发现所有的小块连接上循环中止
			do {
				//发现连接就设置为ture,若遍历所有未连接的小块,却没有发现连接,则说明我们已经找到了连接的小块,否则继续循环。
				var oneLinkFound:Boolean = false;
				// 查看所有的小块 从最近的开始
				for(i=sortedObjects.length-1;i>=0;i--) {
					var n:uint = sortedObjects[i].num; //实际的小块编号
					// 得到与被单击小块之间的相对位置
					var diffX:int = puzzleObjects[n].loc.x - puzzleObjects[clickedPiece].loc.x;
					var diffY:int = puzzleObjects[n].loc.y - puzzleObjects[clickedPiece].loc.y;
					// 查看该对象是否放置正确以连接在被单击的小块上
					if (puzzleObjects[n].piece.x == (puzzleObjects[clickedPiece].piece.x + pieceWidth*diffX)) {
						if (puzzleObjects[n].piece.y == (puzzleObjects[clickedPiece].piece.y + pieceHeight*diffY)) {
							//查看当前对象是否与被选择的对象相邻
							if (isConnected(puzzleObjects[n])) {
								// 添加进选择列表,并设置偏移量
								beingDragged.push(puzzleObjects[n]);
								puzzleObjects[n].dragOffset = new Point(clickLoc.x - puzzleObjects[n].piece.x, clickLoc.y - puzzleObjects[n].piece.y);
								// 移动到顶部的 sprite
								selectedPieces.addChild(puzzleObjects[n].piece);
								// 发现连接,从数组中移除
								oneLinkFound = true;
								sortedObjects.splice(i,1);
							}
						}
					}
				}
			} while (oneLinkFound);
		}
		
		// 得到一个小块,并判断是否与已选择的小块相邻
		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;
		}
		
		// 舞台发出鼠标释放事件,拖拽结束
		public function liftMouseUp(event:MouseEvent) {
			// 约束所有的小块
			lockPiecesToGrid();
			// 将小块移回到底部
			for(var i in beingDragged) {
				otherPieces.addChild(beingDragged[i].piece);
			}
			// 清除拖拽的数组
			beingDragged = new Array();
			
			// 判断游戏是否结束
			if (puzzleTogether()) {
				cleanUpJigsaw();
				gotoAndStop("gameover");
			}
		}
		
		// 将所有的拼图放置在最接近的10*10的位置上
		public function lockPiecesToGrid() {
			for(var i in puzzleObjects) {
				puzzleObjects[i].piece.x = 10*Math.round(puzzleObjects[i].piece.x/10);
				puzzleObjects[i].piece.y = 10*Math.round(puzzleObjects[i].piece.y/10);
			}
		}
		
		public function puzzleTogether():Boolean {
			for(var i:uint=1;i<puzzleObjects.length;i++) {
				// 得到与第一个对象相邻的相对距离
				var diffX:int = puzzleObjects[i].loc.x - puzzleObjects[0].loc.x;
				var diffY:int = puzzleObjects[i].loc.y - puzzleObjects[0].loc.y;
				// 查看该对象是否放置正确以与第一个对象链接
				if (puzzleObjects[i].piece.x != (puzzleObjects[0].piece.x + pieceWidth*diffX)) return false;
				if (puzzleObjects[i].piece.y != (puzzleObjects[0].piece.y + pieceHeight*diffY)) return false
			}
			return true;
		}
					
		public function cleanUpJigsaw() {
			removeChild(selectedPieces);
			removeChild(otherPieces);
			selectedPieces = null;
			otherPieces = null;
			puzzleObjects = null;
			beingDragged = null;
			removeEventListener(Event.ENTER_FRAME,movePieces);
			stage.removeEventListener(MouseEvent.MOUSE_UP,liftMouseUp);
		}
		
	}
}


 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值