Mighty Final Fight. Vol.-1
volume -1
ВНИМАНИЕ!!! данная статья СОДЕРЖИТ плохие рекомендации!!! НЕ рекомендуется к прочтению!!!
-3 :: -2 :: -1 :: 0 :: 1 :: 2 :: 3
Предисловие
В этот раз я хотел бы затронуть еще несколько спорных моментов, касающихся самого инструмента. В следующем выпуске (Vol.1) мы наконец-то начнем анализировать MFF и пытаться что-то создать ))
Вывод картинки на экран
В ГМ предусмотрено несколько способов вывода изображения на экран.
1. sprite_index
Первый и главный способ вывести картинку -- это просто назначить какой-то спрайт объекту. Если объект видимый (visible = true), то привязанный спрайт отобразится на экране.
Только с помощью этого способа мы можем просто и без лишних манипуляций вывести на экран анимированное изображение. Если спрайт состоит из нескольких кадров, то они по кругу будут меняться каждый игровой шаг.
Есть еще две важных переменных, которые необходимо знать.
image_index - позволяет назначить или получить номер текущего кадра в спрайте.
image_speed - устанавливает скорость чередования кадров. При значении 1, кадры следуют один за другим как положено. Значение 2 позволяет перепрыгнуть через каждый второй кадр, и так далее.
При image_speed = 0 -- текущий кадр не меняется, анимации не происходит, и соответственно не случается события Animation End. Это важный момент, который стоит запомнить.
Каждый экземпляр объекта может отображать только один спрайт единовременно. Таким образом, любой анимированный участок на экране (враг, летящая птичка, мигающая реклама) придется реализовывать с помощью отдельного экземпляра объекта.
2. draw_sprite(sprite,subimg,x,y)
Это базовая функция рисования спрайта. Все функции draw выполняются только в событии Draw. Это нужно запомнить. То есть если вы дадите инструкцию рисовать спрайт в событии Step -- ничего не произойдет.
Этим способом один экземпляр объекта может вывести на экран несколько спрайтов. Как видно из аргументов, функция выводит на экран он только один кадр (subimg), то есть запустить анимацию простым использованием этой функции нельзя.
Подчеркиваю, что нельзя именно простым способом. Естественно, мы можем сделать цикл, идти по всем кадрам спрайта, и каждый шаг выводить следующий.
Все функции draw очень медленные, поэтому злоупотреблять ими не стоит.
Важно помнить, что обоими способами спрайты рисуются на глубине (depth) экземпляра объекта, к которому они привязаны, или который их рисует (с помощью draw). При этом если вы выполните две функции draw с разными спрайтами, спрайт вызванный последней функцией будет наложен на первый.
Напоминаю проблему, которую нам предстоит решить.
Совместить эти две картинки мы можем двумя способами:
1. Создать два объекта с разной глубиной, где дальнему мы назначим спрайт Cody (так зовут данного персонажа), а ближнему спрайт со штанами.
2. В событии Draw одного объекта выполним последовательно две функции:
draw_sprite(spriteCody,subimg,x,y);
draw_sprite(spriteShtany,subimg,x,y);
То есть мы нарисуем вначале самого Коди, а на нем нарисуем штаны.
Совместить оба способа нельзя. Если у вас описано событие Draw (даже с пустыми инструкциями), картинка в sprite_index отображаться не будет.
Ну и второй момент заключается в том, что столкновения экземпляров объектов обрабатываются по назначенному в spite_index спрайту.
Я выбрал для себя первый способ, прежде всего потому что отображение картинки с помощью sprite_index намного быстрее и выполняется в цикле перед событием Draw.
3. background_index[0..7]
Я не пользуюсь специальным объектом бэкграунд, потому что он не позволяет картинке находиться в середине глубины экрана. Объяснил путано, но суть довольно проста.
Бэкграунд может быть либо совсем глубоко, так что все спрайты рисуются на нем. Либо совсем близко, так что все спрайты рисуются за ним. Но сделать с помощью бэкграунда, например, стену посредине экрана, чтобы персонажи могли как ходить перед ней, так и за ней -- нельзя.
Возможно я навру вам в этом пункте, потому что отказавшись однажды от использования бэкграундов, я больше к ним не возвращался. Наверняка, я просто не до конца разобрался с их возможностями.
У бэкграунда есть, тем не менее, один известный мне плюс. Картинки отображаемые таким способом, и соответственно сами специальные объекты background, не участвуют в событиях столкновения, то есть обрабатываются намного быстрее, чем картинки в sprite_index обычных объектов.
Также бэкграунды можно рисовать с помощью функции draw_background(back,x,y) (и ее расширенных версий).
Если при добавлении бэкграунда в исходник указать его как тайлсет, можно пользоваться функциями тайлов (например, tile_add(background,left,top,width,height,x,y,depth)). Тайлы также как и бэкграунды не участвуют в событиях столкновения, легки для обработки, и отлично подходят для мелких неинтерактивных элементов.
Итого
- Если картинка анимирована -- используйте отдельный экземпляр объекта и переменную sprite_index.
- Если картинка является фоном -- используйте объект background, или обычный объект с однокадровым спрайтом, или многокадровым спрайтом с image_speed = 0.
- Если нужно отобразить несколько небольших статичных картинок на одной глубине экрана -- используйте функции draw.
- Не забывайте про тайлы (например, если вам понадобится оставить на экране брошенную сигарету)
- 08 февраля 2012, 15:23
То есть бэкграунду нельзя задать глубину?
А тайлам бэкграунда можно?
Да, именно так. Бэкграундов всего может быть восемь (если через background делать). Часть из них может быть foreground (то есть на переднем плане).
Но они либо сзади, либо спереди. background[0] всегда будет дальше background[1], но объекты за бэкграунд уйти не могут.
Еще вопрос немного не по теме. Например персонаж движется по платформе. Физические свойства платформы описываются невидимыми твердыми блоками, а сама платформа отображается в виде тайлов бэкграунда. Возможно ли создать невидимый блок непрямой формы (дугообразной, к примеру), по которому персонаж может ходить, не застревая между пикселями этого блока?
Думаю, что можно, но я никогда не пробовал, поэтому навскидку тебе не скажу.
Может придут специалисты по платформерам и подскажут. Боюсь напридумывать в данном случае.
Например, когда я пытался сделать платформер, то использовал видимые и нетвердые блоки для описания свойств платформы, а на них накладывал сверху тайлы.
В платформерах свои тонкости, и наверняка уже есть какие-то решения на все такие случаи, которые стали условным стандартом.
Я думаю, при желании поверхность можно задавать сплайнами или полигонами.
Описаны далеко не все способы вывода изображения на экран. Не тру. Да и не слишком похоже на то, что ты профессионал.
Этих способов достаточно. И уео нигде не говорил, что он профи, даже наоборот.
Я о том, что нужно быть профессионалом или по крайней мере хорошо разбираться в том, о чём хочешь писать. Иначе статьи получаются неполными или содержать ошибки.
Можно считать, что мы эти статьи пишем всем миром, а координирует это дело yeo.
Если ты видишь неточности, опиши их пожалуйста или исправь, так ты поможешь общему делу.
Я не читал анонса. :)
Не слишком похоже на то, что ты профессионал в чтении постов. :)
:)
так он хорошо разбирается в том, о чем пишет)
о четко знает как написать битэмап, а остальное уже неважно)
Ты так по первому посту и не ответил, кстати. Про то, что там была неправда.
Не ври, ответил. :)