Создание стрелялки с видом от первого лица в Game maker 6
Оригинальная версия: Марк Овермас, 24 октября 2004 года.
Перевод на русский язык и обработка текста: , 19 апреля 2006 года.
Сейчас мы будем изучать 3d функции Game maker. Вы наверно думали, что в Game Maker можно создавать только двумерные игры. В основном Game Maker предназначен для создания 2d игр. Но есть функции и для 3D графики. Итак, мы используем Game Maker, чтобы создавать 2- мерную игру, но, не рисуя двумерную комната, которую мы создадим 3d графику взамен. Вам нужно понимать язык GML очень хорошо.
Первая 2- мерная игра
Итак, мы сначала создадим 2- мерную игру, а затем преобразуем ее в 3d
вид. Графика на этом этапе не важна. Все объекты будет представлены простыми цветными дисками.
Мы создадим два объекта стены: горизонтальный и вертикальный. Мы также создаем один объект базовой стены и назовем его obj_wall_basic. Этот объект станет родителем для других стен. Объекты Стены не имеют поведения. Все
объекты стены будут твердыми. Так горизонтальный объект стены будет выглядеть приблизительно так:

Следующий объект, который мы должны создать, - игрок. Мы представляем его небольшим синим диском.
В событии конечного шага, мы установим значения переменной image_angle такое же, как у переменной directional. В событие отпускания клавиши клавиатуры для клавиши Up поместим код:
{
if (speed < 2) speed = min(2,speed+0.4);
}
В событии создания мы установим значение трения равным 0.2
Для клавиши Down мы делаем то же самое, но с противоположным направлением. Для клавиш Left и Right мы просто увеличиваем или
уменьшите значение переменой directional. В событии столкновения со стеной мы останавливаем движение. Пример игры находиться в файле fps0.gm6.
Переход в 3d.
В событии создания для объекта игрок, пишем код:
d3d_start();
d3d_set_hidden(true);
d3d_set_lighting(false);
d3d_set_culling(false);
texture_set_interpolation(true);
Мы также удаляем действия из конечного события шага, которое мы добавили в нашу 2D версию игры.
Следующая вещь, которую мы должны сделать – улучшить стены. Для этого будут использованы текстуры. Мы используем множество текстур, некоторые из них созданы Давидом Гуэро(http://www. /blade/davegh. htm.).
Вот текстуры стены, потолка и пола:

Мы добавляем их как фон в игру. Нам нужно знать координаты каждой стены.
Мы сделали это в событии создания каждого индивидуального объекта стены.
Например, для горизонтальной стены мы поместили следующий код в событие создания:
{
x1 = x-16;
x2 = x+16;
y1 = y;
y2 = y;
z1 = 32;
z2 = 0;
tex = background_get_texture(texture_wall);
}
Последняя строка требует некоторых объяснений. Функция background_get_texture() возвращает индекс текстуры соответствующей указанному фону.
В событии draw объекта стены напишите код:
{
d3d_draw_wall(x1,y1,z1,x2,y2,z2,tex,1,1);
}
Нам все еще нужно указать, как мы смотрим на мир и мы должны также
сделать пол и потолок комнаты. В событие draw объекта камера пишем код:
{
// set the projection
d3d_set_projection(x, y,10, x+cos(direction*pi/180),
y-sin(direction*pi/180),10, 0,0,1);
// set color and transparency
draw_set_alpha(1);
draw_set_color(c_white);
// draw floor and ceiling
d3d_draw_floor(0,0,0,640,480,0,
background_get_texture(texture_floor),24,18);
d3d_draw_floor(0,0,32,640,480,32,
background_get_texture(texture_ceiling),16,12);
}
Это - все. Игра находится в файле fps1.gm6. Игра должна выглядеть примерно так:

Лучший проект уровня
Текущий уровень имеет множество проблем. Вы можете видеть обе стороны стен. Это должно быть исправлено. Добавляя повороты в коридорах, мы уменьшаем часть доступного пространства. Это увеличивает чувство страха. Вы никогда не знает, что лежит за следующим углом.
Мы увеличили комнату и запретили менять размер окна. Вот образ нового уровня.

Вы можете найти новую игру в файле fps2.gm6.
Дополнение тумана
Вы можете добавить туман к вашей игре. Для того, чтобы включить туман, просто добавьте строку кода в событие создание объекта игрока (после включения 3D):
d3d_set_fog(true, c_black,10,300);
Лучшее движение
Сделаем стены твердыми. В событии столкновения объекта стены мы поместим следующую часть кода:
{
x = xprevious;
y = yprevious;
if (abs(hspeed) >= abs(vspeed) &&
not place_meeting(x+hspeed, y,obj_wall_basic))
{ x += hspeed; exit;}
if (abs(vspeed) >= abs(hspeed) &&
not place_meeting(x, y+vspeed, obj_wall_basic))
{ y += vspeed; exit;}
speed = 0;
}
Чтобы позволить игроку бежать при нажатой клавиши Shift в события нажатия клавиши для клавиш Up и Down напишите следующий код:
{
var maxspeed;
if keyboard_check(vk_shift) maxspeed = 3 else maxspeed = 1.5;
if (speed < maxspeed ) speed = min(maxspeed, speed+0.4);
}
Сделайте так чтобы при нажатии на клавишу Left значение переменной directional увеличивалось на 3, а при нажатии на клавишу Right уменьшалось на 3. В событии клавиатуры для клавиши z напишите код:
{
{
var xn, yn;
xn = x - sin(direction*pi/180);
yn = y - cos(direction*pi/180);
if not place_meeting(xn, yn, obj_wall_basic)
{ x = xn; y = yn; }
}
Вы можете найти игру в файле fps2.gm6.
Добавление объектов
Наш мир пустой. Есть только стены. Сейчас нужно добавить некоторые объекты против нашего мира. Следующая часть кода может быть, например, установлена в рисующем событии для объекта.
{
var ss, cc, tex;
tex = sprite_get_texture(spr_plant,0);
ss = sin(obj_player. direction*pi/180);
cc = cos(obj_player. direction*pi/180);
d3d_draw_wall(x-7*ss, y-7*cc,20,x+7*ss, y+7*cc,0,tex,1,1);
d3d_draw_wall(x-7*ss, y-7*cc,20,x+7*ss, y+7*cc,0,tex,1,1);
}
В каждом событии конечного шага для игрока мы загружаем в sin и cos в значения глобальных переменных camsin и camcos.
Анимированные объекты
Мы можем также создать анимированные объекты. Прежде всего, нам нужен спрайт, который состоит из нескольких частей. Мы
должно убедиться, что спрайт, который мы используем, имеет тоже количество кадров, что и текстура объекта. Вот типичная часть кода, который мог бы быть выполнен в событии создания некоторого объекта взрыва.
{
var ss, cc, tex;
tex = sprite_get_texture(spr_explosion, image_index);
ss = sin(obj_player. direction*pi/180);
cc = cos(obj_player. direction*pi/180);
draw_set_alpha(0.7);
draw_set_color(c_white);
d3d_draw_wall(x-8*ss, y-8*cc,2,x+8*ss, y+8*cc,18,ttt,1,1);
draw_set_alpha(1);
}
Игра, которую мы создали, лежит в файле fps3.gm6.
Добавление бочек
Чтобы стрелять нам нужны спрайты бочки. Мы их возьмем с сайта http://www. cslab. ece. ntua. gr/~phib/doom1.htm. Мы создаем объект бочки и взрывающийся объект бочки. Обоим мы указывает в качестве родителя объект стены.
Когда бочка уничтожена, мы создаем взрывающую бочку на том же месте. В событии рисования мы добавляем следующую строку для этого:
draw_set_alpha(1-0.05*image_index);
Наконец, в конечном событии рисования мы уничтожаем взрывающую бочку. Игра лежит в файле fps4.gm6.
Пушка
Для пушки, которую мы снова используем анимированный спрайт. Установим глубину равную -100. Во-вторых, мы не должны больше использовать
перспективную проекцию. И, наконец, мы должны временно отключить скрытое поверхностное удаление. Код для события рисования выглядит так:
{
d3d_set_projection_ortho(0,0,640,480,0);
d3d_set_hidden(false);
draw_sprite_ext(sprite_shotgun,-1,0,224,2,2,0,c_white,1);
d3d_set_hidden(true);
}
Стрельба
Прежде всего мы вводим переменную can_shoot. Мы дали ей значение true в событии создания объекта. Для каждой позиции, которую мы проверяем столкновение с бочкой. Если так, мы уничтожаем бочку. Код выглядит так:
{
var xx, yy, dx, dy, ii;
xx = obj_player. x;
yy = obj_player. y;
dx = 4*cos(obj_player. direction*pi/180);
dy = -4*sin(obj_player. direction*pi/180);
repeat (100)
{
xx += dx;
yy += dy;
ii = instance_position(xx, yy, obj_wall_basic);
if (ii == noone) continue;
if (ii. object_index == obj_barrel)
with (ii) instance_destroy();
break;
}
}
Добавление врагов
Для чудовищ нам нужно спрайта. Итак, мы создаем новый объект obj_monster_basic. Это будет основным объектом для всех.
Код выглядит так:
{
var xx, yy, ii;
xx = global. camx;
yy = global. camy;
repeat (50)
{
xx += 4*global. camcos;
yy -= 4*global. camsin;
ii = instance_position(xx, yy, obj_wall_basic);
if (ii == noone)
{
ii = instance_position(xx, yy, obj_monster_basic);
if (ii == noone) continue;
with (ii) instance_destroy();
break;
}
if object_is_ancestor(ii. object_index, obj_plant_basic) continue;
if (ii. object_index == obj_barrel)
with (ii) instance_destroy();
break;
}
}
draw_set_alpha(0.4);
draw_healthbar(5,460,100,475,health, c_black, c_red, c_lime,
0,true, true);
draw_set_alpha(1);
}
Вы можете найти игру в файле fps5.gm6. В событии рисования игрока вставьте код:
draw_set_alpha(0.4);
draw_healthbar(5,460,100,475,health, c_black, c_red, c_lime,
0,true, true);
draw_set_alpha(1);
Чтобы позволять чудовищам атаковать игрока, который мы поместили следующее кода в начальное событие шага:
{
if (point_distance(x, y,obj_player. x,obj_player. y) > 200)
{ speed = 0; exit; }
if (collision_line(x, y, obj_player. x,obj_player. y,
obj_wall_basic, false, false))
{ speed = 0; exit; }
if (point_distance(x, y, obj_player. x,obj_player. y) < 12)
{
speed = 0; health -= 2;
if not sound_isplaying(snd_ow) sound_play(snd_ow);
exit;
}
move_towards_point(obj_player. x,obj_player. y,1.4);
}


