Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript
Шрифт:
Определение областей, в которых возможно (невозможно) передвижение лисы, является важнейшей задачей этой игры. Если лиса упирается в блок, она должна остановить свое перемещение в этой позиции.
Эта задача реализована посредством постоянного сравнения положения лисы с положениями всех блоков. Если блок находится к игроку ближе других блоков в этом направлении, тогда его координаты принимаются за самую далекую точку в данном направлении, до которой возможно перемещение лисы. Например, если блок находится на расстоянии 200 пикселов вправо от лисы, значит, лиса не может быть перемещена далее чем на 200 пикселов вправо. Если же в процессе проверки всех остальных блоков обнаружен блок, находящийся на расстоянии 100 пикселов от лисы, то значение 100 принимается как максимальное для возможного перемещения лисы в данном направлении.
То же самое происходит и по вертикали. Когда лиса прыгает, ей передается значение скорости по вертикали. При каждом обращении к кадру эта скорость регулируется за счет воздействия силы тяжести, так что лиса постепенно замедляется, а затем падает обратно
Подготовка ролика
Ролик содержит всего четыре клипа. Клип «fox» содержит некоторое количество кадров. В первом кадре изображена неподвижная лиса, далее некоторое количество кадров изображают анимацию бегущей (в одном напрвлении) лисы, и последние кадры изображают лису в прыжке. Имя экземпляра этого клипа на рабочем столе также «fox»; для экземпляра выставлен масштаб 25 %.
Клип "box" – это просто коричневый квадрат размером 50x50. Этот клип содержит один кадр.
Клип "acorn" начинается с кадра со статичным изображением ореха. В этом кадре находится команда stop. Остальная часть клипа изображает постепенное появление числа "100". Эта анимация проигрывается, когда игрок берет орех и ему начисляются очки.
Клип "bunny" состоит из двух кадров изображающих кролика, шевелящего лапками. Эта анимация работает независимо от направления перемещения кролика.
Клипам "box", "acorn" и "bunny" необходимо присвоить имена в панели Linkage Properties, чтобы был возможен их экспорт.
В главной временной шкале находятся три кадра. Первый содержит инструкции и кнопку Play, последний содержит сообщение "Game Over". В среднем кадре "Play" находится лиса и фон, изображающий землю. Все остальные элементы будут созданы программно при запуске игры.
Создание кода
За небольшими исключениями весь код этой игры находится в кадре «Play». Он начинается с вызова функции startGame. Она инициализирует набор констант таких как скорость лисы и кролика, устанавливает начальное положение лисы и вызывает функции createWorld и creatOjects, которые создают все элементы игрового пространства.
startGame;
stop;
function startGame {
// Устанавливаем константы.
floor = 350;
foxSpeed = 10;
bunnySpeed = 2;
jumpPower = 60;
// Задаем параметры лисы.
foxPos = {x:0,y:0};
fallSpeed = 0;
falling = false;
fox.swapDepths(999);
// При каждом обращении к кадру вызываем moveFox.
_root.onEnterFrame = moveFox;
// Создаем элементы игры.
createWorld;
createObjects;
}Функция creatWord создает массив objects и заполняет его положением всех блоков, орехов и кроликов. Она также задает глобальную переменную worldEnd, которая определяет правую границу игрового пространства.
function createWorld {
objects = new Array;
objects.push({type:"box", x:250, y:0});
objects.push({type:"box", x:300, y:0});
objects.push({type:"box", x:500, y:0});
objects.push({type:"box", x:550, y:0});
objects.push({type:"box", x:600, y:0});
objects.push({type:"box", x:650, y:0});
objects.push({type:"box", x:700, y:0});
objects.push({type:"box", x:550, y:50});
objects.push({type:"box", x:600, y:50});
objects.push({type:"box", x:650, y:50});
objects.push({type:"box", x:850, y:0});
objects.push({type:"box", x:900, y:0});
objects.push({type:"box", x:1050, y:100});
objects.push({type:"box", x:1100, y:100});
objects.push({type:"box", x:1150, y:100});
objects.push({type:"acorn", x:150, y:0});
objects.push({type:"acorn", x:275, y:200});
objects.push({type:"acorn", x:1100, y:250});
objects.push({type:"bunny", x:400, y:0});
objects.push({type:"bunny", x:1200, y:0});
worldEnd = 1400;
}Совет
Если вы собираетесь сделать пространство игры больше или, возможно, хотите добавить новые уровни, то, вероятно, вы захотите изменить функцию creatWord так, чтобы она считывала данные из внешнего текстового файла вместо того, чтобы создавать каждый элемент в отдельной строке кода. Текстовый файл может определять тип и расположение каждого элемента в отдельных позициях так, как это было сделано в главе 12.
После создания массива objects функция creatObjects просматривает его в цикле и создает все соответствующие клипы.
function createObjects {
for(var i=0;i<objects.length;i++) {
_root.attachMovie(objects[i].type,"object "+i, i );
}
}Функция moveFox – это главный движущий механизм [19] всей игры. В ней идет ряд проверок, которые отслеживают появление определенных событий в игре.
Сначала вызывается функция 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. Значит, чтобы получить свойство _y клипа лисы, мы должны вычесть foxPos.y из значения переменной floor (7).
В конце функции moveFox вызываются еще три функции: moveBunnies отвечает за движение кроликов, drawObjects перерисовывает блоки, кроликов и орехи в соответствии с новым положением игрового поля относительно лисы, а функция getAcorns проверяет, не съела ли лиса какой-нибудь из орехов.function moveFox {
(1) → // Определяем границы возможного перемещения лисы.
foxBounds = determineBounds(foxPos);
(2) → // Если под лисой пусто, она начинает падать.
if ((foxBounds.bottom > 0) and (!falling)) falling = true;
(3) → // Падение.
if (falling) checkFall;
(4) → // Если нажата левая стрелка, то движемся влево, если там нет препятствия.
if (Key.isDown(Key.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 (!moving) { // Используем анимацию прыжка только если лиса не идет.
fox.gotoAndPlay("jump");
}
}
(6) → // Если идет и не падает, то анимируем ходьбу.
if (moving and !falling) {
fox.nextFrame;
// Если не идет или падает – кадр со стоящей лисой.
} else if (!moving and !falling) {
fox.gotoAndStop(1);
}
(7) → // Позиция лисы по вертикали.
fox._y = floor – foxPos.y;
// Активируем кролика.
moveBunnies;
// Перерисовываем все объекты в соответствии с новой позицией.
drawObjects;
// Проверяем, не съеден ли орех.
getAcorns;
}Функция determineBounds выглядит сложно, но на самом деле она двольно простая. Вначале мы предполагам, что пространство слева, справа и сверху вокруг лисы пустое на расстоянии 1000 пикселов. Также полагаем, что нет пустого пространства под лисой. Вертикальную позицию лисы мы храним в свойстве pos.y.
Далее следует цикл по всем объектам типа box. Вычисляется расстояние от лисы до блока и записывается в переменные dx и dy.
Если блок занимает то же положение по вертикали, что и лиса (другими словами – если он на том же расстоянии от земли), то функция проверяет, находится ли он справа или слева. Далее проверяется, если расстояние до блока справа (слева) меньше текущего значения bounds.right (.left) , то значение bounds. right (. left) переопределяется. Аналогично проверяются вертикальные границы.
После того как все блоки были проверены, объект bounds содержит горизонтальные и вертикальные границы для лисы в текущем положении. Например, если bounds.left равно 20, то ближайший к лисе блок справа находится на расстоянии 20 пикселов.
Функция determineBounds написана в достаточно общем виде, чтобы ее можно было использовать как для лисы, так и для кроликов. В качестве аргумента pos функции можно передать как объект foxPos, так и элемент массива objects, например кролика.