91824841

Астероид создан так же, как


if (bullets[fi].dist < .01) {

checkForHit(bullets[i].destx, bullets[i].desty);

_root[bullets[i].clip].removeMovieClip();

bullets.splice(i,1);

// Помещаем пулю ближе к цели.

} else {

bullets[i].x = bullets[i].dist*bullets[i].startx + (1.0-bullets[i] .dist)* bullets[i] .destx;

bullets[i].у = bullets[i].dist*bullets[i].starty + (l.0-bulletsfi].dist)* bullets[i].desty;

_root [bullets[i] .clip] ._x = bulletsfi] .x; _root[bullets[i].clip]._y = bullets[i].y;

}}}

Астероид создан так же, как и пуля. Однако координаты появления и исчезновения астероида выбираются случайно. Стартовая точка находится на расстоянии 25 пикселов по горизонтали и вертикали от центра экрана. Конечная точка отстоит от центра на расстоянии 550 пикселов по горизонтали и 400 по вертикали, что ровно в два раза больше размера рабочего поля. Это означает, что астероид появляется всегда в районе центра экрана, но может финишировать в любой точке вне видимой его области.

function createRock() {

// Задаем случайное положение для астероида,

startx = Math.random()*50+250;

starty = Math.random()*50+175;

// Задаем случайное направление движения,

destx = Math.random()*1100-275;

desty = Math.randomO*800-200;



// Добавляем астероид.

level + + ;

attachMovie("rock","rock"+level,level++);

rocks.push({startx: startx, starty: starty, destx: destx,desty: desty, dist: .01, clip: "rock"+level});

}

Подобно функции moveBullets функция moveRocks использует свойство dist каждого астероида, чтобы передвинуть его. Однако со временем он приближается к экрану и его начальное значение 0,01 в каждом кадре увеличивается на 10%. Помимо положения астероида его свойства _xscale и _yscale также зависят от dist, это делает возможным увеличивать астероид и создавать иллюзию его приближения к кораблю.
Если значение dist становится больше 1,0 и астероид все еще находится в видимой области экрана, считается, что астероид попал в корабль. Астероид взрывается, и значение переменной damage увеличивается. Если значение переменной damage больше или равно 20, то игра заканчивается.



function shipFire() {

// Выясняем, достаточно ли времени прошло

//с момента последнего выстрела.

if (timeOfLastFire+200 < getTimer()) {

// Запоминаем, когда производится этот выстрел.
timeOflastFire = getTimer();

// Создаем пулю.

level++;

attachMovie("bullet", "bullet"+level, level);

// Определяем положение и направление движения пули,

clip = _root["bullet"+level];

clip._x = ship._x;

clip._y = ship._y;

clip.dx = 10.0*Math.cos(2.0*Math.PI*-(ship._rotation-90)/360.0);

clip.dy = 10.0*Math.sin(2.0*Math.PI*(ship._rotation-90)/360.0) ;

// Добавляем элемент массива

bullets, bullets.push(clip);
}}

В каждом кадре корабль перемешается на один шаг: для этого увеличиваются значения свойств _х и _у на величины dx и dy соответственно. Если корабль слишком далеко подвинулся вправо, то есть за пределы рабочего поля, то из значений этих свойств вычитается 550 пикселов, чтобы корабль появился с противоположной стороны экрана. Аналогичные действия производятся для левой, нижней и верхней границ рабочего поля.

function shipMove() {

// Перемещаем корабль по горизонтали или, если нужно,
//на противоположную сторону экрана.

ship._x += ship.dx;

if (ship._x > 550) ship._x -= 550;

if (ship._x < 0) ship._x += 550;

// Перемещаем корабль по вертикали или, если нужно,

//на противоположную сторону экрана.
ship._y += ship.dy;

if (ship._y > 400) ship._y -= 400;

if (ship._y < 0) ship._y += 400;
}

Пули двигаются так же, как и корабль. Однако необходимо просматривать весь массив bullets, чтобы перемешать все пули. Если пуля вылетает за границу экрана, она удаляется, а не появляется с противоположной стороны.

