Создание кода
Для этой игры необходимы лишь три функции (посмотрите исходный файл, Wallball.fla). Все эти три функции будут вызываться в клипе "actions”:
onClipEevent(load) {
_root.initGame();
}
onClipEvent(enterFrame) {
_root.moveBall();
_root.movePaddle () ;
}
Функции находятся в основной временной шкале. Первая функция, initGame, хранит положение мяча в переменных х и у. Указаны значения dx и dy, то есть скорость мяча по вертикали и горизонтали (5 пикселов в кадре каждая). Затем функция initGame устанавливает несколько постоянных, определяющих положение каждой стены. Этой функции передается значение радиуса мяча, которое также используется функцией moveBall. Переменной passedPaddle присваивается значение true после того, как ифок пропустит мяч. При этом надо спрятать курсор, чтобы он не отвлекал внимание игрока.
function initGame() {
// Устанавливаем начальное положение мяча,
х = Ьа11._х;
у = ball._y;
// Указываем начальную скорость,
dx = 5;
dy = 5;
// Устанавливаем значения постоянных.
rightwali = 550;
leftWall = 0;
topWall = 0;
bottomWall = 4 4 0;
ballRadius = ball._width/2 passedPaddle = false;
// Прячем курсор.
Mouse.hide();
}
Функция movePaddle - "рабочая лошадка" этой игры. Сначала она изменяет значение х и у на величину значений dx и dy соответственно, чтобы получить новое положение мяча (1). Затем проверяет, пролетел ли мяч сквозь стену или нет (2).
К радиусу мяча прибавляется значение его положения, чтобы получить точную позицию правого края мяча. Если мяч оказался за стеной, функция movePaddle подсчитывает, как далеко он перелетел, и присваивает это значение переменной overshoot. Затем мяч перемешается назад на расстояние, в два раза превышающее значение overshoot. Направление мяча меняется при умножении dx на -1, таким образом, знак dx меняется на противоположный. Если значение dx до столкновения мяча со стеной было равно 5, то после этого события становится равным -5.
Затем код проверяет, пролетел ли мяч сквозь нижнюю стену или нет (3). Этот фрагмент похож на предыдущий, только вместо х и dx используются величины у и dy.
Фрагмент кода, где проверяется, пролетел ли мяч через верхнюю стену, несколько отличается от уже рассмотренных (4). Для определения положения верхней границы мяча из положения его центра вычитается радиус. Затем величина overshoot рассчитывается как разница между положениями стены и верхней границы мяча.
Для того чтобы определить, ударился ли мяч о биту или нет, сначала код рассчитывает положение правой границы биты (5). Потом, если мяч находится достаточно близко к бите, рассчитываются верхняя и нижняя границы, а затем определяется, пересекаются ли мяч и бита (6).
Если мяч сталкивается с битой, то он ведет себя так же, как и при столкновении со стеной. Однако при этом скорость мяча увеличивается на 5% (7). Если мяч перелетает через стену, совершается только одно действие - переменной passedPaddle присваивается значение true.
Если значение переменной passedPaddle равно true, и мяч находится там, где должна быть левая стена, игра заканчивается (8). Курсор возвращается в исходное положение, и ролик переходит к кадру "game over".
В конце функции moveBall положение мяча устанавливается в соответствии со значениями х и у.
Прежде чем будет запушен кадр игры, в кадре "start game" необходимо определить две важные переменные: начальную скорость движения мяча по вертикали и количество мячей, которые могут быть поданы.
dy = 3;
numBalls = 3;
stop() ;
Когда происходит переход к кадру "play", с помощью клипа "actions» можно регулярно вызывать функции. В данной игре все столкновения с мячом или стенами должны быть учтены в функции moveBall, но для блоков была создана отдельная функция - checkCollisions.
onClipEvent(load) {
_root.startBall();
onClipEvent(enterFrame) {
_root.moveBall();
_root.movePaddle();
_root.checkCollisions();
}
Когда начинается кадр "play", подается мяч. Положение мяча определяется тем, где он появляется на рабочем поле. Скорость мяча по горизонтали всегда равна 3, направление движения - вправо. Скорость по вертикали указывается в первом кадре, где величине dy было присвоено значение 3. Однако это значение изменится перед следующим уровнем.
Вдобавок к параметрам мяча воспользуйтесь возможностью и установите некоторые значения, которые не будут изменяться во время игры.
function startBall() {
// Определяем начальное положение мяча,
х = ball._x;
у = ball._y;
// Устанавливаем начальную скорость по горизонтали,
dx = 3;
// Прячем курсор.
Mouse.hide();
// Задаем значения констант.
rightWall = 550;
leftWall = 0;
topWall = 0;
bottomWall = 400;
ballRadius = ball,_width/2;
paddleTop = paddle._y-paddle._height/2;
paddleBottom = paddle._y+paddle.__height/2;
}
Следующая функция управляет битой, выравнивая ее по горизонтали в соответствии с движением мыши.
// Бита следует за курсором,
function movePaddle() {
paddle._x = _xmouse;
}
Следующая функция покажется вам знакомой, так как она очень похожа на функцию moveBall, которая используется в других играх этой главы. Однако есть и некоторые отличия.
Для того чтобы узнать, ударился ли мяч о биту, код проверяет, полностью ли они перекрываются (13). Затем, если все-таки столкновение произошло, скорость мяча по горизонтали определяется тем, где именно мяч ударился о биту (14). К тому же код для определения, пропущен ли мяч, проще, так как он просто проверяет, пролетел ли мяч сквозь нижнюю стену или нет (15).
Код состоит в основном из функций, расположенных во втором кадре. Первая начинает игру. Вместо отдельных переменных для хранения х, у и z значений мяча, мы используем один объект, ballpos, который имеет о свойства. Таким образом, ballpos .x соответствует x-положению мяча. То же самое мы делаем для ballvel, где содержатся х, у и z скорости мяча.
В начале игры значения свойств объекта bollpos устанавливаются таким образом, чтобы мяч начинал свое движение от задней стенки параллелепипеда. Значения объекта ballvel задают начальное движение мяча строго вдоль оси Oz и скорость на единицу большую номера уровня игры (то есть 2).
Следующая часть функции initGame создает 16 блоков из одного библиотечного образца и покрывает ими всю заднюю стенку. В заключении функции мы устанавливаем уровень биты и шара так, чтобы они были расположены поверх созданных кирпичей.
function initGame() {
// Устанавливаем мяч.
ballpos = {х:200, у:200, z:140};
// Определяем его скорость.
ballvel = {х:0, у:0, z:-(1+gameLevel)};
// Создаем блоки,
bricks = new Array();
for(var x=0;x
for(var y=0;y
brick = attachMovie("brick","brick"+x+y,x+y*4);
brick._x = 155+30*x;
brick._y = 155+30*y;
bricks.push(brick);
// Перемещаем биту и шар на передний план.
paddle.swapDepths(101);
ball.swapDepths(100);
}
Клип "actions" вызывает всего две функции.
onClipEvent(enterFrame) {
_root.movePaddle();
_root.moveBall(); }
Первая из этих функций, movePaddle, очень простая. Она устанавливает биту в позицию курсора.
function movPaddle() {
//Положение биты соответствует положению курсора.
Paddle._x=_root._xmouse;
Paddle._y=_root._ymouse;
}
А вот функция moveBall выполняет очень много действий. Вначале переопределяются координаты мяча (объект ballpos) с помощью значений объекта ballvel (16).
Затем вычисляется положение мяча на экране (17). Координата х определяется как значение ballpos. х, подкорректированное в соответствии со значением ballpos.z. Чем глубже находится шар, тем большую величину составляет поправка. Второй множитель поправки определяется тем, насколько далеко находится шар от стенок колодца. Если, например, шар находится ровно посередине между стенкой и центральной осью, то есть ballpos.х = 100 или (-100), то поправка будет равняться значению ballpos.z (ballpos.z соответственно). Если вы не вполне поняли логику этих рассуждений, попробуйте поменять различные параметры объекта bollpos и посмотрите на результат.
Следующий фрагмент кода устанавливает значение масштаба шара в соответствие со значением ballpos.z (18). Поскольку максимальное значение ballpos.z составляет 140, то минимальный масштаб составляет (200-140)/2, то есть 35%.
Далее мы устанавливаем масштаб клипа "ring" (19). Этот клип выполняет роль указателя, помогающего понять, на какой глубине находится шар в данный момент.
Если шар сталкивается с одной из стен параллелепипеда (20), происходит отражение от стенки. Проверка выполняется для всех четырех стен.
Столкновение с задней стенкой (21) обрабатывается несколько сложнее. Значение z меняется на противоположное. Кроме того, клипы блоков проверяют, куда именно врезался шар. Блок, с которым произошло столкновение, удаляется, и счет увеличивается.
Передней стенки у нас нет, но на ее месте располагается бита. Если параметр z принимает значение 0, клип биты проверяет, попал ли в него? шар (22). Бита имеет размер 70x70, так что шар должен находиться не далее чем в 35 пикселях по каждой из координат от центра биты. При столкновении определяются новые значения скорости шара в соответствии с расстоянием от центра биты до места столкновения (23). При столкновении строго по центру шар отражается отвесно, тогда как отражение, например, от левой стороны отклоняет мяч влево и т.д.
При столкновении с битой ее параметр _alpha на мгновение принимает значение 90 (24). В следующем кадре значение восстанавливается (26).
Если шар пролетает мимо биты, игра заканчивается (25). Если же все блоки оказываются выбиты, игрок переходит на следующий уровень.
В сценарий предыдущего ролика необходимо внести некоторые изменения. Изменить существующие функции и добавить одну новую. Приведем сценарий клипа "actions", который вызывает новую функцию moveComputerPaddle:
onClipEvent(load) {
_root.startLevel();
}
onClipEvent(enterFrame) {
_root.moveBall ();
_root.movePaddle() ;
_root.moveComputerPaddle();
}
Вместо функции startGame в этой игре используется функция startLevel, которая обладает всеми возможностями функции startGame и в дополнение к ним указывает, что мяч будет двигаться в произвольном направлении. Достичь этого можно, определив, что мяч в 50% случаев подается вверх, в 50% случаев - вниз, также в 50% случаев - влево и в 50% случаев - вправо. То есть вы получаете четыре возможных направления движения мяча по диагонали.
function startLevel() {
// Определяем начальное положение мяча,
х = ball._x;
у = ball._y;
// Указываем начальную скорость и одно из четырех
// произвольных направлений по диагонали,
dx = 5;
dy = 5;
if (Math.random() < .5) dx *= -1;
if (Math.random() < .5) dy *= -1;
// Прячем курсор. Mouse.hide();
// Устанавливаем значения констант.
rightWall = 550;
leftWall = 0;
topWall = 0;
bottomWall = 400;
ballRadius = ball._width/2;
passedPaddle = false;
}
Теперь в функцию moveBall включен код для определения, пролетел ли мяч мимо биты компьютера или нет (10). Он похож на код, обрабатывающий биту игрока (9), и идентичен соответствующему фрагменту кода предыдущей игры.
Когда мяч пролетает с правой (11) или с левой (12) стороны, обычно игра возвращается к кадру "start level". Однако если не осталось больше мячей, программа переходит к кадру завершения игры, "game over". В зависимости от того, кто пропустил мяч, очко записывается либо игроку, либо компьютеру (переменной playerScore или computerScore).
function moveBall() {
// Изменяем координаты х и у.
х += dx;
y += dy;
// Проверяем, попал ли мяч в нижнюю стену,
if (y+ballRadius > bottomWall) {