赛车游戏-“ActionScript 3.0 game programming university

      as3学习 2008-11-20 8:52

要更新下博客了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

标签集:TAGS:flash游戏 as3 赛车
回复Comments() 点击Count()

回复Comments

{commentauthor}
{commentauthor}
{commenttime}
{commentnum}
{commentcontent}
作者:
{commentrecontent}