function bulletsMove() {

// Передвигаем все пули.

for(i=bullets.length-1; i>=0; i--) {

// Перемещаем пулю по вертикали и горизонтали,

bulletsti]._х += bullets[i].dx;

bullets [ij ._y += bullets [i] .dy;

// Выясняем, вылетела ли пуля за границу экрана,

if ((bullets[i]._x > 550) or (bullets[i]._x < 0) or (bullets[i]._y > 400) or (bullets[i]._y < 0)) {



// Нельзя сделать следующий шаг в течение 50 миллисекунд,

fox.nextmove = getTimer() + 50;

// Перемещаем лису.

fox._x += fox.move.x*5;

fox._y += fox.move.y*5;

// Определяем, прошла ли лиса сквозь тоннель,

if (fox._x > 550) fox._x = 0;

if (fox._x < 0) fox._x = 550;

// Проверяем, достигла ли лиса положения своей цели,

if ((fox._x == fox.dest.x) and (fox.__y == fox.dest.у)) {

eatBerry();

nextMove();

}}}

Для того чтобы лиса съела ягоду, нужно просмотреть массив berries и определить, совпадает ли положение какой-либо ягоды с положением лисы. Если да, то клип этой ягоды переходит ко второму кадру, ягода исчезает, а количество очков увеличивается.
Так как в поисках нужной ягоды вы просматриваете массив berries, можете посчитать, сколько ягод не было съедено. Если была найдена не съеденная ягода, то уровень не заканчивается.

function eatBerry() {

// Предположим, что все ягоды были съедены.

allGone = true;

// Просматриваем массив berries,

for (i=0; i<berries.length; i++) {

// Выясняем, находится ли ягода там же, где и лиса.

if ((berries[i]._currentFrame == 1) and (berries[i]._x == fox._x) and (berries[i]._y == fox._y)) {

// Удаляем ягоду.

berries[i].gotoAndStop("nothing");

// Лиса открывает рот.

fox.gotoAndPlay("eat");

// Увеличиваем число очков.

score++;

// Если какая-то ягода еще не съедена,

// то уровень не закончен.

} else if (berries[i]._currentFrame== 1){

allGone = false;

}} // ЕСЛИ все ягоды были съедены, уровень завершен.

if (allGone) {

gotoAndPlay("level over");

gameLevel++;

}}

Когда лиса доходит до ягоды, необходимо определить следующее положение цели. С помощью объекта Key можно проверить все четыре клавиши со стрелками, если нажата одна из них, для лисы определяется
объект move. Однако это не значит, что лиса будет двигаться в указанном направлении.
Для того чтобы лиса могла сделать шаг, необходимо, чтобы в том направлении на расстоянии ровно в 25 пикселов находился клип ягоды.
Если же его там нет, то свойство move объекта обнуляется.



ship._x += ship.dx;

ship._y += ship.dy;}

Функция checkPorLand проверяет массив footPoints: находится ли хоть одна опора лунохода внутри клипа "pad". Если там нет ни одной опоры, переменной landed присваивается значение false. Такое же значение присваивается и в том случае, когда скорость лунохода больше трех единиц, поскольку данная скорость слишком высока для того, чтобы луноход смог совершить посадку.
Если после этого значение переменной landed все еще равно true, значит, луноход удачно совершил посадку. Все, что, теперь необходимо сделать, - перейти к следующему кадру в основной временной шкале и увеличить значение переменной gameLevel на единицу.

function checkForLand() {

// Выясняем, обе ли опоры находятся на посадочной площадке. landed = true;

for(i=0; i

// Просматриваем все площадки.

footDown = false;

for(j=0; j

// Проверяем, находится ли опора на площадке,

if (pads[j].hitTest(ship._x+footPoints[i].x, ship._y+footPoints[i].y, true)) {

footDown = true;

break;}}

// Если опора не находится на площадке,

// значит, корабль не совершил посадку,

if (!footDown) {

landed = false;

break;}} // Проверяем, не слишком ли быстра движется корабль.

if (ship.dy > 3.0) landed = false;

if (landed) {

// Посадка совершена. gotoAndPlay(_currentFrame+1);

gameLevel++;

}}

