Наконец нашел время написать ещё один небольшой урок. На этот раз он посвящен поверхностям или сурфейсам (surface). Рассмотрим работу с поверхностями на основе разрушения и воссоздания ландшафта.
Внимание! Данный урок не несет в себе цели научить вас создавать разрушаемый ландшафт, потому способ описанный ниже весьма не оптимизированный. Цель урока – разобраться в работе с сурфейсами. Итак, приступим. Для начала создадим все необходимые нам спрайта:
1.
spr_gr – спрайт земли. Размер его будет равен размеру комнаты, в моем случае это 640х480. В нижней части располагается прямоугольник коричневого цвета, который обозначает землю, остальная часть спрайта прозрачная.
2.
spr_del – синий круг произвольного размера.
3.
spr_add – круг такого же цвета как земля на спрайте
spr_gr, так же произвольного размера. (целесообразно сделать его такого же размера как и
spr_del)
4.
spr_ball – круг произвольного цвета размером 16х16, будет использоваться для тестирования создаваемой нами земли.
Теперь займемся непосредственной разработкой. Создадим первый объект и назовем его
obj_gr, установим для него созданный нами спрайт
spr_gr. Так же сделаем этот объект
твердым (solid), поставив соответствующую галочку в настройках. Для этого объекта создадим событие
create в котором запишем следующий код:
Code
sur=surface_create(room_width,room_height)
surface_set_target(sur)
draw_sprite(spr_gr,0,x,y)
surface_reset_target()
Этот код, является основой создания поверхности. Разберем его по строкам.
sur=surface_create(room_width,room_height) создает нашу поверхность-сурфейс. Чтобы можно было работать с этой поверхностью в дальнейшем, мы записываем её индекс в переменную
sur. В параметрах функции
surface_create указываем размер поверхности, в данном случае она по ширине и высоте равна комнате.
surface_set_target(sur) обозначает, что все дальнейшее рисование будет происходить на указанной поверхности, т.е. на поверхности хранящейся в переменной
sur.
На этой поверхности мы рисует наш спрайт земли, при помощи функции:
draw_sprite(spr_gr,0,x,y) Таким образом, наша поверхность теперь хранит в себе изображение спрайта
spr_gr, нарисованного в комнате, в позиции
x и
y.
Наконец функция
surface_reset_target() вновь возвращает рисование с поверхности на экран. Т.е. все, что будет рисоваться после использования этой функции, не будет сохраняться на поверхности, а просто будет отображаться на экране.
Всё в том же объекте создадим событие
draw и запишем в него одну единственную строку:
Code
draw_surface(sur,0,0)
Эта функция, как понятно из названия, рисует поверхность в указанной позиции, в данном случае по позиции
0:0.
Итак, поместим
obj_gr в комнату, в позицию
0:0 (чтобы спрайт данного объекта охватывал всю комнату, ведь он равен ей по размеру) и запустим то, что у нас получилось. Ничего необычного вы не увидите, спрайт spr_gr будет отображаться в комнате, как и положено. Однако рисоваться он будет уже с поверхности и если изменить координаты вывода в событии
draw, то поверхность сместиться, а вместе с ней и изображение.
Теперь проверим нашу землю на прочность. Создадим новый объект и назовем его
obj_ball. Назначим ему спрайт
spr_ball. У этого объекта в событии
step пропишем следующее:
Code
gravity=1
gravity_direction=270
Эти строки устанавливают силу и направление гравитации соответственно.
Для этого же объекта добавим событие столкновения с объектом
obj_gr и пропишем там:
Code
if vspeed>0 and !place_free(x,y+vspeed)
move_contact(270)
vspeed=0
Этот код не позволит нашему шару проходить сквозь землю и будет строго опускать его на уровень поверхности.
Теперь можем поместить один такой шар в комнату, и посмотреть, как он упадет на землю.
Наконец, перейдем к самому интересному, научимся удалять кусочки земли. Для этого создадим новый объект и назовем его
obj_del, применим к нему соответствующий спрайт и в событии
create напишем:
Code
surface_set_target(obj_gr.sur)
draw_set_blend_mode_ext(bm_inv_src_alpha,bm_inv_src_alpha)
draw_sprite(sprite_index,0,x,y)
draw_set_blend_mode(bm_normal)
obj_gr.sprite_index=sprite_create_from_surface(obj_gr.sur,0,0,640,480,0,1,0,0)
surface_reset_target()
instance_destroy()
Это всё, что требуется. Разберем этот код по строкам.
surface_set_target(obj_gr.sur), как и в первом случае, дает понять что теперь всё рисование будет происходить на поверхности, т.е. на сурфейсе.
На функцию
draw_set_blend_mode_ext нужно обратить особое внимание, это, так называемый, режим смешивания. Он позволяет манипулировать с цветами и прозрачностью. Подробнее о нем можно почитать в справке. В данном же случае режим настроен таким образом, что прозрачная область спрайта станет такой же, как цвет фона, а закрашенная часть, станет прозрачной.
Все эти настройки применятся к следующей функции рисования:
draw_sprite(sprite_index,0,x,y) Она рисует спрайт объекта
obj_del в координатах, в которых этот объект в данный момент находится.
Чтобы вернуть нормальный режим смешивания, используется следующая строка:
draw_set_blend_mode(bm_normal) Объясню эту часть на пальцах. На нашем сурфейсе, в котором храниться земля, будет рисоваться спрайт объекта obj_del, т.е. круг. Но круг этот рисуется в определенном режиме смешивания, который, вместо самого спрайта, будет рисовать прозрачную окружность, т.е. стирать часть земли.
Далее, чтобы с новой землей можно было взаимодействовать, её необходимо превратить в спрайт. Для этого нужна следующая строка:
obj_gr.sprite_index=sprite_create_from_surface(obj_gr.sur,0,0,640,480,0,1,0,0) Она устанавливает для объекта
obj_gr спрайт из сурфейса, с указанными размерами
0,0,640,480.
Таким образом, всё изображение которое хранилось в нашей поверхности sur, становится спрайтом.
Далее мы опять возвращаем рисование на экран.
surface_reset_target() И удаляем наш объект
obj_del, ведь как объект он нам больше не нужен.
instance_destroy() Вернемся в объект
obj_gr, создадим событие
Glob Left Pressed и напишем там:
Code
instance_create(mouse_x,mouse_y,obj_del)
Эта функция будет создавать объект
obj_del, по нажатию клавиши мыши в координатах курсора. Одним словом, там, где мы кликнем мышкой, там создастся объект
obj_del и удалится кусок земли.
Аналогично можно сделать и создание земли. Попробуйте сделать это самостоятельно. Ничего сложного тут нет. Создайте объект
obj_add с соответствующим спрайтом и в событии создания пропишите код аналогичный коду из объекта
obj_del, только уберите две строки связанные с режимом смешивания.
Так же настройте создание объекта
obj_add по нажатию на правую клавишу мыши.
Вот и всё, создание и удаление земной поверхности создано. И попутно освоены азы работы с сурфейсами.
Чтобы добавить ещё немного интереса, допишите в step у объекта
obj_ball следующий код:
Code
if collision_ellipse(x-10,y-10,x+10,y+10,obj_gr,0,0)
{
if position_empty(x-4,y+10) and !position_empty(x+4,y+10)
hspeed=-1
if position_empty(x+4,y+10) and !position_empty(x-4,y+10)
hspeed=1
}
Этот код заставит наш шарик скатываться по склонам, если у него по бокам не окажется земли. Код этот весьма не стабильный и не доработанный, добавьте его, чтобы проверить удаление части земли.
На этом урок закончен. Новые уроки ожидайте после середины августа, когда я вернусь домой. Удачи в игрострое.
Исходник по уроку можно скачать здесь: