当前位置: > > > AS3 - 简单游戏源码(移动,碰撞,道具拾取,火把照明,录像回放)

AS3 - 简单游戏源码(移动,碰撞,道具拾取,火把照明,录像回放)

这个是一个很简单的flash游戏源码。
1,游戏说明:
(1)鼠标按下就开始游戏,同时墙壁隐藏看不见。
(2)鼠标拖拽可以移动角色元件。
(3)右上角有个感应雷达,显示角色与墙壁的距离,越靠近墙壁会变得越小,说明越危险。
(4)火把道具可拾取,捡到后会照亮周围一定的范围,墙壁在附近的话可以照出来。(光线忽明忽暗模拟火把光线,光线被墙挡住还有阴影)
(5)碰到墙壁或到达终点则游戏结束,同时会播放录像

2,游戏界面




3,游戏源码
--- 主应用 Main.as ---
package {
	import flash.display.GradientType;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	[SWF(backgroundColor="#000000", frameRate="40", width="650", height="270")]
	public class Main extends Sprite {
		// 玩家角色元件
		private var player:Player=new Player();
		// 鼠标实际的位置
		private var mousePoint:Point;
		// 墙壁元件
		private var wall:Wall=new Wall();
		// 雷达元件(显示离墙的距离)
		private var radar:Radar=new Radar();
		// 火把元件
		private var light:Light=new Light();
		// 目标元件
		private var goal:Goal=new Goal();
		// 火把画布(用来绘制火把光纤的)
		private var lightCanvas:Sprite=new Sprite();
		// 是否获得火把
		private var hasLight:Boolean=false;
		// 保存所有的鼠标移动轨迹
		private var mouseVector:Vector.=new Vector.();
		// 是否开始录制录像(鼠标移动动作)
		private var recordMouse:Boolean=false;
		// 是否开始播放录像(鼠标移动动作)
		private var playMouse:Boolean=false;
		
		public function Main() {
			// 添加玩家角色
			addChild(player);
			player.x=40;
			player.y=40;
			// 添加墙壁
			addChild(wall);
			// 添加墙壁雷达
			addChild(radar);
			radar.x=600;
			radar.y=40;
			// 添加火把
			addChild(light);
			light.x=120;
			light.y=200;
			// 添加火把光线容器
			addChild(lightCanvas);
			// 添加目的地
			addChild(goal);
			goal.x=600;
			goal.y=200;
			// 添加鼠标按下监听
			stage.addEventListener(MouseEvent.MOUSE_DOWN,mousePressed);
			// 添加帧播放响应(改变光线强弱,记录播放录像)
			addEventListener(Event.ENTER_FRAME,update);
		}
		
		private function mousePressed(e:MouseEvent):void {
			// 移除鼠标按下监听
			stage.removeEventListener(MouseEvent.MOUSE_DOWN,mousePressed);
			// 添加鼠标移动和释放监听
			stage.addEventListener(MouseEvent.MOUSE_MOVE,mouseMoved);
			stage.addEventListener(MouseEvent.MOUSE_UP,mouseReleased);
			// 保存鼠标位置
			mousePoint=new Point(mouseX,mouseY);
			// 隐藏墙壁
			wall.visible=false;
			// 开始记录运动轨迹
			recordMouse=true;
		}
		
		private function mouseMoved(e:MouseEvent):void {
			var dx:Number=mouseX-mousePoint.x;
			var dy:Number=mouseY-mousePoint.y;
			// 移动角色元件相同的距离
			player.x+=dx;
			player.y+=dy;
			// 保存当前鼠标的位置
			mousePoint.x=mouseX;
			mousePoint.y=mouseY;
			// a couple of temporary variables
			var rayAngle:Number;
			// 精度 precision is the... precision of the radar system. I suggest a number which divides 360
			var precision:Number=20;
			// rayStep is the number of steps in pixels the raycast performs to find an obstacle
			var rayStep:Number=1;
			// 角色距墙壁的最小距离(默认最小距离 50像素,再远雷达也显示50)
			var minDistance:Number=50;
			// looping and looking for the closest point to the player
			for (var i:Number=0; i<=precision; i++) {
				// 根据精度,算出角色元件 一圈判断点的角度
				rayAngle=2*Math.PI/precision*i;
				// 因为角色元件的半径是16px,而我们只要找离墙最近点距离小于50px,所以范围是16~66
				// the bigger rayStep, the faster and less accurate the process
				for (var j:Number=16; j<=66; j+=rayStep) {
					// 判断点是否与墙壁碰撞
					if (wall.hitTestPoint(player.x+j*Math.cos(rayAngle),player.y+j*Math.sin(rayAngle),true)) {
						// 发现并记录该点
						minDistance=Math.min(j-16,minDistance);
						break;
					}
				}
			}
			// 更新雷达尺寸;
			radar.width=minDistance;
			radar.height=minDistance;
			// 碰到墙壁则游戏结束
			if (minDistance<1) {
				mouseVector.push(new Point(player.x,player.y));
				wall.visible=true;
				stage.removeEventListener(MouseEvent.MOUSE_MOVE,mouseMoved);
				stage.removeEventListener(MouseEvent.MOUSE_UP,mouseReleased);
				removeChild(lightCanvas);
				removeChild(radar);
				recordMouse=false;
				playMouse=true;
			}
			// 如果还没拿到火把,且碰到火把则获得火把
			if (! hasLight) {
				var playerToLightX:Number=player.x-light.x;
				var playerToLightY:Number=player.y-light.y;
				// 1024 = (16 (player radius) + 16 (light radius))^2
				if (playerToLightX*playerToLightX+playerToLightY*playerToLightY<1024) {
					// you got light powerup!!
					hasLight=true;
					removeChild(light);
				}
			}
			else {
				// 如果捡到火把则绘制光线
				lightCanvas.graphics.clear();
				lightCanvas.graphics.lineStyle(0,0xffffff,0);
				var mtx:Matrix = new Matrix();
				mtx.createGradientBox(306,306,0,player.x-158,player.y-158);
				// we are drawing a gradient this time;
				lightCanvas.graphics.beginGradientFill(GradientType.RADIAL,[0xffffff,0xffffff],[0.5,0],[0,255],mtx);
				precision=60;
				for (i=0; i<=precision; i++) {
					rayAngle=2*Math.PI/precision*i;
					for (j=16; j<=158; j+=rayStep) {
						if (wall.hitTestPoint(player.x+j*Math.cos(rayAngle),player.y+j*Math.sin(rayAngle),true)) {
							break;
						}
					}
					if (i==0) {
						// moving the graphic pen if it's the first point we find
						lightCanvas.graphics.moveTo(player.x+j*Math.cos(rayAngle), player.y+j*Math.sin(rayAngle));
					}
					else {
						// or drawing if it's not the first point we find
						lightCanvas.graphics.lineTo(player.x+j*Math.cos(rayAngle), player.y+j*Math.sin(rayAngle));
					}
				}
				lightCanvas.graphics.endFill();
			}
			// 判断是否碰到终点
			var playerToGoalX:Number=player.x-goal.x;
			var playerToGoalY:Number=player.y-goal.y;
			// 1296 = (16 (player radius) + 20 (goal radius))^2
			if (playerToGoalX*playerToGoalX+playerToGoalY*playerToGoalY<1296) {
				// 到达终点
				mouseVector.push(new Point(player.x,player.y));
				wall.visible=true;
				stage.removeEventListener(MouseEvent.MOUSE_MOVE,mouseMoved);
				stage.removeEventListener(MouseEvent.MOUSE_UP,mouseReleased);
				removeChild(lightCanvas);
				removeChild(radar);
				recordMouse=false;
				playMouse=true;
			}
		}
		
		private function mouseReleased(e:MouseEvent):void {
			// 如果释放鼠标,移除鼠标移动和释放监听,添加按下监听
			stage.removeEventListener(MouseEvent.MOUSE_MOVE,mouseMoved);
			stage.removeEventListener(MouseEvent.MOUSE_UP,mouseReleased);
			stage.addEventListener(MouseEvent.MOUSE_DOWN,mousePressed);
		}
		
		private function update(e:Event):void {
			// 改变火把光线透明度,造成闪烁的效果
			lightCanvas.alpha=0.5+Math.random()*0.5;
			// 记录鼠标轨迹(录像)
			if (recordMouse) {
				mouseVector.push(new Point(player.x,player.y));
			}
			// 播放鼠标轨迹(录像)
			if(playMouse){
				var currentPoint:Point=mouseVector.shift();
				player.x=currentPoint.x;
				player.y=currentPoint.y;
				if(mouseVector.length==0){
					removeEventListener(Event.ENTER_FRAME,update);
					}
			}
		}
	}
}

