Всем доброго времени суток. Сегодняшний урок я хотел бы посвятить такой интересной игровой особенности, как перемотка времени. То есть мы заставим нашего героя двигаться в обратном направлении по уже пройденному им пути.
Для начала, как обычно, займемся созданием спрайтов. Их у нас будет три: spr_wall, spr_hero и spr_effect.
Спрайт spr_wall представляет собой квадрат размером 32х32 и будет обозначать стены и поверхности. spr_hero, это герой нашей игры, который так же представляет собой квадрат 32х32, но с нарисованной на нем рожицей. И, наконец, spr_effect – это спрайт, который будет использоваться нами для создания эффекта перемотки времени. Он представляет собой квадрат размером 32х32, с примененным к нему эффектом анимации Disappear распространенным на 8 кадров.
Со спрайтами закончили, переходим к программированию. Создадим объекты obj_wall, obj_hero и obj_effect, указав им соответствующие спрайты. Заходим в свойства объекта obj_wall и делаем его твердым (solid). Затем заходим в obj_effect и добавляем событие Animation end. В этом событии прописываем одну строчку кода:
Code
instance_destroy()
Тем самым мы удаляем данный объект, когда его анимация проходит все кадры. Помимо этого поставим у obj_effect свойство Depth равное 1. Это перенесет наш эффект на задний план по сравнению с другими объектами. В дальнейшем вам станет понятно зачем мы все это сделали, а пока переходим к главному объекту - obj_hero.
Итак, сначала создадим простейшее управление для героя. Я не буду заострять на этом особое внимание, так как это не является целью данного урока.
Создадим событие step и пропишем в нем следующий код:
Для начала, в цикле задаем два массива, в которые мы будем записывать координаты, по которым движется наш герой. Соответственно чем больше размерность массива, тем длиннее путь мы можем записать. Я ограничился значением в 100.
Далее переменные i и j. Они служат ограничителями при записи и перемотке времени. Переменная backtime определяет включен ли режим перемотки. А переменная sila будет служить нам, чтобы визуально отображать, сколько ещё мы сможем перематывать время.
Теперь переходим в событие Step и первым дописываем условие для того кода, который у нас уже есть, т.е. для гравитации:
Code
if backtime=false { gravity_direction = 270 if place_free(x,y+1) gravity = 0.5 else gravity = 0 }
Это значит, что гравитация у нас будет работать только тогда, когда перемотка времени не активирована.
После этого допишем там же следующие строки:
Code
if backtime=false { if sila<100 sila+=1
xmas[100]=x ymas[100]=y
for (i=0; i<=100; i+=1) if i<=99 {xmas[i]=xmas[i+1] ymas[i]=ymas[i+1]} else {xmas[i]=noone ymas[i]=noone} }
Этот кусок кода служит для записи координат героя в массив, а так же он изменяет переменную sila. Действует весь этот код при условии, что режим перемотки времени не активирован. Разберем код подробнее.
if sila<100 sila+=1
Тут все понятно, если значение переменной sila меньше 100, то увеличиваем это значение на единицу, т.е. восстанавливаем энергию для перемотки времени.
xmas[100]=x ymas[100]=y
Эти строки записывают в сотую, последнюю ячейку массива значение координат в которых находится герой. А дальнейший цикл служит для смещения значения из большей ячейки в меньшую.
for (i=0; i<=100; i+=1) if i<=99 {xmas[i]=xmas[i+1] ymas[i]=ymas[i+1]} else {xmas[i]=noone ymas[i]=noone}
Пробегаем циклом по всем элементам массива. Если номер ячейки меньше либо равен 99, то записываем в меньшую ячейку значение из соседней, большей:
xmas[i]=xmas[i+1] ymas[i]=ymas[i+1]
Таким образом в ячейку под номером 1, запишется значение из ячейки 2, в а ячейку 2 значение из ячейки 3 и т.д. Дойдя до сотой, последней ячейки, записывать туда будет нечего, потому мы записываем туда пустое значение:
xmas[i]=noone ymas[i]=noone
Тем самым каждый шаг значение ячеек будет динамически меняться, и хранить в себе только определенный промежуток, пройденный героем. Визуально это можно отобразить так:
000000[1] 000001[2] 000012[3] 000123[4]
С записью закончили, теперь займемся перемоткой. Для этого создадим новое событие, нажатие и удерживание (keyboard) клавиши Space и напишем там:
Code
if j>=0 { gravity = 0 vspeed=0 instance_create(x,y,obj_effect) sila-=1 backtime=true
if xmas[j]!=noone {x=xmas[j] xmas[j]=noone}
if ymas[j]!=noone {y=ymas[j] ymas[j]=noone}
j-=1 } else backtime=false
Итак, разберем по строкам. Если значение переменной j больше, либо равно нулю, тогда выполняем перемотку. Перед этим отключаем гравитацию и обнуляем вертикальную скорость, чтобы исключить какие либо нежелательные смещения героя.
Далее создаем тот самый, созданный нами, эффект перемотки. instance_create(x,y,obj_effect) Таким образом, при движении героя в обратном направлении, за ним будет тянуться шлейф из созданного нами объекта со спрайтом эффекта.
Следующие строки уменьшают энергию и активируют режим перемотки времени: sila-=1 backtime=true
И, наконец, считывание значений из массива, и присваивание их соответствующим переменным x и y.
if xmas[j]!=noone {x=xmas[j] xmas[j]=noone}
if ymas[j]!=noone {y=ymas[j] ymas[j]=noone}
j-=1
Проверяем, не пустая ли ячейка, если не пустая, то считываем из неё значение в соответствующую переменную и делаем эту ячейку пустой. После чего уменьшаем значение переменной j на единицу, чтобы сместиться на следующую ячейку.
Если значение переменной j становится меньше 0, то отключаем режим перемотки времени.
С основными аспектами разобрались. Остались мелочи. Сначала поставим ограничение на движения героя влево и вправо, и на прыжок. Для этого в соответствующих событиях первой строкой допишем:
Code
if backtime=false {код, который уже написан в этих событиях}
Такое же ограничение ставим в событии столкновения со стеной:
Code
if backtime=false { move_contact_solid(direction,-1) vspeed = 0 }
Теперь, добавим событие release Space, т.е. отпускание клавиши “Пробел”. И пропишем там две строки:
Code
j=100 backtime=false
Первая, возвращает нам значение переменной j в исходное состояние, чтобы при каждом новом нажатии пробела, значения считывались из последней ячейки.
Ну а с переменной backtime думаю все понятно, отключаем режим перемотки.
Наконец последнее, создадим событие Draw и напишем там:
Тем самым создадим healthbar, который будет отображать значение переменной sila, т.е. будет показывать, сколько осталось энергии для перемотки времени.
А строка draw_sprite(sprite_index,0,x,y), служит для того, чтобы спрайт нашего героя отображался при событии рисования.
Вот и всё. Теперь строим уровень и наслаждаемся.
Как всегда, исходник по уроку можно скачать тут:
Сообщение отредактировал LunarPixel - Воскресенье, 07 Августа 2011, 21:18
Большое похоже на антигравитацию. Урок кошерный, но чей то в нем не так, уж больно простой Фотошоп это не сложно. Немного теории, полезной на практике: Работа с наложением текстур Рисуем без планшета
Пока нет времени выкладывать уроки, завален работой.
Но вот решил выложить один скрипт. Сделал только что в помощь одному пользователю, но может ещё кому нибудь понадобится. Скрипт закрашивает две части одного текста разными цветами.
w_view - ширина видимой области (комнаты или вида) h_view - высота видимой области text - текст который нужно преобразовать в цветной x1 - смещение от начала текста, до точки перехода цвета y - высота текста x2 - смещение второй части текста от точки разрыва до конца color1,color2 - цвета левой и правой части текста
Ku6opk, исходник был залит на файлообменник yemsalat, который сейчас не работает. Если у кого то остался исходник, просьба выложить. У меня исходник есть, но он уже претерпел массу изменений и доработок, так что там черт ногу сломит, и всё без комментариев.
В общем, если у кого то сохранился стары вариант исходника, прошу выложить в теме.
(Переиздание и продолжение) Урок седьмой. Имитация веревки-поводка.
Всем здравствуйте. Сегодня я хотел бы рассказать вам, как можно простым способом сымитировать поведение веревки-поводка. Что мы получим в конце: объект "привязанный" псевдо-веревкой к курсору и следующий за ним.
Итак, для начала нам понадобятся два спрайта: spr_block - квадратный объект 32х32 spr_curs - спрайт курсора, я сделал его размером 16х16
Теперь создадим два объекта obj_block и obj_curs, и назначим этим объектам соответствующие спрайты.
Первым делом заставим наш курсор следовать за мышкой с определенной скоростью, для этого в объекте obj_curs в событии step пропишем:
Code
mp_potential_step(mouse_x,mouse_y,10,0)
mp_potential_step заставляет объект двигаться к точке mouse_x, mouse_y со скоростью 10. В дальнейшем скорость можно будет перенастроить, а при желании вообще не использовать объект курсора, а взять за основу саму мышь.
На этом obj_curs можно отложить в сторонку и заняться obj_block, в котором и будет прописан весь основной код.
Заходим в объект блока и в событии create создаем две переменные:
Code
p=0 l=200 n=0 m=0
Переменная p у нас будет отвечать за само построение нашей псевдо-веревке, подробнее об этом вы узнаете ниже. Переменная l отвечает за длину веревки. Переменные n и m будут формировать смещение веревки, о котором так же будет рассказано ниже. С переменными разобрались. Теперь создаем событие Draw в котором и будет творить всё самое интересное.
Первое, что нужно, это отрисовать сам спрайт нашего obj_block, для этого напишем следующее:
Code
draw_sprite(sprite_index,0,x,y)
Теперь перейдем к формированию веревки. Пора раскрыть все карты и рассказать принцип её создания, а создана она будет на основе всем известный путей (path).
Итак, чтобы создать псевдо-веревку на основе путей, нам понадобится следующий код:
if distance_to_object(obj_curs)<l-50 { if x>object2.x n=distance_to_point(obj_curs.x,y)/2 if x<object2.x n=-distance_to_point(obj_curs.x,y)/2 } else n=0
Давайте разберем его подробнее: p=path_add() - создает новый путь и присваивает его идентификатор переменной p. Теперь чтобы работать с новым путем, нам нужно обратиться к этой самой переменной. path_set_kind(p,1) и path_set_closed(p,0) указывают, что наш путь должен быть закругленным и не замкнутым, соответственно.
Рассмотрим в совокупности следующие строки, который непосредственно и формируют саму веревку: path_insert_point(p,0,x,y,100) - задает начало веревки, которое находится в точке x,y, т.е. непосредственно на нашем obj_block path_insert_point(p,1,obj_curs.x+m,obj_curs.y+(l-distance_to_object(obj_curs))/1.5,100) - чтобы веревка изгибалась, мы создаем одну промежуточную точку, координата x у этой точки равна соответствующей координате x у объекта obj_curs со смещением на m, координата y так же равна соответствующей координате у курсора, но смещается на (l-distance_to_object(obj_curs))/1.5, т.е. на разность общей длины веревки и расстояния от obj_block до курсора разделенной на 1.5 (этот параметр можно изменить, или же вообще поменять формулу на более реалистичную). path_insert_point(p,2,obj_curs.x,obj_curs.y,100) - задает конец веревки, которое находится в точке x,y объекта obj_curs, т.е. непосредственно на нашем курсоре.
Наконец мы рисует нашу веревку через draw_path(p,x,y,0), а затем удаляем путь path_delete(p), чтобы в последствии создать вместо него новый, с новыми координатами.
Если оставить всё как есть, то изгиб будет не очень реалистичным, чтобы хоть как-то это исправить, был введен следующий блок кода:
Code
if distance_to_object(obj_curs)<l-50 { if x>object2.x n=distance_to_point(obj_curs.x,y)/2 if x<object2.x n=-distance_to_point(obj_curs.x,y)/2 } else n=0
Что же делает этот код?! Он формирует отклонение по x для центральной части веревки (та самая переменная m, которая далее будет определяться через n). Пока расстояние от obj_block до obj_curs меньше l-50, центральная точка веревки отклоняется по x на distance_to_point(obj_curs.x,y)/2, в зависимости от того, в какую сторону направлена веревка. Если же расстояние от obj_block до obj_curs становится больше l-50, отклонение становится равным 0.
Для отклонения уже сейчас можно использовать переменную n вместо m, но тогда переход к нулевому отклонению будет слишком резким, чтобы это исправить, напишем следующее:
Code
if m<n m+=4 if m>n m-=4
Тут вопросов быть не должно, если есть разница между n и m, то эта разница постепенно уменьшается, делая переход плавным. Ну вот и всё, с формированием псевдо-веревки мы закончили. При желании, можно добавить большей реалистичности дописав пару формул.
Но ведь у нас не просто веревка, а веревка-поводок, а это значит, что нужно научиться таскать предмет за эту веревку. Делается это очень просто:
Code
if distance_to_object(obj_curs)>=l { direction=point_direction(x,y,obj_curs.x,obj_curs.y) speed=10 } else speed=0
Если расстояние от obj_block до obj_curs достигает предела, то направление движения obj_block меняется, в зависимости от позиции obj_curs, и obj_block начинает двигаться в сторону курсора со скоростью 10.