Глава 7. Прыжки
Взглянем на игру со стороны и добавим прыжки. Наш Герой сможет не только ходить влево-вправо при нажатии клавиш, но и прыгать при нажатии клавиши «пробел». Приступим. (Внимание. Меняется проекция. До этого у нас была проекция или взгляд на игру СВЕРХУ. Стремление добавить новую возможность для Героя - прыжки, автоматически приводит к переносу взгляда на пространство игры. Теперь мы глядим СПЕРЕДИ. Ось Х - горизонтальное движение, а ось У - движение по высоте. Появление высоты приводит к новым свойствам Героя - притяжение, скорость прыжка, состояние Героя. Поэтому не будем забывать про новый взгляд на игру. Кто хочет дальше развивать или расширять пространство игры при взгляде СВЕРХУ, должен запомнить эту точка поворота в игростроении, сесть на пенек, съесть пирожок и подумать. А, мы пойдем дальше! ) Основа прыжкаЛюбой прыжок начинается с поднятия себя в воздух. (Вообще то, с начала, надо присесть, а потом толкнуться и подняться. Приседание опускаем, переложим это на анимацию, но очень быструю.) Как вы помните, во Flash поднятие на экране соответствует уменьшению У координаты. Итак, прыжок - new_y=current_y-jumpspeed. Если мы делаем однократно, то Герой прыгнет на месте. При множестве прыжков скорость прыжка jumpspeed меняется, и вскоре Герой может взлететь в небо и не вернуться. Внимание. Т.к. прыжок ВВЕРХ - это уменьшение координаты по У, то скорость будет отрицательной, а в формулках все будет складываться. Для изменения скорости прыжка введем новую переменную "gravity". Притяжение возвращает Героя на землю. На каждом шаге мы добавляем притяжение к скорости прыжка: jumpspeed=jumpspee+gravity. Можно изменять значение притяжения. Если притяжение меньше, Герой будет взлетать выше (как шарик). Когда притяжение выше, Герой будет быстрее падать (как камень). Ну а так, как мы работаем с объектами, то разные объекты могут иметь разное притяжение. Давайте посмотрим это на примере. Скорость прыжка в начале составляет -10 и притяжение равно 2. На первом шаге, Герой поднимется на 10 пикселов вверх и скорость примет значение 8. На следующем шаге, поднятие составит 8, а скорость 6. После нескольких шагов, скорость станет равной 0 и Герой остановится. Затем скорость станет отрицательной и Герой начнет падать. Но, что делать, когда Герой прыгает под стенкой. Герой прыгает вверх, стукается башкой, его скорость прыжка падает до 0, и Герой падает вниз. На этом прыжок заканчивается. В играх на основе плиток очень важно не устанавливать скорость больше размера плитки. Если Герой получает такую скорость, то трудно проверить его встречу с плиткой, он может пролететь стенку. (Хорош Герой, как маг и волшебник.) Это хорошо именно для волшебников, в обычной игре это считается ошибкой. Как можно видеть, прыжок может быть совмещен с горизонтальным перемещением. Путь проверки тот же, только нужно проверить наличие препятствий в начале прыжка. (Т.е., если Герой прыгнул ВПЕРЕД - ВВЕРХ, то проверяем препятствия, прыгаем и ничего не боимся, т.к. все одно ничегго не проверяется, даже если там и будет стенка. ) Будь моим ГероемДобавим несколько свойств нашему Герою: char={xtile:2, ytile:1, speed:4, jumpstart:-18, gravity:2, jump:false};
Свойство speed скорость будет влиять на движение влево-вправо. Свойство jumpstart будет определять начальное значение скорости при прыжке. Притяжение gravity будет возвращать Героя на землю, а свойство jump будет использоваться в момент прыжка и определять состояние Героя, т.е. Герой может или быть в состоянии прыжка, или в любом другом состоянии (двигаться/стоять/сидеть/лежать). Следующая строка для изменения функции построения карты и указания местоположения Героя. В прежних примерах мы устанавливали Героя в центре плитки, но в действительности поставим Героя в основании плитки. char.y = ((char.ytile+1)*game.tileH)-char.height;
(Именно из-за смены проекции, теперь на пространство игры смотрим спереди и естественно Герой не может висеть в воздухе - гравитация. Если оставить взгляд СВЕРХУ и включить изометрию, то, действительно, все одно, где Герой будет стоять. прыжок в изометрии будет более красив, но здесь не описывается.) Функции changeMap и getMyCorners не требуют изменений.
Дайте мне ВетерДавайте начнем с функции detectKeys. Нам нужно добавить код, который будет проверять нажатие клавиши «Пробел» и можно удалить проверку нажатия клавиш вверх/вниз. (А как же движение по лестницам вверх/вниз, ну да ладно. Об этом будет сказано в свое время. Что сказал учитель, так, тому и быть.) //**************** // Функция: detectKeys // Назначение: Определение нажатых клавиш, вызывается в событии onClipEvents // Параметры: // Возвращает: // **************************** function detectKeys() { var ob = _root.char; // Объект var keyPressed = false; // Клавиша // Проверим (Нажат «Пробел» и объект не в прыжке) ? if (Key.isDown(Key.SPACE) and !ob.jump) { // Объект «в прыжке» ob.jump = true; // Скорость прыжка ob.jumpspeed = ob.jumpstart; }
// Проверим (Нажато Вправо)? if (Key.isDown(Key.RIGHT)) { // ДА перемещение вправо keyPressed=_root.moveChar(ob, 1, 0); // НЕТ Проверим (Нажато Влево)? } else if (Key.isDown(Key.LEFT)) { // ДА перемещение влево keyPressed=_root.moveChar(ob, -1, 0); }
// Проверим (Объект в прыжке)? if (ob.jump) { // ДА вызываем функцию Прыжок keyPressed=_root.jump(ob); }
// Проверим (Перемещение не проведено)? if (!keyPressed) { // ДА стоять зорька ob.clip.char.gotoAndStop(1); } else { // НЕТ показываем анимацию перемещения ob.clip.char.play();
}
}
Обратите внимание, мы запрещаем прыжок в прыжке проверкой (!ob.jump). Клавиша «Пробел» будет использоваться для запуска только нового прыжка, когда свойство объекта jump = false. Но если нажата клавиша «Пробел» и Герой еще не в прыжке, состояние Героя меняется, и он получает начальную скорость. После проверки нажатия клавиш влево/вправо, проверим состояние Героя и, если он в прыжке (аки лев рыкающий), то вызываем функцию "jump" (функция "jump" и свойство jump не одно и тоже, плохо, что они одинаково называются, звиняйте). Функция "jump" будет вызываться на каждом шаге, пока Герой летит в прыжке, т.е. свойство jump = true, ведь Герой еще летит, даже, когда мы отпустим клавишу «Пробел». В функции jump учтем притяжение при вычислении начальной скорости прыжка. Это уравновесит скорости и будем устанавливать скорость прыжка отношением высоты плитки к высоте объекта. Последняя строка вызывает функцию перемещения moveChar. //**************** // Функция: jump // Назначение: Вычисление скорости и координат при прыжке, показ анимации прыжка // Параметры: // ob - объект // Возвращает: // true - всегда // **************************** function jump (ob) { // Определяем скорость, здесь притяжение должно быть отрицательным, иначе скорость будет расти // Но у нас скорость отрицательна, т.к. прыжок вверх уменьшение по У ob.jumpspeed = ob.jumpspeed+ob.gravity; // Проверка (Скорость первая космическая)? if (ob.jumpspeed>game.tileH-char.height) { // ДА - Оставляем меньшую скорость ob.jumpspeed = game.tileH-char.height; }
// Проверим (Скорость отрицательна)? if (ob.jumpspeed<0) {
// ДА Летим вверх moveChar(ob, 0, -1, -1);
// НЕТ - Проверим (Скорость положительна)? } else if (ob.jumpspeed>0) { // ДА Падаем вниз moveChar(ob, 0, 1, 1); }
return (true);
}
Также нужно изменить функцию moveChar. В предыдущей версии функции мы использовали свойство ob.speed, чтобы изменить позицию объекта. Теперь добавим скорость прыжка jumpspeed, которая меняется на каждом шаге. Изменения и в заголовке функции moveChar: function moveChar(ob, dirx, diry, jump) { if (Math.abs(jump)==1) { speed=ob.jumpspeed*jump; } else { speed=ob.speed; }
...
Параметр jump будет принимать значения 1 или -1 только при вызове функции moveChar из функции jump, в этом случае, скорость speed будет определяться знаком и значением свойства jumpspeed. Когда функция вызывается по клавише влево/вправо скорость будет определяться скоростью перемещения объекта свойство ob.speed. Изменение строк в функции moveChar приводит к корректному значению при использовании функции. После этого в функции moveChar необходимо заменить использование ob.speed на speed в формулах определения координат. И еще, мы собирались изменить код при встрече с препятствием в прыжке. ob.y = ob.ytile*game.tileH+ob.height; ob.jumpspeed = 0;
В этом случае, прыжку конец. ob.y = (ob.ytile+1)*game.tileH-ob.height; ob.jump = false;
При движении влево/вправо добавим строку проверки хождения Героя по краю и момент начала падения. ob.x += speed*dirx; fall (ob);
Ба, а тут новая функция - fall. //**************** // Функция: fall // Назначение: Реализация падения объекта // Параметры: // ob - объект // Возвращает: // **************************** function fall (ob) { // Проверим (Объект НЕ в прыжке)? if (!ob.jump) { // ДА определим препятствия по углам getMyCorners (ob.x, ob.y+1, ob); // Проверим (Препятствий внизу нет)? if (ob.downleft and ob.downright) { // ДА падаем, состояние прыжок ob.jumpspeed = 0; ob.jump = true; }
}
}
Мы не можем падать, пока в прыжке, поэтому первое проверяем состояние Героя. Будем проверять препятствия ниже себя, поэтому ob.y+1 . Если препятствий ниже нет (внизу слева и справа), то будем считать, что наш Герой болтается в воздухе и медленно падает. Для корректного отображения ситуции «зависания в воздухе» (или левитации Героя), будем переводить Героя в состояние «в прыжке» и установим скорость прыжка равной 0. Итак, Герой начнет падать вниз, как ястреб на цыпленка. Исправление ошибок 16.01.2005. Я обновил управление максимумом скорости прыжка в функции, корректный код показан ниже. if (ob.jumpspeed>game.tileH-char.height) { ob.jumpspeed = game.tileH-char.height; }
Можно загрузить код и клипы отсюда. Есть вопросы - пишите мне на semikin@dionaholding.ru Продолжение Главы 7 - Облака Возвращение на Начало учебника
|