要更新下博客了o(∩_∩)o...
“ActionScript 3.0 game programming university "中的有一章是讲赛车游戏的,学习了感觉很好,还发现了作者源文件中的两个bug ^_^.以下是我的源文件,除了起跑倒计时的实现方式与作者的有所改动外,其他的基本相同.源文件和swf文件下载在下面.
package{
import flash.display.*;
import flash.events.*;
import flash.text.TextField;
import flash.geom.*;
import flash.utils.getTimer;
import flash.utils.Timer;
import flash.media.Sound; //如果不导入这两个包,则编译不通过,提示不是编译时常数;
import flash.media.SoundChannel;
public class game extends MovieClip{
//------------相关的常量与变量设置-------------------------
static const maxSpeed:Number=.3; //赛车的最大速度限制
static const accel:Number=.0003; //加速度
static const decel:Number=.0002; //减速度
static const turnSpeed:Number=.15; //转弯速度
private var speed:Number;
private var leftArrow,rightArrow,upArrow,downArrow:Boolean; //控制赛车运动方向的变量,上下左右方向键按下时为true,
//(接上)否则为false
private var lastTime:int; //记录上帧运行时的时间
private var startTime:int; // 用来记录赛车时间,从倒计时后开始计时
private var timer:Timer; //用来实现倒计时的 Timer对象
private var gameMode:String; //游戏模式:当处于倒计时时,为 "wait" ,倒计时后 "race" 开始比赛
private var wayPoints:Array; //用来存储各路点(wayPoint)的数组
static const theBrakestopSound:BrakestopSound = new BrakestopSound(); //各中需要用到的声音
static const theDriveSound:DriveSound = new DriveSound();
static const theGoSound:GoSound = new GoSound();
static const theOffroadSound:OffroadSound = new OffroadSound();
static const theReadysetSound:ReadysetSound = new ReadysetSound();
static const theSideSound:SideSound = new SideSound();
private var soundChannel:SoundChannel; //这两个用来控制声音
private var currentSound:Object;
//-----------以下是函数部分---------------------------------
//开始游戏函数 由fla文件调用
public function startGame():void{
findWayPoint();
//设置car_mc的位置,使其刚好位于起跑线(finishLine_mc)下面
sprite_mc.car_mc.x=sprite_mc.finishLine_mc.x+sprite_mc.finishLine_mc.width/2;
sprite_mc.car_mc.y=sprite_mc.finishLine_mc.y+sprite_mc.car_mc.height/2+30;
sprite_mc.car_mc.rotation=-90;
//变量初始化
speed=0; //开始游戏时候,car_mc的speed设置为0,并且游戏处于 wait状态 (倒计时)
gameMode="wait";
moveMap(); //移动地图使得car_mc在场景中心
time_txt.text=""; //time_txt 是游戏状态栏中显示时间的动态文本框
currentSound=null;// 游戏大学书中本程序的声音管理部分有个bug:重玩时,开始不会有声音,加上这句后问题解决
leftArrow=rightArrow=upArrow=downArrow=false; //游戏大学书中有bug:如果在接近终点线时,按住方向键不放,
//(接上)则游戏结束后, endGame函数中会马上注销侦听KeyboardEvent.KEY_Up
//的侦听器,这样当释放方向键后, leftArrow等就没有恢复为false,当再玩游戏时,
//leftArrow就为true,这样不按键car_mc也会运动,所以要在startGame中加上这一句
//添加侦听器
this.addEventListener(Event.ENTER_FRAME,loop);
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDown);
stage.addEventListener(KeyboardEvent.KEY_UP,keyUp);
timer=new Timer(1000,4);
timer.addEventListener(TimerEvent.TIMER,showCountDown);
timer.addEventListener(TimerEvent.TIMER_COMPLETE,changeGameMode);
timer.start();
}
//3秒倒计时函数
private function showCountDown(evt:TimerEvent):void{
sprite_mc.countDown_txt.text=String(4-timer.currentCount);
playSound(theReadysetSound); //播放倒计时声音
}
//倒计时结束后,游戏进入 race状态, 记录此时的getTimer()为游戏的开始时间
private function changeGameMode(evt:TimerEvent):void{
gameMode="race"; //改变游戏状态,不再"wait" 而是已经"race"
startTime=getTimer(); // 游戏正式开始计时
lastTime=getTimer();
sprite_mc.countDown_txt.text="";
playSound(theGoSound);
}
//找出所有wayPoint,并存储在数组 wayPionts中
private function findWayPoint():void{
wayPoints=new Array();
for(var i:int=0;i<sprite_mc.numChildren;i++){ //sprite_mc为游戏容器
var _mc=sprite_mc.getChildAt(i);
if(_mc is WayPoint){ //WayPoint 是库元件绑定的类名;
wayPoints.push(_mc);
_mc.visible=false;
}
}
}
//每帧调用的loop函数
private function loop(evt:Event):void{
if(gameMode=="wait") return; //当游戏还处于 wait 状态时,直接返回
var timeDiff:int=getTimer()-lastTime;
lastTime+=timeDiff;
//改变赛车方向: 与转向速度、时间、速度有关
if(leftArrow==true) sprite_mc.car_mc.rotation-=turnSpeed*timeDiff*(speed+.1);
if(rightArrow==true) sprite_mc.car_mc.rotation+=turnSpeed*timeDiff*(speed+.1);
if(upArrow==true){ //如果按了向上方向键,加速
speed+=accel*timeDiff;
if(speed>maxSpeed) speed=maxSpeed;
}else if(downArrow==true){ //如果按了向下方向键,减速
speed-=decel*timeDiff;
if(speed<-maxSpeed) speed=-maxSpeed;
}else if(speed>0){ //如果上下方向键都没按,则自动减速
speed-=decel*timeDiff;
if(speed<0) speed=0;
}else if(speed<0){
speed+=decel*timeDiff;
if(speed>0) speed=0;
}
if(speed!=0){ //如果速度不为零,则赛车运动,
moveCar(timeDiff);
moveMap(); //移动地图,使得赛车位于场景中央
checkWayPoint(); //如果遇到路点,则将其从存储路点的数组中删除,当全部删除了才说明玩家是沿着跑道运行
//(接上)而没有超近道
checkFinishLine(); //检测游戏是否结束 : 路点数组中所有路点被删除,且过了终点线
}
//trace(speed);
showTime(); //显示时间
}
private function moveCar(diff:int):void{ //移动汽车
var angle:Number=sprite_mc.car_mc.rotation*2*Math.PI/360;
var dx:Number=speed*diff*Math.cos(angle);
var dy:Number=speed*diff*Math.sin(angle);
sprite_mc.car_mc.x+=dx;
sprite_mc.car_mc.y+=dy;
var newSound:Object;
if(sprite_mc.road_mc.hitTestPoint(sprite_mc.car_mc.x+sprite_mc.x,sprite_mc.car_mc.y+sprite_mc.y,true)==true){
newSound=theDriveSound;
}else if(sprite_mc.side_mc.hitTestPoint(sprite_mc.car_mc.x+sprite_mc.x,sprite_mc.car_mc.y+sprite_mc.y,true)==true){
newSound=theSideSound;
speed*=1-0.001*diff;
}else{
newSound=theOffroadSound;
speed*=1-0.005*diff;
}
if(!upArrow&&!downArrow){
newSound=null;
currentSound=null;
soundChannel.stop();
//soundChannel=null; 此句不能要,不能凭主观意识 查关于 SoundChannel 的知识
}else if(newSound!=currentSound){
if(soundChannel!=null) soundChannel.stop();
currentSound=newSound;
if(currentSound!=null) soundChannel=currentSound.play(0,9999);
}
}
private function checkWayPoint():void{ //检测是否靠近wayPoint,如果靠近了则清除它
for(var i:int=0;i<wayPoints.length;i++){
var curDistance:Number=Point.distance(new Point(sprite_mc.car_mc.x,sprite_mc.car_mc.y),new Point(wayPoints[i].x,wayPoints[i].y));
if(curDistance<150) {
wayPoints.splice(i,1); //当car_mc离开wayPoint的距离不超过150时,才算通过该wayPoint
}
}
}
private function checkFinishLine():void{ //检测游戏是否结束
//trace(wayPoints.length);
if(wayPoints.length>0) return; //如果还有wayPoint没清除,则不算游戏结束
//trace("game is over");
if(sprite_mc.car_mc.y<sprite_mc.finishLine_mc.y) endGame(); //finishLine_mc 是sprite_mc中终点线的名称
}
private function keyDown(evt:KeyboardEvent):void{ //键盘按下侦听函数
if(evt.keyCode==37){
leftArrow=true;
}else if(evt.keyCode==38){
upArrow=true;
}else if(evt.keyCode==39){
rightArrow=true;
}else if(evt.keyCode==40){
downArrow=true;
}
}
private function keyUp(evt:KeyboardEvent):void{ //键盘释放侦听函数
if(evt.keyCode==37){
leftArrow=false;
}else if(evt.keyCode==38){
upArrow=false;
}else if(evt.keyCode==39){
rightArrow=false;
}else if(evt.keyCode==40){
downArrow=false;
}
}
private function moveMap():void{ //移动地图函数,使得car_mc位于舞台中央
sprite_mc.x=-sprite_mc.car_mc.x+275;
sprite_mc.y=-sprite_mc.car_mc.y+200;
trace(sprite_mc.x+"--"+sprite_mc.y);
}
private function showTime():void{ //显示时间函数更新动态文本框 time_txt 在loop函数中调用 即每帧调用
if(gameMode=="wait") return;
var i:int=getTimer()-startTime;
var seconds:Number=Math.floor(i/1000);
var ms:int=i-seconds*1000;
var minutes:Number=Math.floor(seconds/60);
time_txt.text="time:"+minutes+":"+seconds+":"+ms;
}
private function playSound(soundObject:Object):void{ //临时播放声音的函数
var channnel:SoundChannel=soundObject.play();
}
private function endGame():void{ //结束游戏函数
gameMode="wait";
soundChannel.stop();
playSound(theBrakestopSound);
removeEventListener(Event.ENTER_FRAME,loop);
stage.removeEventListener(KeyboardEvent.KEY_DOWN,keyDown);
stage.removeEventListener(KeyboardEvent.KEY_UP,keyUp);
gotoAndPlay("over");
}
}
}
:( 不知道怎么上传源文件,老是提示错误,需要源文件的网友可以和我联系.欢迎哦..
qq:503067274 E_mail:cmliuyong@tom.com
回复Comments
作者:
{commentrecontent}