AS3 - 简单游戏源码(移动,碰撞,道具拾取,火把照明,录像回放)
作者:hangge | 2014-12-05 13:53
这个是一个很简单的flash游戏源码。


--- 角色元件 Player.as ---
--- 雷达元件 Radar.as ---
--- 墙壁元件 Wall.as ---
--- 火把元件 Light.as ---
--- 目标元件 Goal.as ---
4,在线试玩
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)