при нажатии клавиши Пробел вызывает
function moveCursor() {
// Перемещаем перекрестие в точку,
// где находится курсор мыши.
cursor._x = _xmouse;
cursor._y = _ymouse;
}
Кнопка "button" при нажатии клавиши Пробел вызывает функцию fire, в которой определяется положение курсора и создается пара новых клипов "point" для пуль. Кроме того, в массив bullets добавляются следующие элементы: исходное положение, конечное положение, пройденное расстояние и имя клипа для каждой пули.
function fire() {
// Определяем положение мыши.
х = _xmouse;
y = _ymouse;
// Создаем левую пулю.
level++;
attachMovie("point","bullet"+level,level);
bullets.push({startx:50, starty:350, destx:x, desty:y,dist:1.0, clip: "bullet"+level});
// Создаем правую пулю.
level++;
attachMovie("point","bullet" + level,level) ;
bullets.push({startx:500, starty:350, destx:x, desty:y, dist:1.0, clip: "bullet"+level});
}
После того как пуля выпушена, ее движением во всех кадрах управляет функция moveBullets, которая использует массив bullets, чтобы отслеживать путь каждой пули. В каждом кадре значение свойства dist уменьшается на 40% от своего предыдущего значения. Пуля отображается между своим исходным и конечным положением в зависимости от значения dist. Если это значение равно 1,0, пуля находится в исходном положении, а при 0,0 - в конечном.
Однако когда значение свойства dist становится равным 0,01, считается, что пуля практически закончила свой путь. В этот момент вызывается функция checkForHit, чтобы определить, попадет ли пуля в астероид или нет. Независимо от результата пуля удаляется из массива и ролика.
Эта игра не претендует на трехмерную модель реального пространства. Она, скорее, воссоздает типичную аркадную игру.
function moveBullets() {
// Перемещаем все пули.
for (i=bullets.length-1; i>=0; i--) {
// Увеличиваем пройденное расстояние на 40%.
bullets[i].dist *= .4;
// Если пуля оказалась слишком далеко от астероида,
// удаляем ее.
function startLevel() {
// Корабль не движется,
ship.dx = 0.0;
ship.dy = 0.0;
// Создаем новые массивы,
bullets = new Array();
rocks = new Array();
// Начинаем игру с нулевым уровнем клипа,
level = 0;
// Добавляем новые астероиды, количество которых на единицу
// больше значения переменной
gamelevel. tor(i=0; i
newRock{100,0,0) ;}
// Можно стрелять сразу же.
timeOfLastFire = 0;}
Следующий набор функций состоит из функций, реагирующих на нажатие клавиш. Все они так или иначе управляют кораблем. Первая функция поворачивает корабль на определенный угол. Если вы еще раз посмотрите, как кнопка "button" вызывала эту функцию, то заметите, что в первом случае функции сообщалось значение 30, а в другом -30. При этом корабль поворачивается на угол 30° в том или ином направлении.
function shipTurn(amt) {
// Поворачиваем корабль,
ship._rotation += amt;}
Следующая функция активизирует ускорители. С помощью функций Math.cos и Math.sin она преобразует угол поворота корабля в горизонтальную и вертикальную компоненты. К сожалению, свойство клипа _rotation представлено в градусах, а две математические функции требует величины в радианах. Для перевода значения из градусов в радианы необходимо из величины „rotation вычесть 90° (чтобы 0° находился в верхней точке окружности, а не в правой), а затем умножить на 2? и разделить на 360.
function shipThrust() {
// Перемещаем корабль туда, куда направлен его нос.
ship._dx += Math.cos(2.0*Math.Pi*(ship._rotation-90)/360.0);
ship._dy += Math.sin(2.0*Math.Pi*(ship._rotation-90)/360.0);
// Показываем, как включаются ускорители,
ship.gotoAndPlay("thrust");}
С другой стороны, когда игрок нажимает клавишу со стрелкой "вниз", можно легко остановить корабль, обнулив свойства dx и dy.
function shipBreak() {
// Останавливаем корабль.
ship.dx = 0;
ship.dy = 0;}
Когда игрок нажимает клавишу Пробел, корабль должен выстрелить. Однако сначала проверяется, достаточно ли времени прошло с момента последнего выстрела.
С помощью клипа "bullet" генерируется пуля, свойства dx и dy создаются и устанавливаются так же, как и для корабля. А в массив bullets добавляется указатель на клип, чтобы потом можно было легко к нему обратиться.
clip = _root["berry"+level];
clip._x = x*25; clip._y = y*25;
// Добавляем клип в массив berries.
berries.push(clip);
level++;
}}}
// Создаем клип с лисой и определяем его положение.
attachMovie("fox", "fox", level++);
fox._x = 275;
fox._y = 275;
// Определяем направление движения и координаты цели,
fox.move = {x:0; у:0};
fox.dest = {х:275, у:275};
fox.nextmove = 0;
// Создаем и размещаем клип с кроликом.
attachMovie("bunny", "bunny", level++);
bunny._x = 275;
bunny._y = 125;
// Определяем направление движения и координаты цели.
// Запоминаем координаты предыдущего положения,
bunny.move = {х:1, у:0};
bunny.dest = {х:300, у:125};
bunny.nextmove = 0;
bunny.last = {x:275, у:125};
}
В каждом кадре вызывается функция move, которая передвигает клип с лисой в соответствии с объектом move. В функции содержится специальное условие, чтобы можно было определить, перемещается ли лиса за пределы экрана справа или слева, и если да, то лиса появляется на противоположной стороне (по тоннелю лиса может переходить с одной стороны экрана на другую).
Новое положение цели как для лисы, так и для кролика - всегда координаты следующей ягоды. Даже если ягоду не видно, клип все равно находится на своем месте. Когда лиса доходит до ягоды, координаты которой совпадают со значениями объекта fox.dest, вызывается функция eatBerry, чтобы удалить ягоду, если она все еще видна. Затем с помощью функции nextMove определяются координаты следующего положения цели.
Обратите внимание, что лиса каждый раз перемещается на пять пикселов. Так как все ягоды расположены на расстоянии 25 пикселов друг от друга, то, чтобы дойти до следующей ягоды, необходимо сделать пять шагов. Скорость передвижения лисы - число, которое прибавляется к свойству nextMove. В данном случае добавляется число 50, то есть между шагами пройдет, по крайней мере, 50 миллисекунд.
function move() {
// Выясняем, можно ли сделать следующий шаг.
if (getTimert) > fox.nextmove) {
hitPoints.push({x:9, y:13});
hitPoints.push({x:0, y:-10});
hitPoints.push({x:-9, y:-7});
hitPoints.push({x:8, y:-7});
// Определяем координаты опор лунохода
footPoints = new Array();
footPoints.push({x:-9, y:13});
footPoints.push({x:9, y:13});
// Создаем массив из клипов "pad" (посадочная площадка)
pads = new Array();
for (i=0; i
pads.push(_root["pad"+i]);
}}
В каждом кадре посредством клипа "actions" вызывается функция moveShip, которая, в свою очередь, вызывает множество небольших функций для управления кораблем. Всегда лучше разбивать большой фрагмент кода на несколько небольших функций.
function moveShip() {
shipThrusters();
shipMovement();
checkForLand();
checkForCrash();}
Функция shipThrusters проверяет, осталось ли еще горючее, если нет, то клип "ship" переходит к кадру "normal". В противном случае, если игрок нажимает на одну из клавиш со стрелками "вверх", "влево" или "вправо", включается соответствующий ускоритель. Клип "ship" переходит к соответствующему кадру, и чтобы отразить эффект действия ускорителя, изменяются значения dx и dy. Также уменьшается количество топлива.
function shipThrusters() {
// Проверяем ускорители и корректируем скорость,
if (fuel < 0) {
ship.gotoAndStop("normal");
} else if (Key.isDown(Key.UP)) {
ship.dy -= .4;
ship.gotoAndStop("up");
fuel -= 2;
showFuel();
} else if (Key.isDownfKey.LEFT)) {
ship.dx -= .2;
ship.gotoAndStop("left");
fuel -= 1;
showFuel();
} else if (Key.isDownfKey.RIGHT)) {
ship.dy += .2;
ship.gotoAndStop("right");
fuel -= 1;
showFuel();
} else {
//He включен ни один из ускорителей,
ship.gotoAndStop("normal");
}}
Функция shipMovement изменяет скорость корабля согласно гравитации и перемешает корабль в зависимости от скорости лунохода.
function shipMovement() {
// Гравитация заставляет корабль двигаться вниз,
ship.dy += gravity;
// Перемещаем корабль.
worldEnd = 1400;
}
Если вы собираетесь сделать пространство игры больше или, возможно, хотите добавить новые уровни, то, вероятно, вы захотите изменить функцию creatworld так, чтобы она считывала данные из внешнего текстового файла вместо того, чтобы создавать каждый элемент в отдельной строке кода. Текстовый файл может определять тип и расположение каждого элемента в отдельных позициях так, как это было сделано в главе 12.
После создания массива objects функция creatObjects просматривает его в цикле и создает все соответствующие клипы.
function createObjects() {
for(var i=0;i
_root.attachMovie(objects[i].type,"object "+i,i);
} }
Функция moveFox - это главный движущий механизм всей игры. В ней идет ряд проверок, которые отслеживают появление определенных событий в игре.
Сначала вызывается функция determineBounds, которой передается значение координат лисы (1). Эта функция возвращает максимальные значения расстояний вверх, вниз, вправо и влево, на которые может передвигаться лиса, не натыкаясь на какой-нибудь блок.
Далее, функция moveFox проверяет, есть ли пустое место под лисой и не находится ли лиса в состоянии падения, что определяется с помощью переменной falling (2). Если это так, то лиса начинает падать.
Если falling равняется true, то вызывается функция checkFall для обработки вертикального движения (3).
Далее, проверяется не нажаты ли стрелки "вправо" и "влево" (4). Если да, то проверяются оба значения foxBounds.left и foxBounds.right, чтобы определить, есть ли место для движения лисы. Также проверяются границы игрового пространства - 0 и worldEnd, - чтобы лиса не выходила за их пределы. Переменная moving принимает значение true только если нажата клавиша со стрелкой. Эта переменная определяет, какая часть клипа "fox" будет проигрываться.
Лиса прыгает при нажатии пробела (5). Прыжок противоположен падению, поэтому переменная fallSpeed принимает положительное значение (когда лиса падает, ее значение меньше ноля). Если в момент нажатия пробела лиса стоит, то запускается анимация прыжка лисицы. Если же лиса находится в движении, когда нажат пробел, то клип лисы остается в позиции шага (то есть она прыгает в том положении, в котором ее застало нажатие на пробел).
Следующий фрагмент кода отвечает за анимацию лисы (6). Если лиса, движется и не падает вниз (не прыгает вверх), то клип лисы переходит к следующему кадру. Благодаря этому ноги лисы "шагают". Если же лиса движется или падает, то клип лисы переходит в первый кадр с изображением стоящей лисы.
В то время как горизонтальная позиция лисы постоянно находится в центре экрана, ее вертикальное положение может меняться. Вертикальное положение лисы задается свойством foxPos.y, а земля находится в вертикальной позиции 0. Значит, чтобы получить свойство _у клипа лисы, мы должны вычесть foxPos.y из значения переменной floor (7).
В конце функции moveFox вызываются еще три функции: moveBunnies отвечает за движение кроликов, drawObjects перерисовывает блоки, кроликов и орехи в соответствии с новым положением игрового поля относительно лисы, а функция getAcorns проверяет, не съела ли лиса какой-нибудь из орехов.
Содержание раздела