Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript - Гэри Розенцвейг
Шрифт:
Интервал:
Закладка:
dy = _ymouse – straw._y;
// Вычисляем угол наклона.
strawRadians = Math.atan2(dy,dx);
// Переводим полученное значение в градусы.
strawDegrees = 360*strawRadians/(2*Math.PI);
straw._rotation = strawDegrees;
}
Теперь при запуске пули в массив bullets будет записано больше информации. Чтобы осуществлять перемещение объекта-пули в каждом кадре, нам необходимо знать угол, под которым он был выпущен.
К каждому объекту массива bullets будет добавлен параметр down, описывающий силу гравитации, действующую на пулю. Исходное значение этого параметра – 0.
Для того чтобы пуля вылетала из кончика соломинки, ее координаты должны иметь значение, равное значению координат соломинки плюс 20 пикселов (длина соломинки чуть больше 20 пикселов). Эти пикселы необходимо распределить (найти значения катетов при заданной гипотенузе и угле) между координатами x и y при помощи функций Math.sin и Math.cos для того, чтобы получить горизонтальную и вертикальную стороны угла....Примечание
Функции Math.sin и Math.cos используются здесь для определения горизонтальной и вертикальной сторон угла. Для того чтобы наглядно представить это, возьмем круг, центр которого находится в точке 0,0; крайняя верхняя точка имеет координаты 0, -1 [13] ; крайняя правая – 1,0. Задав в функции Math.sin любой угол, вы получите координату y этого угла на окружности. Функция Math.cos позволяет вычислить координату х. Таким образом, значение Math.sin(0) будет равно (-1), значение Math.cos(0) – 0, что соответствует координатам 0, -1.
Более важно понять то, что перемещение имеет две составляющие: скорость и угол. Значения расстояний для монитора компьютера не могут быть заданы по диагонали, они задаются только по вертикали и горизонтали. Функции Math.sin и Math.cos позволяют преобразовать значения скорости и угла в расстояние по горизонтали и вертикали.
function shootBullet() {
// Проверяем, можно ли выстреливать следующую пулю.
if (getTiner() > nextBulletTime) {
// Создаем пулю.
attachMovie("bullet","bullet"+nextBullet,nextBullet+9999);
bullet = _root["bullet"+nextBullet];
// Устанавливаем координаты.
bullet._x = straw._x + Math.cos(strawRadians)*20;
bullet._y = straw._y + Math.cos(strawRadians)*20;
// Добавляем в массив информацию о пуле:
// clip = название клипа,
// angle = начальный угол,
// down = эффект гравитации.
bullets.push({clip:bullet,angle:strawRadians,down:0});
// Увеличиваем счетчик пуль.
nextBullet++;
nextBulletTime = getTimer()+1000;
}
}Функция moveBullets использует параметры angle и down каждого снаряда для перемещения их на определенное расстояние. Кроме этого параметр down увеличивается, чтобы создавался эффект гравитации. Так как запущенный снаряд должен снова упасть на землю, прежде чем удалить его клип из массива, необходимо проверить, достиг ли он нижнего края экрана.
function moveBullets() {
// Перемещаем все снаряды.
for(i=bullets.length-1;i>=0;i–) {
// Определяем название клипа.
bullet = bullets[i].clip;
// Перемещаем клип.
bullet._x += Math.cos(bullets[i].angle)*10;
bullet._y += Math.sin(bullets[i].angle)*10;
// Добавляем искажение траектории
// из-за воздействия гравитации.
bullet._y += bullets[i].down;
// Увеличиваем значение параметра гравитации.
bullets[i].down += .2;
// Выясняем, достигла ли пуля земли.
if (bullet._y > 400) {
bullet.removeMovieClip();
bullets.splice(i,1);
// Определяем, есть ли попадение.
} else {
if (checkCollision(bullet)) {
bullet.removeMovieClip();
bullets.splice(i,1);
}
}
}
}К сведению
Так как пули в данной игре могут разлетаться в разные стороны, мы поменяли изображение пули в клипе, теперь она напоминает не короткую линию, а скорее небольшую точку.
Другие возможности
Как и предыдущую игру этой главы, только что рассмотренную можно усовершенствовать различными способами, например можно добавлять очки за шары, летящие выше и быстрее. Неплохим вариантом будет создание на ее основе игры, где в качестве целей будут использоваться самолеты. Оружие, из которого ведется обстрел, обычно в таких играх неподвижно, но может стрелять под разными углами.
Шарики-захватчики
Исходный файл: Ballooninvaders.fla
В самой классической видеоигре, "Космические захватчики", есть очень странное, но запоминающееся поведение вражеских единиц. Они движутся группой из стороны в сторону, медленно опускаясь вниз. Если они достигнут поверхности, игрок проигрывает.
Давайте изменим первую игру данной главы так, чтобы воздушные шарики вели себя как космические захватчики.
Задачи проекта
Поведение шариков простое. Они образуют группу шириной 10 и высотой 3 шарика, как показано на рис. 10.5. Шарики движутся вправо, пока первая колонна шариков не коснется правой стороны экрана. Тогда они меняют направление и чуть-чуть опускаются.
Рисунок 10.5. Шарики-захватчики движутся группой
Между тем лиса внизу движется слева направо и стреляет в шарики. Она должна перестрелять их всех, прежде чем группа шариков достигнет поверхности земли.
Подход
Поведение лисы может остаться таким же, как в первой игре этой главы. Но поведение шариков должно быть полностью изменено. К тому же во время игры не должно быть создано ни одного нового шарика. Они все появляются в начале игры.
Подготовка ролика
Как и в первой игре этой главы, есть кадр стоящей лисы – «stand», и анимация ходьбы. У шарика есть нормальный кадр и анимация взрыва. Все шарики сначала серого цвета и потом раскрашиваются с помощью ActionScript. Пуля – это короткий клип-линия.
Создание кода
Клип «actions» такой же, как в первой игре этой главы, за исключением того, что новые шарики не создаются в каждом кадре.onClipEvent(load) {
_root.initGame();
}
onClipEvent(enterFrame) {
_root.moveBalloons();
_root.moveFox();
_root.moveBullets();
}Функция initGame вызывает функцию createBalloons, чтобы создать группу шариков. Ей не нужно задавать такие переменные, как nextBalloon или создавать массив balloons, поскольку после начала игры новые шарики не создаются.
function initGame() {
// Создаем шарики.
createBalloons();
// Параметры снарядов.
nextBulletTime = 0;
nextBullet = 0;
bullets = [];
// Переменная счета.
score = 0;
}Функция createBalloons создает 30 шариков в 10 колонках по 3 штуки в каждой. Каждая ссылка на шарик хранится в массиве. Цвет шарику назначается в зависимости от того, в каком он ряду. Каждому шарику придано начальное направление и скорость равная 3.
function createBalloons() {
balloons = new Array();
balloonNum = 0;
// Создаем новый ряд.
for(var y=0;y<3;y++) {
for(var x=0;x<10;x++) {
// Создаем и размещаем новый шарик.
attachMovie("balloon", "balloon"+balloonNum, balloonNum);
balloonClip = this["balloon"+balloonNum];
balloonClip._x = x*30+20;
balloonClip._y = y*30+20;
// Добавляем в массив.
balloons.push(balloonClip);
// Устанавливаем цвет.
balloonColor = new Color(balloonClip);
if (y == 0) {
balloonColor.setTransform({rb: 255});
} else if (y == 1) {
balloonColor.setTransform({gb: 255});
} else if (y == 2) {
balloonColor.setTransform({bb: 255});
}
balloonNum++;
}
}
// Направление (скорость)шариков.
balloonDirection = 3;
}Функция moveBalloons двигает все шарики в массиве balloons. Если какой-нибудь из них дотронется до края экрана, то все они меняют направление. Если же какой-нибудь достигнет низа экрана, игра заканчивается.
function moveBalloons() {
// Переменная-флаг изменения направления.
var newDirection = false;
// Просматриваем все шарики.
for(var i=0;i<balloons.length;i++) {
// Передвигаем текущий шарик.
balloons[i]._x += balloonDirection;
// Смотрим, не достиг ли шарик границы экрана.
if ((balloonDirection > 0) and (balloons[i]._x > 530)) {
newDirection = true;
} else if ((balloonDirection < 0) and (balloons[i]._x < 20)) {
newDirection = true;
}
}
// При столкновении с границой экрана
// шарики опускаются и меняют направление.
if (newDirection) {
balloonDirection *= -1;
for(var i=0;i<balloons.length;i++) {
balloons[i]._y += 3;
}
}
// Не достигли ли шарики земли?
if (balloons[i-1]._y > 300) {
gotoAndStop("game over");
}
}Все функции для создания лисы и пуль точно такие же, как и в первой игре главы, поэтому их код я здесь приводить не буду. Но функция checkCollision другая, поскольку она должна следить, не случилось ли так, что все шарики уничтожены, и заканчивать игру.
function checkCollision(bullet) {
// Просматриваем все шарики.
for(j=balloons.length-1;j>=0;j—) {
balloon = balloons[j];
// Смотрим не попала ли пуля в шарик.
if (distance(bullet,balloon) < 10) {
// Удаляем шар из массива.
balloons.splice(j,1);
// Переходим в кадр взрыва шарика.
balloon.gotoAndPlay(2);
// Увеличиваем счет.
score += 1;
// Если шаров больше нет – игра заканчивается.
if (balloons.length == 0) {
gotoAndStop("game over");
}
// Возвращаем значение true, так как попали в шарик.
return(true);
}
}
// Возвращаем false, поскольку попали в шарик.
return(false);
}
К сведению
Как и в исходной игре этой главы, здесь есть вводный и заключительный кадры. Я в обоих играх использую одинаковые кадры вне зависимости от того, выиграл игрок или проиграл. Вы можете сделать два разных кадра с соответствующим текстом в каждом.
Другие возможности
Чтобы сделать игру труднее, вы можете ускорить движение захватчиков. Сначала попробуйте увеличить расстояние, на которое они падают каждый раз. Также можно увеличить скорость, с которой они движутся из стороны в сторону.
Если вы хотите добавить в игру уровней, то можете создать переменную startSpeed, которая начинается со значения 3. Задайте эту скорость функции balloonDirection каждого шарика вместо жестко заданного "3". Пусть теперь после того, как все шарики выбиты, игрок переходит к экрану «level over». Когда он нажимает кнопку «play next level», startSpeed увеличивается, и ролик отправляется к кадру «play», где шарики появляются с новой, более высокой скоростью.