--- 角色元件 Player.as ---
package
{
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	
	public class Player extends Sprite
	{
		public function Player()
		{
			super();
			this.graphics.beginFill(0x0000ff);
			this.graphics.drawCircle(0,0,16);
			this.graphics.endFill();
			
			var tf:TextField = new TextField;
			tf.autoSize = TextFieldAutoSize.LEFT;
			tf.htmlText = "玩家";
			tf.y = - 9;
			tf.x = - 14;
			addChild(tf);
		}
	}
}

--- 雷达元件 Radar.as ---
package
{
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	
	public class Radar extends Sprite
	{
		public function Radar()
		{
			super();
			this.graphics.beginFill(0xff00aa);
			this.graphics.drawCircle(0,0,25);
			this.graphics.endFill();
			
			var tf:TextField = new TextField;
			tf.autoSize = TextFieldAutoSize.LEFT;
			tf.htmlText = "雷达";
			tf.y = - 9;
			tf.x = - 14;
			addChild(tf);
		}
	}
}

--- 墙壁元件 Wall.as ---
package
{
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	
	public class Wall extends Sprite
	{
		public function Wall()
		{
			this.graphics.beginFill(0xffffff);
			this.graphics.drawRect(300,0,50,100);
			this.graphics.endFill();
			
			this.graphics.beginFill(0xffffff);
			this.graphics.drawRect(300,150,50,100);
			this.graphics.endFill();
			
			var tf1:TextField = new TextField;
			tf1.autoSize = TextFieldAutoSize.LEFT;
			tf1.text = "墙";
			tf1.x = 315;
			tf1.y=40;
			addChild(tf1);
		}
	}
}

--- 火把元件 Light.as ---
package
{
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	
	public class Light extends Sprite
	{
		public function Light()
		{
			super();
			this.graphics.beginFill(0xff8800);
			this.graphics.drawCircle(0,0,16);
			this.graphics.endFill();
			
			var tf:TextField = new TextField;
			tf.autoSize = TextFieldAutoSize.LEFT;
			tf.htmlText = "火把";
			tf.y = - 9;
			tf.x = - 14;
			addChild(tf);
		}
	}
}

--- 目标元件 Goal.as ---
package
{
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	
	public class Goal extends Sprite
	{
		public function Goal()
		{
			super();
			this.graphics.beginFill(0x00aa00);
			this.graphics.drawCircle(0,0,20);
			this.graphics.endFill();
			
			var tf:TextField = new TextField;
			tf.autoSize = TextFieldAutoSize.LEFT;
			tf.htmlText = "终点";
			tf.y = - 9;
			tf.x = - 13;
			addChild(tf);
		}
	}
}

4,在线试玩

评论0