`
kinglong
  • 浏览: 32992 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

Flash游戏-SlidingPuzzle滑块拼图游戏

阅读更多
最近在研究Flash游戏的算法,发现同一种游戏能有很多种算法,而我比较喜欢面向对象和事件通知方式的算法,清清爽爽的程序结构。。。

[运行效果]

[FLASH=550,400,True]upload/SlidingPuzzle.swf[/FLASH]

[主程序类]
package {
	import com.klstudio.puzzles.slider.PuzzleBoard;

	import flash.display.Sprite;

	/**
	 * SlidingPuzzle
	 * @author Kinglong(kinglong@gmail.com)
	 * @since:2010-9-13
	 */
	public class SlidingPuzzle extends Sprite {
		[Embed(source="image.jpg")]
		private var embeddedImage : Class;
		
		private var _board:PuzzleBoard;
		public function SlidingPuzzle() {
			_board = new PuzzleBoard(300,300,4);
			addChild(_board);
			
			_board.createPuzzle(new embeddedImage());
			
			_board.startGame();
		}
	}
}

[PuzzleBoard类]
package com.klstudio.puzzles.slider {
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.display.Bitmap;
	import flash.geom.Matrix;
	import flash.display.BitmapData;
	import flash.display.Sprite;

	/**
	 * PuzzleBoard
	 * @author Kinglong(kinglong@gmail.com)
	 * @since:2010-9-13
	 */	

	public class PuzzleBoard extends Sprite {
		private var _pieces : Array;
		private var _moving : Boolean;
		private var _boardWidth : int;
		private var _boardHeight : int;
		private var _pieceWidth : Number;
		private var _pieceHeight : Number;
		private var _subdivisions : uint;
		private var _space : uint;
		private var _padding : uint;

		public function PuzzleBoard(width : uint,height : uint,subdivisions : uint = 3,padding : uint = 1,space : int = -1) {
			_pieces = [];
			_moving = true;
			
			_boardWidth = width;
			_boardHeight = height;
			_subdivisions = subdivisions = (subdivisions < 3) ? 3 : subdivisions;
			_space = (space < subdivisions * subdivisions && space > -1) ? space : subdivisions - 1; 
			_padding = padding;
			
			_pieceWidth = _boardWidth / subdivisions;
			_pieceHeight = _boardHeight / subdivisions;
		}

		public function get subdivisions() : uint {
			return _subdivisions;
		}

		public function get padding() : uint {
			return _padding;
		}

		private function scaleImage(bitmap : Bitmap) : BitmapData {
			var bd : BitmapData = new BitmapData(_boardWidth, _boardHeight);
			var bRate : Number = _boardWidth / _boardHeight;
			var iRate : Number = bitmap.width / bitmap.height;
			var matrix : Matrix = new Matrix();
			if(bRate < iRate) {
				matrix.scale(_boardHeight * iRate / bitmap.width, _boardHeight / bitmap.height);
			} else {
				matrix.scale(_boardWidth / bitmap.width, _boardWidth / iRate / bitmap.height);
			}
			bd.draw(bitmap, matrix, null, null, null, true);			
			return bd;
		}

		public function createPuzzle(bitmap : Bitmap) : void {
			clearBoard();
			var bd : BitmapData = scaleImage(bitmap);
			var pbd : BitmapData;
			var len : uint = subdivisions * subdivisions;
			var rect : Rectangle = new Rectangle(0, 0, _pieceWidth, _pieceHeight);
			var point : Point = new Point();
			for(var i : uint = 0;i < len;i++) {
				if(i == _space) {
					continue;
				}
				rect.x = (i % subdivisions) * _pieceWidth;
				rect.y = Math.floor(i / subdivisions) * _pieceHeight;
				pbd = new BitmapData(_pieceWidth, _pieceHeight);				
				pbd.copyPixels(bd, rect, point);				
				var piece : PuzzlePiece = new PuzzlePiece(pbd, new Point(i % subdivisions, Math.floor(i / subdivisions)), padding);
				piece.addEventListener(PuzzleEvent.CLICK, clickHandler);
				piece.addEventListener(PuzzleEvent.MOVE, moveHandler);
				piece.addEventListener(PuzzleEvent.READY, moveHandler);
				addChild(piece);
				_pieces.push(piece);
			}
		}

		public function startGame() : void {
			var count : uint = 0;
			var piece : PuzzlePiece;
			var position : int;
			while (count < 100) {                
				do {                    
					piece = _pieces[int(Math.random() * _pieces.length - 1)];
					position = checkNeighbours(piece);
				}while (position == -1);
				piece.move(position, false);
				count++;
			}
			_moving = false;
		}

		private function clickHandler(event : PuzzleEvent) : void {
			if(_moving) {
				return;
			}
			var position : int = checkNeighbours(event.piece);
			if(position > -1) {
				event.piece.move(position);
			}
		}

		private function moveHandler(event : PuzzleEvent) : void {
			switch(event.type) {
				case PuzzleEvent.READY:
					_moving = false;
					break;
				case PuzzleEvent.MOVE:
					_moving = true;
					break;
			}
		}

		private function clearBoard() : void {
			if(_pieces.length == 0) {
				return;
			}
			for each(var piece:PuzzlePiece in _pieces) {
				piece.removeEventListener(PuzzleEvent.CLICK, clickHandler);
				piece.removeEventListener(PuzzleEvent.READY, moveHandler);
				piece.removeEventListener(PuzzleEvent.MOVE, moveHandler);
				removeChild(piece);
			}
			_pieces = [];
		}

		private function isEmptySpace(x : int,y : int) : Boolean {            
			for each (var piece:PuzzlePiece in _pieces) {
				if(piece.point.x == x && piece.point.y == y) {
					return false;
				}
			}
			return true;
		}

		private function checkNeighbours(piece : PuzzlePiece) : int {
			if (piece.point.x > 0 && isEmptySpace(piece.point.x - 1, piece.point.y)) {				
				return PuzzlePiece.LEFT;
			}
			if (piece.point.x < subdivisions - 1 && isEmptySpace(piece.point.x + 1, piece.point.y)) {				
				return PuzzlePiece.RIGHT;
			}
			if (piece.point.y > 0 && isEmptySpace(piece.point.x, piece.point.y - 1)) {				
				return PuzzlePiece.UP;
			}
			if (piece.point.y < subdivisions - 1 && isEmptySpace(piece.point.x, piece.point.y + 1)) {				
				return PuzzlePiece.DOWN;
			}			
			return -1;
		}
	}
}

[PuzzleEvent类]
package com.klstudio.puzzles.slider {
	import flash.events.Event;

	/**
	 * PuzzleEvent
	 * @author Kinglong(kinglong@gmail.com)
	 * @since:2010-9-13
	 */	

	public class PuzzleEvent extends Event {
		private var _piece : PuzzlePiece;
		public static const MOVE : String = "MOVE";
		public static const READY : String = "READY";
		public static const CLICK : String = "CLICK";

		public function PuzzleEvent(type : String, piece : PuzzlePiece = null) {
			super(type);
			_piece = piece;
		}

		public function get piece() : PuzzlePiece {
			return _piece;
		}

		override public function clone() : Event {
			return new PuzzleEvent(type, piece);
		}
	}
}


[PuzzlePiece类]
package com.klstudio.puzzles.slider {
	import flash.filters.GradientBevelFilter;
	import flash.filters.BitmapFilter;
	import flash.filters.BitmapFilterType;
	import flash.filters.BitmapFilterQuality;
	import flash.events.MouseEvent;

	import gs.TweenLite;
	import gs.easing.Circ;

	import flash.display.Bitmap;
	import flash.display.Shape;
	import flash.geom.Point;
	import flash.display.BitmapData;
	import flash.display.Sprite;

	/**
	 * PuzzlePiece
	 * @author Kinglong(kinglong@gmail.com)
	 * @since:2010-9-13
	 */	

	public class PuzzlePiece extends Sprite {
		public static const DOWN : int = 3;
		public static const LEFT : int = 1;
		public static const UP : int = 4;
		public static const RIGHT : int = 2;

		private var _padding : uint;
		private var _ease : Function;
		private var _point : Point;
		private var _oPoint : Point;
		private var _bmp : Bitmap;
		private var _mask : Shape;

		public function PuzzlePiece(bitmapData : BitmapData,point : Point,padding : uint = 1) {
			mouseChildren = false;			
			_ease = Circ.easeInOut;
			_padding = padding;
			_oPoint = point.clone();
			_point = point.clone();
			
			_bmp = new Bitmap(bitmapData);
			addChild(_bmp);			
			
			_mask = new Shape();
			_mask.graphics.beginFill(0xFF0000);
			_mask.graphics.drawRoundRect(_padding, _padding, _bmp.width - _padding * 2, _bmp.height - _padding * 2, 8, 8);
			_mask.graphics.endFill();
			addChild(_mask);
			_bmp.mask = _mask;	
			
			x = point.x * _bmp.width;
			y = point.y * _bmp.height;
			
			addEventListener(MouseEvent.CLICK, clickHandler);		
			
			_bmp.filters = [getBitmapFilter()];
		}

		public function move(position : int,tweened : Boolean = true) : void {
			var params : Object = {ease:_ease, onComplete:tweenCompleteHandler};
			var duration : Number = 0.4;
			switch(position) {
				case LEFT:
					updatePoint(point.x - 1, point.y);
					if(tweened) {
						params["x"] = point.x * _bmp.width;
						TweenLite.to(this, duration, params);
						dispatchEvent(new PuzzleEvent(PuzzleEvent.MOVE));
					} else {
						x = point.x * _bmp.width;
					}
					break;
				case RIGHT:	
					updatePoint(point.x + 1, point.y);	
					if(tweened) {
						params["x"] = point.x * _bmp.width;
						TweenLite.to(this, duration, params);
						dispatchEvent(new PuzzleEvent(PuzzleEvent.MOVE));
					} else {
						x = point.x * _bmp.width;
					}			
					break;
				case UP:	
					updatePoint(point.x, point.y - 1);
					if(tweened) {
						params["y"] = point.y * _bmp.height;
						TweenLite.to(this, duration, params);
						dispatchEvent(new PuzzleEvent(PuzzleEvent.MOVE));
					} else {
						y = point.y * _bmp.height;
					}				
					break;
				case DOWN:	
					updatePoint(point.x, point.y + 1);
					if(tweened) {
						params["y"] = point.y * _bmp.height;
						TweenLite.to(this, duration, params);
						dispatchEvent(new PuzzleEvent(PuzzleEvent.MOVE));
					} else {
						y = point.y * _bmp.height;
					}				
					break;				
			}		
		}

		public function get point() : Point {
			return _point;
		}

		public function reset() : void {
			updatePoint(_oPoint.x, _oPoint.y);
			x = point.x * _bmp.width;
			y = point.y * _bmp.height;						
		}

		private function updatePoint(x : int,y : int) : void {
			_point.x = x;
			_point.y = y;
			if(hasCompleted()) {
				_bmp.filters = null;
			}else{
				_bmp.filters = [getBitmapFilter()];
			}
		}

		private function getBitmapFilter() : BitmapFilter {
			return new GradientBevelFilter(5, 225, [16777215, 13421772, 0], [0.4, 0, 0.4], [0, 128, 255], 8, 8, 2, BitmapFilterQuality.HIGH, BitmapFilterType.INNER, false);
		}

		public function hasCompleted() : Boolean {
			return _point.equals(_oPoint);
		}

		private function clickHandler(event : MouseEvent) : void {
			dispatchEvent(new PuzzleEvent(PuzzleEvent.CLICK, this));
		}

		private function tweenCompleteHandler() : void {
			dispatchEvent(new PuzzleEvent(PuzzleEvent.READY));
		}
	}
}
分享到:
评论

相关推荐

    SlidingPuzzle

    在这个主题下,我们将深入探讨如何使用Flash Builder这一专业工具来开发一款滑动拼图游戏。 Flash Builder是一款强大的集成开发环境(IDE),专门用于创建基于Adobe Flash平台的应用程序,包括网页游戏。它支持...

    福兴讯V587对讲机写频,调频软件 福摩斯特V587

    福兴讯V587对讲机写频,调频软件。福摩斯特V587对讲机写频,调频

    uni-helper_vite-plugin-uni-tai_1742854282.zip

    app开发

    LangChain框架详解:大语言模型应用开发的核心模块与实践

    内容概要:本文介绍了LangChain这一开源框架,它专为开发基于大型语言模型(LLM)的应用程序而设计。文章阐述了LangChain的核心理念、架构组成及其重要性。LangChain通过模块化设计解决了大模型应用开发中的效率低下和局限性问题,提供了标准化的接口和丰富的抽象层,使开发者能够轻松接入不同大模型并构建高效的应用程序。文中详细讲解了几个关键模块,包括Model I/O、Retrieval、Chains、Memory、Agents和Callbacks,以及如何安装和使用LangChain进行开发。此外,还展示了具体的代码示例,如如何调用OpenAI的API、构建LLMChain链路、设置回调机制和实现对话记忆功能。 适合人群:对大语言模型有一定了解并且有兴趣开发基于LLM的应用程序的研发人员和技术爱好者。 使用场景及目标:①帮助开发者快速掌握LangChain的基本概念和使用方法;②提供实用的代码示例,便于开发者实际操作;③解释如何通过LangChain克服大模型应用开发中的常见难题,如模型差异、输出不稳定等。 阅读建议:鉴于LangChain涉及较多的专业术语和技术细节,建议读者在阅读时结合官方文档和示例代码一起学习,尤其是对于核心模块的理解和实践。同时,关注GitHub上的最新版本更新,以获取最新的特性和改进。

    网络伴侣 iCompanion 2.1

    网络伴侣 iCompanion 2.1 网络计费软件,功能全面,支持ISDN

    移动开发_Flutter_简约聊天_纸聊APP_1742846962.zip

    app开发

    《基于YOLOv8的交通事故自动报警系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    《基于YOLOv8的八段锦练习指导系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    前端开发_UniApp_云开发_JsSdk_全端适配实战讲解_1742852088.zip

    app开发

    移动开发_Flutter_轮子推荐_开发效率提升_1742851671.zip

    移动开发_Flutter_轮子推荐_开发效率提升_1742851671.zip

    往复活塞杆密封件热弹流润滑仿真:Python实现与解析(复现论文,含详细可运行代码及解释)

    内容概要:本文详细介绍了往复活塞杆密封件在瞬态条件下热弹流润滑仿真的Python实现。首先定义了几何、材料和工况参数,然后分别构建了流体力学、热力学和固体力学模型。流体力学模型使用有限差分法求解瞬态雷诺方程,热力学模型考虑了温度和压力对粘度的影响,固体力学模型则采用了Mooney-Rivlin超弹性模型和Prony级数描述的粘弹性松弛。最后通过耦合求解实现了整个系统的时间积分,并绘制了液膜厚度和压力分布图。文中还讨论了模型的特点、简化假设以及扩展建议。 适合人群:机械工程领域的研究人员和技术人员,尤其是对密封件性能优化感兴趣的从业者。 使用场景及目标:适用于研究往复活塞杆密封件的工作机理及其在不同工况下的表现,帮助工程师理解和预测密封件的动态特性,从而改进设计和选材。 其他说明:该实现基于论文中的理论框架,但在实际应用时可能需要进一步调整和完善。

    人人商城V3-3.2.1版本.zip 亲测能用

    人人商城V3-3.2.1版本.zip 亲测能用

    《基于YOLOv8的灯光设备监测系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    Java面向对象编程,出现的示例代码

    Java面向对象编程,出现的示例代码

    蓝桥杯python相关资源,真题,蓝桥杯,蓝桥杯Python练习系统题库,蓝桥杯Python练习系统题库

    蓝桥杯python,蓝桥杯python相关资源,真题,蓝桥杯,蓝桥杯Python练习系统题库,蓝桥杯Python练习系统题库

    fsfzdgdfrgbzgr

    rgrgdfsegfasgrsredgf

    《基于YOLOv8的冲浪运动分析系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    Lotus Notes 4.65

    Lotus Notes 4.65 是 IBM 旗下早期版本的企业级协作平台,主要面向办公自动化和非结构化数据管理领域。以下为综合信息整理: 一、版本背景与定位 核心架构 Lotus Notes 4.65 属于客户端-服务器架构的早期版本,其服务器端为 Lotus Domino18。 客户端功能:集成电子邮件、日历、联系人管理、文档数据库访问16。 服务器功能:支持分布式文档存储、跨平台数据同步及安全权限管理18。 技术特性 数据库技术:采用非结构化文档数据库,支持表单、视图、代理等自定义数据管理工具68。 工作流引擎:内置开发环境(Domino Designer),可定制审批流程、文档跟踪等企业级应用18。 跨平台兼容性:支持 Windows 95/98、NT 等早期操作系统,依赖 TCP/IP 协议实现网络通信25。

Global site tag (gtag.js) - Google Analytics