You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Игрострой для новичка<br />
Скорая<br />
помощь<br />
Если вам<br />
понадобится<br />
вывести на<br />
экране несколько<br />
одинаковых<br />
спрайтов, не<br />
вздумайте загружать<br />
их в разные слоты!<br />
Функция sprite()<br />
вполне справляется<br />
с отображением<br />
одной и той<br />
же картинки в<br />
точках с разными<br />
координатами.<br />
106 <strong>Linux</strong> <strong>Format</strong> Январь 2008<br />
Если вы пытались уклониться от астероида чересчур активно (он,<br />
конечно, неподвижен, но, как утверждал сперва Галилей, а потом<br />
Эйнштейн, все относительно), то не могли не заметить, что наша игра<br />
обладает одним маленьким недостатком – корабль легко исчезает за<br />
пределы видимости. Так происходит потому, что со временем значения<br />
координат x и y становится слишком большими и выходят за рамки<br />
отведенных 500 х 700 пикселей. Чтобы исправить ошибку, можно,<br />
например, добавить сразу после блока инструкций if следующий код:<br />
if (x=500){x=500;}<br />
if (y=700){y=700;}<br />
Происки врагов<br />
Инопланетные захватчики – это не мирные астероиды, и у кораблей,<br />
которые будут нас атаковать, возможны различные траектории движения.<br />
Какие именно – зависит от вас. Например, большой бомбардировщик<br />
может медленно перемещаться по диагонали экрана, методично<br />
сбрасывая смертельно опасные, но неповоротливые бомбы, а легкие<br />
истребители будут выделывать петли. Иными словами, траектории движения<br />
удобно связать с типом противника.<br />
Здесь, конечно, не помешает учебник математики, но особо усердствовать<br />
не стоит: если в знаменитой Galaga траектории достаточно<br />
сложны, это еще не значит, что существует прямая зависимость между<br />
их хитроумностью и увлекательностью игры. Попробуйте, для начала,<br />
ограничиться теми элементами, которые будут отвлекать вас на<br />
дополнительные действия. Например: вы увидели вражеский корабль<br />
и начинаете палить по нему из всех орудий. Если бы все было так просто,<br />
то секунду спустя его обломки уже затерялись бы в безбрежных<br />
просторах мирового эфира. Но вражеский корабль – крепкий орешек:<br />
он тоже делает выстрелы, и вам приходится уворачиваться от летящих<br />
снарядов, а тут еще этот шальной метеор, вынырнувший неизвестно<br />
откуда – и вот вам Game Over, которого никто не ждал. А сколько я там<br />
очков набрал? 4100? О, уже больше, чем в прошлый раз. А смогу больше?<br />
Собственно, это и называется «увлекательный геймплэй».<br />
Приведем несколько стандартных траекторий движения вражеских<br />
объектов для игр, подобных нашей.<br />
1 Сверху вниз по прямой:<br />
sprite(10, evil_x, evil_y);<br />
evil_y++;<br />
2 По диагонали слева направо (или наоборот – замените в последней<br />
строке знак «плюс» на «минус»).<br />
sprite(10, evil_x, evil_y);<br />
evil_y++; evil_x++;<br />
Попробуйте также изменять приращения evil_y и evil_x (например:<br />
evil_y+=3;). Интересной траектории можно добиться, добавив сюда<br />
фактор случайности (evil_x+=rand() %3;), а также внезапную смену<br />
направления движения.<br />
3 Движение по кругу. Это более сложный случай, но, в целом, формулы<br />
для координат имеют следующий вид: x=r*cos(a)+x0, y=r*sin(a)+y0,<br />
где r – радиус окружности, a – угол в радианах. Для использования<br />
тригонометрических функций (cos(), sin()) необходимо подключить<br />
заголовочный файл math.h и задействовать библиотеку libm (добавьте<br />
-lm к командной строке gcc).<br />
Попробуйте угадать, как будет двигаться объект в этом примере:<br />
float evil_x=300;<br />
float evil_y=0;<br />
float radius=150;<br />
float a;<br />
while (GAME) {<br />
sprite(1, radius*sin(a)+evil_x,radius*cos(a)+evil_y);<br />
a=a+0.01;<br />
if (a>=3.14){a=0.;}<br />
evil_y+=0.5;<br />
fx();<br />
}<br />
Вражеский пилот явно ас: его корабль движется практически случайным<br />
образом. Да, поразить такую цель будет непросто... А если вас<br />
смущает загадочное число 3,14 – то это просто примерное значение<br />
«пи» или число радиан, соответствующее 180 градусам. Обратите внимание<br />
на то, что увеличивать координаты можно не только на 1, 2 и так<br />
далее, но и на дробные числа – например на 0,5, как в этом примере.<br />
Что за штука... велосити?<br />
Велосити (англ. velocity – скорость) – вероятно, один из самых чудесных<br />
способов сделать управление более реалистичным. Что мы имеем<br />
сейчас? Нажимаем клавишу – корабль движется, отпускаем – останавливается.<br />
Но в реальном мире тела обладают инерционностью, и, как<br />
с детства учат нас правила безопасного поведения на дорогах, ни одна<br />
машина не может затормозить мгновенно. Это тем более верно для<br />
космического корабля, на который не действуют силы трения, но... мы<br />
отвлеклись.<br />
Реализовать такое поведение в игре достаточно просто. В момент<br />
нажатия клавиши в функции изменения координат необходимо увеличить<br />
и значение велосити, а при отпускании клавиши – уменьшить его.<br />
Например, так:<br />
int dir=1;<br />
if (LEFT){velocity=4.5; dir=1; x-=3;}<br />
if (RIGHT){velocity=4.5; dir=-1; x+=3;}<br />
if (velocity>0) {<br />
velocity-=0.1;<br />
} else {<br />
velocity=0;dir=0;<br />
}<br />
x=x-velocity*dir;<br />
Переменная dir просто задает направление движения: +1 – налево,<br />
-1 – направо.<br />
Обратите внимание на последнюю строчку – именно она обеспечивает<br />
«тормозной путь» после отпускания клавиши, а заодно и<br />
меняет знак приращения в зависимости от значения dir. Физическая<br />
модель заключена в блоке if () {...} else {}: если мы не поддерживаем<br />
нужную скорость, удерживая клавишу нажатой, она (за счет действия<br />
сил трения, надо думать) постепенно уменьшается. Поскольку трение<br />
в космосе не слишком велико, коэффициент затухания можно<br />
выбрать малым – подберите его опытным путем, чтобы играть было<br />
интересно.<br />
Оживляем персонажей<br />
Анимация – один из ключевых аспектов, на который нужно обратить<br />
самое пристальное внимание. Конечно, можно создать игру, где будут<br />
только статические персонажи – но ведь это же несерьезно!<br />
Эффект анимации, как известно, создается последовательным<br />
отображением незначительно отличающихся друг от друга кадров.<br />
Таким образом мы можем украсить игру роскошными взрывами. Если<br />
вы внимательно читали предыдущие номера LXF, то надеюсь, не пропустили<br />
руководство по работе с 3D-редактором Blender (см. LXF87/88-<br />
LXF91 на DVD) – здесь он окажет вам неоценимую помощь.<br />
Ниже представлен пример, демонстрирующий основы анимации. В<br />
данном случае ролик формируется из четырех кадров:<br />
#include “ingame.h”<br />
int main(int n, char **s) {<br />
screen(640,480);<br />
loadsprite (10,”01.png”);<br />
loadsprite (11,”02.png”);<br />
loadsprite (12,”03.png”);<br />
loadsprite (13,”04.png”);<br />
int i=10;<br />
while (GAME){<br />
sprite(i, 200 , 200);<br />
i++;<br />
if (i==14){i=10;}<br />
fx();