С другой стороны, необходимо проверять, взорвался луноход или нет. В массиве hitPoints содержится список координат точек вокруг корабля: двух опор, середины каждой стороны, вершины и центра днища. Так как невозможно определить, полностью ли один объект накладывается на другой, вы просто проверяете эти точки. Если какая-то из них оказалась внутри элемента "activeground", тогда корабль разбился. У клипа "Ground - level X" на каждом уровне - имя экземпляра "activeground".

function checkForCrash() {

// Корабль не совершил посадку. Проверяем, коснулся ли он

// поверхности Луны,

if (Handed) {

// Просматриваем все возможные точки касания.

for(i=0; i

// Проверяем, не коснулся ли корабль поверхности



function moveFox() {

(1) // Определяем границы возможного перемещения лисы.

foxBounds = determineBounds(foxPos);

(2) // Если под лисой пусто, она начинает падать.

if ((foxBounds.bottom > 0) and (!falling)) falling = true;

(3)// Падение.

if (falling) checkFall();

(4) // Если нажата левая стрелка, то движемся влево, если там

// нет препятствия.

if (Key.isDownfKey.LEFT)) {

if (foxSpeed < foxBounds.left) {

foxPos.x -= foxSpeed;}

if (foxPos.x < 0) foxPos.x = 0;

fox._xscale = 25;

moving = true;

// Если нажата правая стрелка, то движемся вправо, если там

// нет препятствия.

} else if (Key.isDown(Key.RIGHT)) {

if (foxSpeed < foxBounds.right) {

foxPos.x += foxSpeed;}

if (foxPos.x > worldEnd) foxPos.x = worldEnd;

fox._xscale = -25;

moving = true;

// Если не движемся.

} else {

moving = false;}

(5)// Если стоим на поверхности и нажат пробел - прыгаем,

if (Key.isDown(Key.SPACE) and (!falling)) {

fallSpeed = jumpPower;
// Прыжок = падение вверх

falling = true;

if (Jmoving) {
// Используем анимацию прыжка только

// если лиса не идет.

fox.gotoAndPlay("jump");}}

(6)// Если идет и не падает, то анимируем ходьбу,

if (moving and !falling) { fox.nextFrame();

// Если не идет или падает - кадр со стоящей лисой.

} else if (imoving and !falling) {

fox.gotoAndStop(1);

}

(7)// Позиция лисы по вертикали.

fox._y = floor - foxPos.у;

// Активируем кролика.

moveBunnies ();

// Перерисовываем все объекты в соответствии с новой

// позицией.

drawObjects();

// Проверяем,не съеден ли орех.

getAcorns();}

Функция determineBounds выглядит сложно, но на самом деле она довольно простая. Вначале мы предполагам, что пространство слева, справа и сверху вокруг лисы пустое на расстоянии 1000 пикселов. Также полагаем, что нет пустого пространства под лисой. Вертикальную позицию лисы мы храним в свойстве pos.у.
Далее следует цикл по всем объектам типа box. Вычисляется расстояние от лисы до блока и записывается в переменные dx и dy.
Если блок занимает то же положение по вертикали, что и лиса (другими словами - если он на том же расстоянии от земли), то функция проверяет, находится ли он справа или слева. Далее проверяется, если расстояние до блока справа (слева) меньше текущего значения bounds.right (.left), то значение bounds.right (.left) переопределяется. Аналогично проверяются вертикальные границы.
После того как все блоки были проверены, объект bounds содержит горизонтальные и вертикальные границы для лисы в текущем положении. Например, если bounds.left равно 20, то ближайший к лисе блок справа находится на расстоянии 20 пикселов.
Функция determineBounds написана в достаточно общем виде, чтобы ее можно было использовать как для лисы, так и для кроликов. В качестве аргумента pos функции можно передать как объект foxPos, так и элемент массива objects, например кролика.


Содержание раздела