碰撞是这个游戏的主要部分。游戏会有两种类型的碰撞:导弹和岩石,岩石碰飞船。
弹和岩石碰撞时,原有的岩石被移除。如果有一颗大岩石,那么两个中等的岩石就会出现在同样的位置上。如果是一颗中等的岩石,就是在当前位置上出现两个小岩石。如果是一颗小岩石,没有新的出现。碰撞后导弹也会被移除。
当岩石和飞船碰撞时,岩石相当于被飞船击中,飞船则被移除了,玩家有三条命。如果玩家还有生命,就会得到一个新的飞船,会在两秒鈡以后出现在屏幕的中央。
如果玩家将所有的岩石打掉了,而且屏幕上没有新的岩石出现,则这个级别的游戏结束了。短暂的等待后,新的一波岩石出现了,不过这次岩石的速度要比之前快一些。
还有一个操作就是玩家可以产生一个保护盾,按住Z键,就可以让飞船的周围产生一个保护盾,持续3秒。这就可以让飞船穿越岩石。但是,玩家的每条生命只有三个保护盾。
这个游戏有个重要特性,飞船和岩石在运动时都可以穿越屏幕。如果其中一个从屏幕左边穿出,则会在屏幕右边出现。如果从底部穿出,就会在顶部出现。不过导弹在运动到屏幕的边缘时就会消失。
package {
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.utils.getTimer;
import flash.utils.Timer;
import flash.geom.Point;
public class SpaceRocks extends MovieClip {
static const shipRotationSpeed:Number = .1;//飞船旋转速度
static const rockSpeedStart:Number = .03;//岩石起始速度
static const rockSpeedIncrease:Number = .02;//岩石加速
static const missileSpeed:Number = .2;//导弹速度
static const thrustPower:Number = .15;//推进器
static const shipRadius:Number = 20;//飞船半径
static const startingShips:uint = 3;//飞船数量
// 游戏对象
private var ship:Ship;//飞船
private var rocks:Array;//岩石
private var missiles:Array;//导弹
//动画计时器
private var lastTime:uint;
// 方向键
private var rightArrow:Boolean = false;
private var leftArrow:Boolean = false;
private var upArrow:Boolean = false;
// 飞船速度
private var shipMoveX:Number;
private var shipMoveY:Number;
// 计时器
private var delayTimer:Timer;//下一架飞船出现的时间
private var shieldTimer:Timer;//保护盾持续的时间
// 游戏模式
private var gameMode:String;
private var shieldOn:Boolean;//保护盾是否打开
// 飞船和保护盾
private var shipsLeft:uint;//
private var shieldsLeft:uint;//记录数量
private var shipIcons:Array;//
private var shieldIcons:Array;//保存显示在屏幕上给予玩家的信息
private var scoreDisplay:TextField;
// 得分和游戏等级
private var gameScore:Number;
private var gameLevel:uint
// sprites
private var gameObjects:Sprite;
private var scoreObjects:Sprite;
// 开始游戏
public function startSpaceRocks() {
// 设置sprites
gameObjects = new Sprite();
addChild(gameObjects);
scoreObjects = new Sprite();
addChild(scoreObjects);
// 设置游戏属性
gameLevel = 1;//游戏等级
shipsLeft = startingShips;//飞船数量
gameScore = 0;//起始得分
createShipIcons();
createScoreDisplay();
// 设置侦听器
addEventListener(Event.ENTER_FRAME,moveGameObjects);
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownFunction);
stage.addEventListener(KeyboardEvent.KEY_UP,keyUpFunction);
// 开始
gameMode = "delay";
shieldOn = false;
missiles = new Array();//保存子弹
nextRockWave(null);//创建第一组岩石
newShip(null);//创建第一艘飞船
}
// SCORE OBJECTS
// 在左边绘制飞船
public function createShipIcons() {
shipIcons = new Array();
for(var i:uint=0;i<shipsLeft;i++) {
var newShip:ShipIcon = new ShipIcon();
newShip.x = 20+i*15;
newShip.y = 375;
scoreObjects.addChild(newShip);
shipIcons.push(newShip);
}
}
// 右边绘制保护盾
public function createShieldIcons() {
shieldIcons = new Array();
for(var i:uint=0;i<shieldsLeft;i++) {
var newShield:ShieldIcon = new ShieldIcon();
newShield.x = 530-i*15;
newShield.y = 375;
scoreObjects.addChild(newShield);
shieldIcons.push(newShield);
}
}
// 将得分记录放在右上角
public function createScoreDisplay() {
scoreDisplay = new TextField();
scoreDisplay.x = 500;
scoreDisplay.y = 10;
scoreDisplay.width = 40;
scoreDisplay.selectable = false;
var scoreDisplayFormat = new TextFormat();
scoreDisplayFormat.color = 0xFFFFFF;
scoreDisplayFormat.font = "Arial";
scoreDisplayFormat.align = "right";
scoreDisplay.defaultTextFormat = scoreDisplayFormat;
scoreObjects.addChild(scoreDisplay);
updateScore();
}
//显示新得分
public function updateScore() {
scoreDisplay.text = String(gameScore);
}
// 移除飞船图标
public function removeShipIcon() {
scoreObjects.removeChild(shipIcons.pop());
}
// 移除保护盾图标
public function removeShieldIcon() {
scoreObjects.removeChild(shieldIcons.pop());
}
// 移除剩余的飞船图标
public function removeAllShipIcons() {
while (shipIcons.length > 0) {
removeShipIcon();
}
}
// 移除剩余的保护盾图标
public function removeAllShieldIcons() {
while (shieldIcons.length > 0) {
removeShieldIcon();
}
}
// SHIP CREATION AND MOVEMENT
// 创建一艏新的飞船
public function newShip(event:TimerEvent) {
// 如果飞船存在,移除它
if (ship != null) {
gameObjects.removeChild(ship);
ship = null;
}
// 没有飞船了
if (shipsLeft < 1) {
endGame();
return;
}
// 创建、定位并添加新的飞船
ship = new Ship();
ship.gotoAndStop(1);
ship.x = 275;
ship.y = 200;
ship.rotation = -90;
ship.shield.visible = false;
gameObjects.addChild(ship);
// 设置飞船属性 (用以存储飞船的速度)
shipMoveX = 0.0;
shipMoveY = 0.0;
gameMode = "play";
// 设置保护盾
shieldsLeft = 3;
createShieldIcons();
// 除第一条外,每条生命开始时都有一个免费的保护盾
if (shipsLeft != startingShips) {
startShield(true);//为true时表示免费使用,不会影响玩家已有的3个
}
}
// 注册按键
public function keyDownFunction(event:KeyboardEvent) {
if (event.keyCode == 37) {
leftArrow = true;
} else if (event.keyCode == 39) {
rightArrow = true;
} else if (event.keyCode == 38) {
upArrow = true;
// 显示推进器
if (gameMode == "play") ship.gotoAndStop(2);
} else if (event.keyCode == 32) { // 空格键
newMissile();
} else if (event.keyCode == 90) { // Z键
startShield(false);
}
}
// 注册按键
public function keyUpFunction(event:KeyboardEvent) {
if (event.keyCode == 37) {
leftArrow = false;
} else if (event.keyCode == 39) {
rightArrow = false;
} else if (event.keyCode == 38) {
upArrow = false;
// 移除推进器
if (gameMode == "play") ship.gotoAndStop(1);
}
}
//飞船动画
public function moveShip(timeDiff:uint) {
// 旋转和推动
if (leftArrow) {
ship.rotation -= shipRotationSpeed*timeDiff;
} else if (rightArrow) {
ship.rotation += shipRotationSpeed*timeDiff;
} else if (upArrow) {
shipMoveX += Math.cos(Math.PI*ship.rotation/180)*thrustPower;
shipMoveY += Math.sin(Math.PI*ship.rotation/180)*thrustPower;
}
// 移动
ship.x += shipMoveX;
ship.y += shipMoveY;
// 屏幕约束
if ((shipMoveX > 0) && (ship.x > 570)) {
ship.x -= 590;
}
if ((shipMoveX < 0) && (ship.x < -20)) {
ship.x += 590;
}
if ((shipMoveY > 0) && (ship.y > 420)) {
ship.y -= 440;
}
if ((shipMoveY < 0) && (ship.y < -20)) {
ship.y += 440;
}
}
// 移除飞船
public function shipHit() {
gameMode = "delay";
ship.gotoAndPlay("explode");
removeAllShieldIcons();
delayTimer = new Timer(2000,1);
delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE,newShip);
delayTimer.start();
removeShipIcon();
shipsLeft--;
}
// 打开保护盾3秒钟
public function startShield(freeShield:Boolean) {
if (shieldsLeft < 1) return; // 没有保护盾可用
if (shieldOn) return; // 保护盾已经打开
// 打开保护盾 设置计时器来关闭保护盾
ship.shield.visible = true;
shieldTimer = new Timer(3000,1);
shieldTimer.addEventListener(TimerEvent.TIMER_COMPLETE,endShield);
shieldTimer.start();
// 更新剩余保护盾数量
if (!freeShield) {
removeShieldIcon();
shieldsLeft--;
}
shieldOn = true;
}
// 关闭保护盾 3秒时间结束
public function endShield(event:TimerEvent) {
ship.shield.visible = false;
shieldOn = false;
}
// ROCKS
// 创建一个指定尺寸的岩石
public function newRock(x,y:int, rockType:String) {
// 创建一个合适的新类
var newRock:MovieClip;
var rockRadius:Number;
if (rockType == "Big") {
newRock = new Rock_Big();
rockRadius = 35;
} else if (rockType == "Medium") {
newRock = new Rock_Medium();
rockRadius = 20;
} else if (rockType == "Small") {
newRock = new Rock_Small();
rockRadius = 10;
}
// Here is an alternate way to do the above, without a case statement
// Need to import flash.utils.getDefinitionByName to use
/*
var rockClass:Object = getDefinitionByName("Rock_"+rockType);
var newRock:MovieClip = new rockClass();
*/
// 选择一个随机的外观
newRock.gotoAndStop(Math.ceil(Math.random()*3));
// 设置起始位置
newRock.x = x;
newRock.y = y;
// 设置随机的运动和旋转
var dx:Number = Math.random()*2.0-1.0;
var dy:Number = Math.random()*2.0-1.0;
var dr:Number = Math.random();
// 将岩石添加的舞台和岩石列表中
gameObjects.addChild(newRock);
rocks.push({rock:newRock, dx:dx, dy:dy, dr:dr, rockType:rockType, rockRadius: rockRadius});
}
// 创建4块岩石
public function nextRockWave(event:TimerEvent) {
rocks = new Array();
newRock(100,100,"Big");
newRock(100,300,"Big");
newRock(450,100,"Big");
newRock(450,300,"Big");
gameMode = "play";
}
// 操纵所有的岩石
public function moveRocks(timeDiff:uint) {
for(var i:int=rocks.length-1;i>=0;i--) {
// 移动岩石
var rockSpeed:Number = rockSpeedStart + rockSpeedIncrease*gameLevel;
rocks[i].rock.x += rocks[i].dx*timeDiff*rockSpeed;
rocks[i].rock.y += rocks[i].dy*timeDiff*rockSpeed;
//旋转岩石
rocks[i].rock.rotation += rocks[i].dr*timeDiff*rockSpeed;
// 约束岩石
if ((rocks[i].dx > 0) && (rocks[i].rock.x > 570)) {
rocks[i].rock.x -= 590;
}
if ((rocks[i].dx < 0) && (rocks[i].rock.x < -20)) {
rocks[i].rock.x += 590;
}
if ((rocks[i].dy > 0) && (rocks[i].rock.y > 420)) {
rocks[i].rock.y -= 440;
}
if ((rocks[i].dy < 0) && (rocks[i].rock.y < -20)) {
rocks[i].rock.y += 440;
}
}
}
//
public function rockHit(rockNum:uint) {
// 创建两个更小的岩石
if (rocks[rockNum].rockType == "Big") {
newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Medium");
newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Medium");
} else if (rocks[rockNum].rockType == "Medium") {
newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Small");
newRock(rocks[rockNum].rock.x,rocks[rockNum].rock.y,"Small");
}
// 移除原始的岩石
gameObjects.removeChild(rocks[rockNum].rock);
rocks.splice(rockNum,1);
}
// MISSILES
// 创建一刻新的导弹
public function newMissile() {
// 创建
var newMissile:Missile = new Missile();
// 设置方向
newMissile.dx = Math.cos(Math.PI*ship.rotation/180);
newMissile.dy = Math.sin(Math.PI*ship.rotation/180);
// 放置
newMissile.x = ship.x + newMissile.dx*shipRadius;
newMissile.y = ship.y + newMissile.dy*shipRadius;
// 添加到舞台和数组中
gameObjects.addChild(newMissile);
missiles.push(newMissile);
}
// 移动导弹
public function moveMissiles(timeDiff:uint) {
for(var i:int=missiles.length-1;i>=0;i--) {
//移动
missiles[i].x += missiles[i].dx*missileSpeed*timeDiff;
missiles[i].y += missiles[i].dy*missileSpeed*timeDiff;
// 离开屏幕
if ((missiles[i].x < 0) || (missiles[i].x > 550) || (missiles[i].y < 0) || (missiles[i].y > 400)) {
gameObjects.removeChild(missiles[i]);
delete missiles[i];
missiles.splice(i,1);
}
}
}
// 移除导弹
public function missileHit(missileNum:uint) {
gameObjects.removeChild(missiles[missileNum]);
missiles.splice(missileNum,1);
}
// GAME INTERACTION AND CONTROL
public function moveGameObjects(event:Event) {
// 得到经过的时间 然后开始动画
var timePassed:uint = getTimer() - lastTime;
lastTime += timePassed;
moveRocks(timePassed);
if (gameMode != "delay") {
moveShip(timePassed);
}
moveMissiles(timePassed);
checkCollisions();
}
// 寻找导弹和岩石的碰撞
public function checkCollisions() {
// 循环遍历岩石
rockloop: for(var j:int=rocks.length-1;j>=0;j--) {
// 循环遍历导弹
missileloop: for(var i:int=missiles.length-1;i>=0;i--) {
// 碰撞检测
if (Point.distance(new Point(rocks[j].rock.x,rocks[j].rock.y),
new Point(missiles[i].x,missiles[i].y))
< rocks[j].rockRadius) {
// 移除岩石和导弹
rockHit(j);
missileHit(i);
// 增加分数
gameScore += 10;
updateScore();
// 结束这次循环,然后开始下一次
continue rockloop;
}
}
//检测岩石与飞船的碰撞
if (gameMode == "play") {
if (shieldOn == false) { // 只有当保护盾关闭时
if (Point.distance(new Point(rocks[j].rock.x,rocks[j].rock.y),
new Point(ship.x,ship.y))
< rocks[j].rockRadius+shipRadius) {
// 移除飞船和岩石
shipHit();
rockHit(j);
}
}
}
}
// 岩石清光了,改变游戏模式,增加难度
if ((rocks.length == 0) && (gameMode == "play")) {
gameMode = "betweenlevels";
gameLevel++; // 增加难度
delayTimer = new Timer(2000,1);
delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE,nextRockWave);
delayTimer.start();
}
}
public function endGame() {
// 移除所有的物体和监听
removeChild(gameObjects);
removeChild(scoreObjects);
gameObjects = null;
scoreObjects = null;
removeEventListener(Event.ENTER_FRAME,moveGameObjects);
stage.removeEventListener(KeyboardEvent.KEY_DOWN,keyDownFunction);
stage.removeEventListener(KeyboardEvent.KEY_UP,keyUpFunction);
gotoAndStop("gameover");
}
}
}