03.03.2013 Views

LXFDVD - Журнал Linux Format

LXFDVD - Журнал Linux Format

LXFDVD - Журнал Linux Format

SHOW MORE
SHOW LESS

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();

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!