主要源码如下
/* This code is from "ActionScript 3.0 Game Programming University" by Gary Rosenzweig
Copyright 2007
http://flashgameu.com
See the book or site for more information */
package {
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.geom.*;
import flash.utils.getTimer;
import flash.media.Sound;
import flash.media.SoundChannel;
public class Racing extends MovieClip {
// constants
static const maxSpeed:Number = .3;
static const accel:Number = .0002;
static const decel:Number = .0003;
static const turnSpeed:Number = .18;
// game variables
private var arrowLeft, arrowRight, arrowUp, arrowDown:Boolean;
private var lastTime:int;
private var gameStartTime:int;
private var speed:Number;
private var gameMode:String;
private var waypoints:Array;
private var currentSound:Object;
// sounds
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 driveSoundChannel:SoundChannel;
public function startRacing() {
// get list of waypoints
findWaypoints();
// add listeners
this.addEventListener(Event.ENTER_FRAME,gameLoop);
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownFunction);
stage.addEventListener(KeyboardEvent.KEY_UP,keyUpFunction);
// set up game variables
speed = 0;
gameMode = "wait";
timeDisplay.text = "";
gameStartTime = getTimer()+3000;
centerMap();
}
// look at all gamesprite children and remember waypoints
public function findWaypoints() {
waypoints = new Array();
for(var i=0;i<gamesprite.numChildren;i++) {
var mc = gamesprite.getChildAt(i);
if (mc is Waypoint) {
// add to array and make invisible
waypoints.push(new Point(mc.x, mc.y));
mc.visible = false;
}
}
}
// note key presses, set properties
public function keyDownFunction(event:KeyboardEvent) {
if (event.keyCode == 37) {
arrowLeft = true;
} else if (event.keyCode == 39) {
arrowRight = true;
} else if (event.keyCode == 38) {
arrowUp = true;
} else if (event.keyCode == 40) {
arrowDown = true;
}
}
public function keyUpFunction(event:KeyboardEvent) {
if (event.keyCode == 37) {
arrowLeft = false;
} else if (event.keyCode == 39) {
arrowRight = false;
} else if (event.keyCode == 38) {
arrowUp = false;
} else if (event.keyCode == 40) {
arrowDown = false;
}
}
// main game code
public function gameLoop(event:Event) {
// calculate time passed
if (lastTime == 0) lastTime = getTimer();
var timeDiff:int = getTimer()-lastTime;
lastTime += timeDiff;
// only move car if in race mode
if (gameMode == "race") {
// rotate left or right
if (arrowLeft) {
gamesprite.car.rotation -= (speed+.1)*turnSpeed*timeDiff;
}
if (arrowRight) {
gamesprite.car.rotation += (speed+.1)*turnSpeed*timeDiff;
}
// accelerate car
if (arrowUp) {
speed += accel*timeDiff;
if (speed > maxSpeed) speed = maxSpeed;
} else if (arrowDown) {
speed -= accel*timeDiff;
if (speed < -maxSpeed) speed = -maxSpeed;
// no arrow pressed, so slow down
} 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 moving, then move car and check status
if (speed != 0) {
moveCar(timeDiff);
centerMap();
checkWaypoints();
checkFinishLine();
}
}
// update time and check for end of game
showTime();
}
public function moveCar(timeDiff:Number) {
// get current position
var carPos:Point = new Point(gamesprite.car.x, gamesprite.car.y);
// calculate change
var carAngle:Number = gamesprite.car.rotation;
var carAngleRadians:Number = (carAngle/360)*(2.0*Math.PI);
var carMove:Number = speed*timeDiff;
var dx:Number = Math.cos(carAngleRadians)*carMove;
var dy:Number = Math.sin(carAngleRadians)*carMove;
// assume we'll use drive sound
var newSound:Object = theDriveSound;
// see if car is NOT on the road
if (!gamesprite.road.hitTestPoint(carPos.x+dx+gamesprite.x, carPos.y+dy+gamesprite.y, true)) {
// see if car is on the side
if (gamesprite.side.hitTestPoint(carPos.x+dx+gamesprite.x, carPos.y+dy+gamesprite.y, true)) {
// use special sound, reduce speed
newSound = theSideSound;
speed *= 1.0-.001*timeDiff;
} else {
// use special sound, reduce speed
newSound = theOffroadSound;
speed *= 1.0-.005*timeDiff;
}
}
// set new position of car
gamesprite.car.x = carPos.x+dx;
gamesprite.car.y = carPos.y+dy;
// if not moving, forget about drive sound
if (!arrowUp && !arrowDown) {
newSound = null;
}
// if a new sound, switch sound
if (newSound != currentSound) {
if (driveSoundChannel != null) {
driveSoundChannel.stop();
}
currentSound = newSound;
if (currentSound != null) {
driveSoundChannel = currentSound.play(0,9999);
}
}
}
// see if close enough to waypoint
public function checkWaypoints() {
for(var i:int=waypoints.length-1;i>=0;i--) {
if (Point.distance(waypoints[i], new Point(gamesprite.car.x, gamesprite.car.y)) < 150) {
waypoints.splice(i,1);
}
}
}
// see if crossed finish line
public function checkFinishLine() {
// only if all waypoints have been hit
if (waypoints.length > 0) return;
if (gamesprite.car.y < gamesprite.finish.y) {
endGame();
}
}
// update the time shown
public function showTime() {
var gameTime:int = getTimer()-gameStartTime;
// if in wait mode, show countdown clock
if (gameMode == "wait") {
if (gameTime < 0) {
// show 3, 2, 1
var newNum:String = String(Math.abs(Math.floor(gameTime/1000)));
if (countdown.text != newNum) {
countdown.text = newNum;
playSound(theReadysetSound);
}
} else {
// count down over, go to race mode
gameMode = "race";
countdown.text = "";
playSound(theGoSound);
}
// show time
} else {
timeDisplay.text = clockTime(gameTime);
}
}
// convert to time format
public function clockTime(ms:int):String {
var seconds:int = Math.floor(ms/1000);
var minutes:int = Math.floor(seconds/60);
seconds -= minutes*60;
var timeString:String = minutes+":"+String(seconds+100).substr(1,2);
return timeString;
}
// make sure car stays at center of screen
public function centerMap() {
gamesprite.x = -gamesprite.car.x + 275;
gamesprite.y = -gamesprite.car.y + 200;
}
// game over, remove listeners
public function endGame() {
driveSoundChannel.stop();
playSound(theBrakestopSound);
this.removeEventListener(Event.ENTER_FRAME,gameLoop);
stage.removeEventListener(KeyboardEvent.KEY_DOWN,keyDownFunction);
stage.removeEventListener(KeyboardEvent.KEY_UP,keyUpFunction);
gotoAndStop("gameover");
}
// show time on final screen
public function showFinalMessage() {
showTime();
var finalDisplay:String = "";
finalDisplay += "Time: "+timeDisplay.text+"\n";
finalMessage.text = finalDisplay;
}
public function playSound(soundObject:Object) {
var channel:SoundChannel = soundObject.play(0);
}
}
}