Урок будет долгим, так что устраиваемся поудобнее, завариваем чай и набираемся терпением.
Содержание: 1. Настройка экрана и размер уровня 2. Все, что нужно, для рисования уровня 3. Немного о Picture Editor 4. Про сетку 5. О слоях 6. Создаем главного героя 7. Настраиваем управление 8. Первый опыт в редакторе событий 9. Анимирование 10. Создаем призраков 11. Частные переменные 12. Столкновение с врагами 13. Стрельба 14. Здоровье противников 15. Создаем удобства (ESC, рестарт) 16. Интерфейс: жизни и очки 17. О глобальных переменных 18. Переход на новый уровень
Часть 1
В данной статье я покажу, как создать 2D платформер на подобии Ghost Quest. Для примера я указываю все настройки, которые использовались в Ghost Quest (GQ).
Настройки экрана и размер уровня
Запускаем Scirra Construst, что дальше? Создаем новый проект: Файл – New – New DirectX Game
Сперва, изменим размеры экрана. В правой части экрана переходим во вкладку Project, щелкаем по Application 1. Слева в Layout Properties указываем нужные значения, где Window Width – ширина, Window Height – высота. В GQ использовались значения 840х480. Также убираем галочку с пункта Caption. Это нужно для того, чтобы убрать рамку, вокруг экрана.
Как проверить, какие настройки получились? В верхнем меню выбираем вкладку Project и щелкаем по Run layout
У вас должен отображаться белый квадрат по центру, а слева и справа – черные полосы. Что это? Белый квадрат – это ваша сцена (уровень).
Как его увеличить? Справа внизу переходим во вкладку Project, и в папке Layouts (в ней хранятся все ваши уровни), щелкаем по Layout 1 (это ваш первый уровень). Теперь слева изменяем необходимые параметры, где Width – ширина уровня, Height – высота уровня. Ставим 1680х480. Здесь же вы можете изменить название для уровня, отредактировав пункт Name. прописываем Level 1.
Часть 2
Все, что нужно, для рисования уровня
Уже хочется приступить к рисованию уровня? Для начала нам нужно создать объект, по которому наш герой будет перемещаться. Дважды щелкаем по нашему уровню (белый квадрат/прямоугольник по центру), либо щелкаем по нему же правой кнопкой мыши и выбираем пункт Insert an object, либо в верхнем меню переходим во вкладку Layout и щелкаем по Insert object. Далее дважды щелкаем по Sprite, и тыкаем в любую область нашего уровня.
Появилось окно Picture Editor. Это встроенный в конструктор редактор изображений. В нем, на подобии Paint, мы можем рисовать различные объекты, которые будут в игре.
Левая колонка отображает набор инструментов. Все стандартно (карандаш, кисть, заливка, линии), кроме Hotspot и Image Points. Hotspot указывает центральную для спрайта точку, относительно которой он будет размещен. Обычно, она размещается по центру. Image Points – о них позже.
На верхней панели щелкаем по Resize Canvas (изменение ширины и высоты изображения), и указываем 30х30. Рисуем наш блок, по которому герой и будет перемещаться. Для удобства можно поставить Hotspot по центру изображения (в точке 15,15).
Закрываем Picture Editor. Scirra предложит нам сохранить спрайт – отвечаем взаимностью.
Итак, мы нарисовали блок. Но он всего один, это что же, каждый квадрат рисовать заново? Нет, достаточно его просто размножить. Выделяем наш спрайт, нажимаем на клавиатуре Ctrl + C, затем Ctrl + V и вставляем спрайт в нужном месте, либо щелкаем по спрайту правой кнопкой мыши и выбираем пункт Copy, после щелкаем правой кнопкой мыши по любой точке уровня и выбираем пункт Paste. Вы заметили, что после пункта Paste, присутствует пункт Paste Clone? Paste Clone создает объект, идентичный клонируемому, но по сути - это два совершенно разных объекта с одинаковыми настройками. К примеру, если создать несколько квадратов желтого цвета, а затем попытаться изменить цвет, хотя бы у одного – изменятся цвета всех квадратов. Чего не произойдет при нескольких квадратах, размноженных через Paste Clone.
Создайте несколько квадратов и попробуйте их расставить по уровню.
Хм.. не так-то просто выдержать ровную линию? И для таких случаев у нас есть нужные инструменты. В верхнем меню переходим во вкладку Layout. Выбираем пункт Edit grip и выставляем значения 30х30. Нажимаем ОК. Ставим галочку напротив пункта Snap-to moving (включаем).
Мы создали сетку, размером 30х30 пикселей, по которой можно ровной линией выставлять наши блоки. Для отображения сетки щелкаем по Toggle grid.
Вот теперь расставлять блоки одно удовольствие!
Уровень нарисован, а как сделать фон? В GQ фон сделан через градиент. Давайте повторим. Создаем новый спрайт, указываем ему размеры 128х128. Выбираем инструмент Rectangle Tool. Сверху появились параметры, которые можно менять. В пункте Style, выбираем пятый параметр. Это градиент. Теперь нам нужно выбрать 2 цвета. Первый (выбираем через левую кнопку мыши), – который будет в верхней части изображения, второй (выбираем через правую кнопку мыши) – который будет в нижней части изображения. Далее программа сама сделает плавный переход с первого ко второму цвету. Выбираем темно-синий и синий цвета. Затем выделяем всю область для закрашивания. Сохраняем.
Теперь нам нужно растянуть фон по всему размеру уровня. Можно либо растягивать изображение, либо задать ему нужные параметры напрямую. Делается это так: Выбираем наш фон. Слева в панели Properties открываем вкладку Common и проставляем значения Width и Height. Там же переименовываем спрайт в Fon.
Если сетка мешает, можно отключить ее, сняв галочку с пункта Snap-to moving.
Теперь мы столкнулись с еще одной проблемой – наш фон закрывает все наши блоки. Что ж, будем исправлять.
В правой панельке переходим во вкладку Layers. Мы видим один слой, под названием Layer 1. Так как больше слоев нет, то все объекты создаются на нем. Чуть выше находится меню управления слоями. Зеленая стрелка вверх/вниз – создать слой, который будет находиться выше/ниже существующих. Корзина – удалить выделенный слой Иконка глаза – сделать все объекты выделенного слоя невидимыми. Замок – блокирует перемещение объектов этого слоя. Серые стрелки вверх и вниз – перемещение выбранного слоя вверх или вниз.
Т.к. фон должен находиться под всеми изображениями, щелкаем по зеленой стрелке, направленной вниз. Создался новый слой и ему присвоено имя Layer 2.
Теперь перенесем наш фон в этот слой, для этого просто выделяем фон и перетаскиваем его на Layer 2. Все, теперь все находится на своих местах.
Для удобства можно изменить название слоям. Щелкаем по Layer 2 и в левой панели Properties в пункте Name пишем Fon. Также переименуем Layer 1 в Carcas.
Для удобства можно использовать Замок на слое Fon. В результате чего спрайт фона не будет выделяться, и не будет нам больше мешать.
Часть 3
Создаем и анимируем главного героя, настраиваем управление
Пришло время создавать главного героя. Герой в GQ состоит из двух объектов: 1. “Скелет” героя – он невидим в игре, но именно он отвечает за передвижение героя 2. Его оболочка – то, что мы видим
Зачем такое разделение? Приведу пример: Допустим, мы оставили только лишь одну оболочку и ей дали возможность перемещаться, прыгать, плавать и т.п. Оболочка героя – это его рисунок. Посмотрите на героя GQ. Его рука отходит от одной линии с телом и в результате, при соприкосновении с углами блоков, герой может зависнуть в воздухе, т.к. его рука зацепится о край. “Скелет” же представляет собой прямоугольник, который не имеет вогнутостей и выпуклостей, что означает – цепляться нечему.
Переходим к делу. Создаем новый спрайт размером 25х30. Разукрашиваем, как вздумается, это не имеет значения. Ставим Hotspot на позицию X=13, Y=15. Сохраняем. Переименуем спрайт в bazis. Мы создали “скелет” героя. Что умел персонаж GQ? Ходить влево, вправо, прыгать и стрелять. О стрельбе поговорим в отдельном пункте, об остальном – здесь и сейчас.
Наиболее частые действия для персонажа уже заготовлены разработчиками в виде “поведений”. Выбираем bazis. В панели Properties открываем вкладку Behavior (поведения), нажимаем Add. Перед нами заготовки частых поведений. Некоторые из них будут рассмотрены в этой статье. Выбираем из списка поведение Platform, и оно автоматически применится к нашему спрайту. Поведение Platform – это типичное поведение для героя платформера. С помощью него персонаж может перемещаться по твердым объектам и прыгать.
Давайте сразу сделаем так, чтобы герой был всегда по центру экрана. Выбираем bazis, в панели Properties открываем вкладку Groups – Attributes. И ставим галочку напротив Center view on me.
Неплохо было бы испытать. Располагаем bazis над блоками и запускаем уровень (Run layout). Перед нами возникает такая картина: bazis проходит сквозь блок, падая вниз. Это произошло из-за того, что мы не дали никаких настроек блокам и на данном этапе они выступают лишь как картинки.
Выделяем блок. В панели Properties открываем вкладку Groups – Attributes и ставим галочку напротив пункта Solid (сделать твердым). По твердым объектам можно ходить. Еще можно ходить по Platform. Отличие Solid от Platform в том, что на Platform можно запрыгивать снизу и с них можно спускаться, нажав стрелку вниз и клавишу прыжка.
Делаем повторную проверку. Теперь bazis не проваливается сквозь землю и спокойно перемещается куда нужно.
Давайте настроим управление. При применении к спрайту поведения Platform, ему задается стандартное управление: Стрелки – движение Shift – прыжок
Это управление прописано по адресу: вкладка Project (в правой панельке), Application 1, далее в панельке Properties (слева) вкладка Controls. Move Left – движение влево Move Right – движение вправо Jump – прыжок Остальные нам не нужны. Движение влево и вправо стоит как надо, а вот прыжок изменяем, выбрав клавишу Z.
Теперь изменим высоту прыжка. Выбираем bazis, Properties – Platform Behavior. Изменяем параметр Jump strength с 800 на 325. Мы изменили высоту прыжка, сделав ее меньше. Теперь, если нажать на Z – герой подпрыгнет на фиксированную величину. Но, в GQ, при зажатии клавиши прыжка герой прыгал еще выше, чем при простом нажатии. Для этого нам всего лишь нужно проставить значение Jump sustain time на 250. Этот параметр как раз таки и влияет на продолжительность прыжка.
В той же вкладке рассмотрим еще три параметра. Скорость персонажа на земле определяется параметром Max floor speed. Ставим значение 180. Скорость персонажа в воздухе – параметр Max air speed. Для того, чтобы сделать скорость и на земле и в воздухе одинаковой – ставим одинаковые параметры, т.е. 180. Уберем галочку напротив пункта Allow bunny hop – если этого не сделать, то при зажатой клавише прыжка герой будет прыгать сразу после приземления. В GQ же для повторного прыжка нужно было повторно нажимать прыжок.
Делаем bazis невидимым в игре, ведь он выступает лишь в роли скелета. Делается это просто: Properties – Appearance – ставим галочку напротив Invisible on start.
Самое время создавать оболочку. Создаем новый спрайт размером 25х30, рисуем, проставляем позицию Hotspot на X=13, Y=15 сохраняем. Переименовываем спрайт в Hero. Это будет наш главный герой.
Теперь нужно привязать оболочку к скелету. Открываем редактор событий: снизу в центральном экране переходим во вкладку Event Sheet Editor, либо в правой панельке Project – щелкаем по + у Level 1 (или если не меняли название уровня Layout 1) – Layout 1 events. Открылось окно, в котором мы будем прописывать все события.
Редактор событий - мощный инструмент, благодаря которому не нужно изучать языки программирования, чтобы создать игру. Но это вовсе не означает, что думать нам не придется. У редактора своя логика. Она достаточно простая, нужно ее лишь понять.
Давайте подумаем, что мы хотим сделать. Мы хотим, чтобы всегда объект Hero находился на том же самом месте, что и объект bazis, т.е. прилепить hero к bazis. Реализовываем: Щелкаем правой кнопкой мыши – выбираем пункт Insert event (вставить событие). Далее System – и в выпавшем списке ищем Always (всегда, каждую секунду). Создалось событие.
Справа от него щелкаем по New action (новое действие) – Hero – Set position to another object (установить позицию относительно другого объекта) – Pick an object (выбрать объект) – выбираем bazis – Finish.
Готово, теперь все так, как мы запланировали. Как уже можно было заметить, редактор делится на 2 части: указание действий, которые должны произойти (правая часть редактора) и указание событий, при которых это действие происходит (левая часть).
В данном случае мы сделали действие “Установить позицию объекта Hero относительно объекта bazis”, и событие, когда это действие должно выполняться “Это должно происходить всегда”.
Далее хотелось бы сделать так, чтобы оболочка поворачивалась влево, при движении влево и вправо, при движении вправо. Реализовываем: Данное событие должно выполняться с помощью клавиатуры (ведь движение – это стрелки). В данный момент клавиатура не подключена. Проделываем следующие манипуляции: переходим во вкладку Layout Editor (у центрального окна внизу, либо в правой панельке вкладка Project – Level 1). Правая кнопка мыши по любой области уровня – Insert an object – Mouse & Keyboard. Готово, теперь подключена клавиатура, а заодно и мышь.
Переходим обратно в редактор событий. Создаем событие: Щелкаем правой кнопкой мыши – Insert event (вставить событие) – MouseKeyboard – Key is down? (клавиша нажата?) – выбираем из списка Left arrow (стрелка влево) – Finish. Создаем действие: New action – Hero – Set angle (установить угол) – прописываем значение 180 – Finish.
Мы создали событие, когда при нажатой клавише Стрелка влево герой поворачивается налево. Создадим аналогичное событие, но для другой стороны: Щелкаем правой кнопкой мыши – Insert event (вставить событие) – MouseKeyboard – Key is down? (клавиша нажата?) – выбираем из списка Right arrow (стрелка вправо) – Finish. Создаем действие: New action – Hero – Set angle (установить угол) – прописываем значение 0 – Finish.
Попробуем, как выглядит? Run layout. Ох.. возник косяк, при повороте наш герой поворачивается еще и по оси. Не хорошо. Но исправить это проще простого.
Переходим в редактор уровней (Layout Editor). Выбираем Hero – Properties – Angle – ставим галочку напротив Auto mirror (отзеркаливание). Проверяем. Теперь все ок, персонаж поворачивается по сторонам. Неплохо было бы сразу добавить ему анимации ходьбы и прыжка. Выбираем объект Hero и в правой панели заходим во вкладку Animator. Окно Animator делится на 2 части. Сверху расположен список групп анимаций выбранного объекта (по умолчанию для каждого объекта создается группа Default). Под списком групп отображаются все анимации, которые входят в данную группу. Для того, чтобы их увидеть, щелкните по пункту Angle: 0 (Right) (у вас должен отобразиться 1 спрайт, который вы рисовали для оболочки героя). Для начала, переименуем уже имеющуюся группу анимаций в Stop. Для этого щелкните по Default и в панели Properties измените пункт Animation name.
Давайте создадим анимацию ходьбы. На верхнем окошке панели Animator щелкните правой кнопкой мыши – Add new animation (добавить новую анимацию). Создастся новая группа анимации. Переименуйте ее в Move. Если щелкнуть по Angle: 0 (Right) у группы анимации Move, то мы увидим один пустой спрайт. В Scirra Construct любая группа анимаций не может иметь пустого значения (т.е. нельзя, чтобы в ней не содержалось ни одного спрайта), поэтому и создается пустой спрайт. Просто так удалить его нельзя, нужно сперва создать еще один.
Здесь можно пойти двумя путями: 1. В нижнем окне панели Animator щелкните правой кнопкой мыши – add frame (добавить новый кадр анимации), открываем его и можно рисовать. Только не забудьте указать Hotspot в той же точке, что и у основного спрайта. Если этого не сделать, то в итоге вы получите скачущую картинку. Проще всего указывать у всех спрайтов в анимации одни и те же значения и ставить Hotspot в одну и ту же точку. В нашем случае, значения 25х30, позиция Hotspot: X=13, Y=15. Если использовать этот путь анимирования, то каждый кадр нужно будет рисовать с нуля, что не очень то и удобно. 2. Суть второго метода в том, что мы копируем первый спрайт, и в редакторе Picture Editor лишь изменяем нужные части. Делается это так: Щелкаем по группе анимации Stop – Angle: 0 (Right) – правой кнопкой по имеющемуся у нас единственному спрайту – Copy frames. Далее переходим в созданную группу Move – Angle: 0 (Right) – правой кнопкой по пустому месту нижнего окошка – Paste frames. Все готово, теперь можно рисовать анимацию, на основе уже имеющегося спрайта.
Сейчас ваша задача – нарисовать движение героя. Для этого вам хватит 4-6 кадров анимации. После того, как анимирование завершено – удаляем тот пустой спрайт.
Аналогично рисуем анимацию прыжка. Единственное отличие – прыжок состоит из двух групп анимаций. Создаем первую и называем ее Jump. В ней вы должны нарисовать лишь “взлет” персонажа. В GQ взлет состоит из двух кадров: первый кадр - толчок от земли, второй – полет до верхней точки прыжка.
Создаем вторую группу и называем ее Fall. В ней рисуем падение героя, т.е. кадры с того места, когда он достиг верхней точки прыжка. В GQ на это я потратил 3 кадра.
Все, анимация готова. Сама собой она, конечно, не вставится в игру, поэтому будем ее встраивать руками. Переходим в редактор событий. Давайте проговорим то, что мы хотим сделать. Мы хотим, чтобы при движении героя влево проигрывалась анимация движения в левую сторону (Move), при движении вправо – показывалась анимация движения в правую сторону (Move), при нажатии на клавишу прыжок проигрывалась анимация взлета (Jump), а в тот момент, когда герой падал, нам показывалась анимация падения (Fall).
Прежде чем читать правильное решение, лучше попробуйте реализовать все сами. Если не получилось – не беда, рано или поздно вы поймете логику редактора.
Итак, правильное решение: Добавляем новое событие – bazis – сверху переходим во вкладку Platform – выбираем пункт Is moving (в движении). Это еще не все. Ведь персонаж может быть в движении, как в воздухе, так и на земле. Нам же нужно, чтобы проигрывалась анимация движения только тогда, когда он на земле. Для этого щелкаем правой кнопкой мыши по только что созданному событию – выбираем пункт Insert new condition – bazis – вкладка Platform – Is on ground (на земле). Мы создали такое событие, при условии которого наш герой находится и в движении и при этом на земле. Добавляем действие – New action – Hero – Set animation – и прописываем “Move” (вместе с кавычками). Теперь герой будет ходить, но появилась новая проблема – он будет ходить даже тогда, когда будет стоять на месте. Давайте сделаем так, чтобы при остановке, герой менял анимацию на Stop. Новое событие – bazis – вкладка Platform – Is on ground Щелкаем правой кнопкой мыши по только что созданному событию – Insert new condition (далее, для краткости, я буду называть это вторичным событием) – bazis – Platform – Is moving. Теперь нажимаем правой кнопкой мыши по созданному событию Is moving – Invert condition. Invert condition – это обратное событие. Т.е. если у нас событие “Герой в движении”, то если применить к нему Invert condition, мы получим обратное событие “Герой не в движении”, т.е. стоит на месте. Создаем к событию действие – New action – Hero – Set animation – прописываем “Stop” (с кавычками). Анимация движения для героя на земле готова. Создадим анимацию прыжка:
Новое событие – bazis – Platform – Is jumping (в прыжке) Действие – New action – Hero – Set animation – “Jump”
Ну и анимация падения: Новое событие – bazis – Platform – Is falling (падает) Действие – New action – Hero – Set animation – “Fall”
Если сейчас вы запустите уровень, то заметите косяк со скоростью – она слишком высокая. Настроить скорость можно очень просто: Переходим во вкладку Layout Editor и выделяем Hero. Выберите группу анимаций Move и в ней – Angle: 0 (Right). В панели Properties пункт Animation speed отвечает за скорость изменения кадров этой группы. Для каждого объекта выставляется своя скорость, в зависимости от количества кадров и нужного эффекта. В GQ я поставил скорость = 6. Также обратите внимание на пункт Loop – это зацикливание анимации. Т.е. когда будут проиграны все анимации в выбранной группе – они начнут проигрываться заново. Для группы Move – этот параметр оставляем включенным, а вот для групп Jump и Fall – выключаем.
Поздравляю. Персонаж полностью анимирован.
Часть 4
Создаем призраков и здоровье героя
Какой же платформер без врагов? Нужно населить ваш виртуальный мир монстрами, которые так и норовят откусить от героя кусок, да побольше.
Начнем мы, как всегда, с малого. Помните летающего призрака, самого первого противника в GQ? Вот его-то мы сейчас и реализуем.
Создаем новый спрайт размерами 14х25, рисуем что-то похожее на летающую простыню с глазами и проставляем значения Hotspot по центру (X=7, Y=12). P.S. если рисунок создается за фоном – то перетаскиваем его на слой выше (в нашем случае – на слой Carcas). Чтобы рисунки всегда создавались на слое Carcas, нужно просто выделить его. P.P.S. если вы не можете перетаскивать спрайт, проверьте, не стоит ли замок на том слое, на котором он находится.
Переименуйте спрайт в Ghost. Далее добавляем поведение призраку. Выделяем Ghost – Properties – Behaviors – Add – Bullet. Bullet (пуля) – это поведение, при котором объект всегда летит прямо в выбранном направлении. Сразу изменим пункт Speed (скорость), поставив значение 50. И сделаем отзеркаливание – Properties – Angle – Auto mirror.
Нажимаем Run layout, проверяем. Наш призрак летит вправо с невысокой скоростью. Как же заставить его повернуть?
Здесь мы можем пойти двумя путями. Первый зависит от времени, второй – от конкретных позиций на уровне (в GQ использовался второй метод).
Первый путь. Суть его в том, что каждые X секунд призрак поворачивается и идет в противоположную сторону. Когда X секунд прошло снова – призрак вновь поворачивает и так до бесконечности. Реализация: Переходим в редактор событий. Новое событие – System – Every X milliseconds – и пишем значение времени, допустим, 5 секунд (время в редакторе указывается в миллисекундах, т.е. 1 секунда = 1000 миллисекунд, соответственно 5 секунд = 5000 миллисекунд). Действие – New Action – Ghost – Set Angle (установить угол) – пишем Ghost.Angle+180
Разберем фразу Ghost.Angle+180 Слово перед точкой обозначает объект, над которым мы хотим провести манипуляции. Нашим объектом является призрак Ghost. После точки указываем то, что хотим изменить. Мы хотим изменить угол (Angle). По умолчанию угол равен 0 градусов. К этим 0 градусам мы каждые пять секунд добавляем 180 градусов, т.е. пишем “+180”. Можно написать “-180”, значения не имеет.
Проверяем – все нормально, призрак поворачивается каждые 5 секунд в другую сторону.
Второй путь (или путь самурая). Удаляем все то, что мы нахимичили в первом методе. Переходим в Layout Editor и создаем новый спрайт, размеры произвольные (для удобства поставьте где-то 10х50), заливаем его любым цветом, сохраняем, переименовываем в Wall. Объект Wall – это стенка, при соприкосновении с которой призрак поворачивается на 180 градусов. Эта стенка не должна быть видимой в игре, поэтому выделяем ее – Properties – Appearance – ставим галочку у пункта Invisible on start.
Логично предположить, что стенок должно быть две: одна слева, вторая справа. Поэтому копируем Wall и ставим одну стенку на позиции, где призрак должен поворачиваться влево, а вторую на позиции, где призрак должен поворачиваться вправо. Между ними располагаем призрака.
Переходим в редактор событий. Новое событие – Ghost – On collision with another object (взаимодействует с другим объектом) – Pick an object (выбрать объект) – Wall – Finish. Действие – New Action – Ghost – Set angle – прописываем Ghost.Angle+180 – Finish.
Все готово. Получился летающий призрак, но… Какой-то он не реалистичный. Можно, конечно, нарисовать ему пару анимаций, но мы пойдем другим путем.
Переходим в Layout Editor. Выделяем Ghost – Properties – Bullet Behavior – Add – Sine Изменяем следующие параметры: Period (частота) – ставим 1600 Range (высота) – 5
Смотрим что получилось. Вполне себе симпатично, и без анимирования. А если еще и анимацию добавить…
Что-то в этом призраке не так.. Он не атакует героя. Пока что наш герой бессмертный, давайте это исправим.
Выделяем bazis – Properties – Private Variables – Add/Edit Вылезло небольшое окно, в котором хранятся все переменные объекта bazis. Переменные – это очень важная функция. С помощью нее можно реализовать очень и очень много действий. Как пример: здоровье героя и врагов, патроны к оружию, очки, модели поведения любых объектов на экране. Я вам настоятельно рекомендую почитать специализированные статьи по переменным, т.к. без их знания даже в Scirra Construct далеко не уедешь.
Рассмотрим, что можно здесь сделать: Зеленый крест – добавить новую переменную Красный крест – удалить выбранную переменную Листок с карандашом – редактировать выбранную переменную Стрелки – перемещение выбранной переменной выше/ниже
Нажимаем на зеленый крест. И изменяем следующие параметры: Name – Life Type (тип переменной: числовой или текстовый) – Оставляем Number Initial (значение при старте) – 4
Мы создали частную переменную для объекта bazis со значением 4. Предполагается, что это 4 жизни у героя.
Переходим в редактор событий. Новое событие – bazis – On collision with another object – Pick an object – Ghost – Finish Действие – New action – bazis – Substruct from value – в пункте Value прописываем 1
Теперь при соприкосновении героя с призраком, у героя отнимается единица из переменной Life. Давайте сделаем так, чтобы при Life = 0 герой умирал.
Новое событие – bazis – Compare a private variable и проверяем, чтобы следующие параметры были такими: Private variable (частная переменная) – Life Comparison – Equal to (равно) Value – 0 Т.е. частная переменная Life равна 0. Если все ок - Finish
У Comparison есть еще несколько параметров, на все случаи жизни: Not equal to – не равно Less than – меньше, чем Less or equal – меньше или равно Greater than – больше, чем Greater or equal – больше или равно
Действие – New action – bazis – Destroy Вторичное действие (еще одно действие для этого же события) – New action – Hero – Destroy.
Теперь, если вы соприкоснетесь с призраком 4 раза – герой умрет.
Неплохо было бы сделать, чтобы героя отталкивало от призрака, при соприкосновении. Можно делать отдачу для каждого типа призраков отдельно, но мы позаботимся обо всех сразу.
Переходим в Layout editor и выделяем Ghost – Properties – Groups – Families – Add – выделяем Enemy - Ok Нашему призраку добавился класс Enemy. Теперь мы будем всех призраков добавлять в данный класс, чтобы им устанавливались одинаковые настройки.
!!!ВНИМАНИЕ!!! Следующая реализация соприкосновений работает не совсем корректно, в чем причина – напишу несколькими абзацами ниже.
Переходим в редактор событий. Новое событие. Обратите внимание, что добавилась группа Families. Группы и пункты добавляются в редактор событий только в том случае, если они присутствуют в Layout Editor или в параметрах у уже созданных объектов. Выбираем Enemy – On collision with another object – Pick an object – bazis
Правой кнопкой мыши по только что созданному событию – Insert sub-event (вставить под-событие) – Hero – Compare angel – пишем 0 – Finish Опять правой кнопкой мыши по созданному под-событию – Insert sub-event – System – Trigger once while true (выполнить один раз, если правда) Действие – New action – bazis – Platform – Set X component of motion – пишем -500 (минус пятьсот) - Finish
Sub-event (под-событие) – это события, которые будут выполняться только в том случае, если будет выполнено событие, находящееся выше него.
Мы сделали так, что при соприкосновении bazis с любым призраком, входящим в группу Enemy, включалось под-событие, которое проверяет, в какую сторону смотрит наш герой. Если герой смотрим в правую сторону (0 градусов), то его отталкивает на 500 единиц влево.
Теперь сделаем аналогичное действие, но для того события, когда герой смотрит влево (180 градусов).
Новое событие – Enemy - On collision with another object – Pick an object – bazis Создаем sub-event – hero – Compare angel – пишем 180 – Finish Sub-event для только что созданного sub-event’а – System – Trigger once while true Действие – New action – bazis – Platform – Set X component of motion – пишем 500 - Finish
Все готово, проверяем.
Перед реализацией данной системы, я писал, что у нее есть один существенный минус. Минус заключается в том, что даже если вы будете просто стоять на месте так, чтобы герой смотрел в левую сторону, а призрак подойдет с правой стороны – героя все равно унесет в правую сторону, за место положенной левой. Если кто-то знает, как сделать нормальную коллизию героя – напишите, я изменю этот пункт.
P.s. в пункте 12 сделана некорректная реализация столкновений. Если кто знает как исправить - пишите, я исправлю текст. P.p.s. у меня очень жесткий интернет, поэтому я не смогу прикрепить картинки к каждому действию. Буду рад, если кто-нибудь сделает это за меня.
Сообщение отредактировал: Loko™ - Суббота, 28.07.2012, 07:12
Текст сообщения превышает допустимый лимит. В первый пост смог добавить лишь 4 части. Остальные пишу в этом посте.
Часть 5
Стрельба и уничтожение противника
Далее я хотел бы показать вам, как реализовать стрельбу. Для начала, нам понадобиться реализовать пулю. Переходим в Layout Editor, создаем новый спрайт с размерами 20х15 и точкой Hotspot по центру (10х8), рисуем пулю, сохраняем. Если вы хотите, чтобы ваша пуля была не статичной, а, например, как огненное кольцо в GQ – добавляем новые кадры анимации в группу Default. В GQ огненное кольцо состоит из 5 кадров, а скорость смены кадров – 10, зацикливание включено.
Далее выделяем пулю, переименуем спрайт в Bullet и добавим поведение пули: Properties – Behaviors – Add – Bullet Изменим скорость (Speed) на 330 Также изменим пункт Destroy when (когда уничтожить) на Offscreen (за пределами экрана).
Переходим в редактор уровней. Новое событие – MouseKeyboard – On key pressed – выбираем X – Finish Создаем вторичное событие (Insert new condition) – Hero – Compare angel – Finish Создаем третичное событие (Insert new condition) – System – Compare и далее прописываем: Value 1 – bullet.count Comparison – Lower than Value 2 – 3 И создаем последнее событие (Insert new condition) – System – Every X milliseconds – 100 – Finish
Первым действием мы указали, на какую клавишу нажал игрок. X – это клавиша, на которую будет осуществляться стрельба. Можете изменить на нужную. Вторичным событием мы вычислили угол, т.е. сторону, в которую повернут герой. Третичное событие – ограничили число выстрелов. Т.е. если пуль на экране больше, чем 3 – герой больше не будет стрелять. Ну и последним событием мы ограничили частоту выстрелов. Чем больше число – тем реже герой сможет стрелять. Проследите за тем, чтобы четвертое событие стояло на последнем месте, иначе, перед стрельбой будет задержка в 100 миллисекунд.
Новое действие – New action – Hero – Spawn another object (создать объект) – Pick an object (выбор создаваемого объекта) – Bullet – где Layer (слой) ставим 2, где Image point name or number ставим 1 – Finish Еще одно действие – New action – Bullet – Set angle – 0 – Finish
Мы сделали так, что bazis создает внутри себя другой объект на слое 2, и устанавливает ему угол, равным 0 градусов (т.е. пуля летит вправо). Как вы помните, на первом слое у нас фон, на втором – каркас. Пулю нужно создавать на том слое, где у нас находится герой, а герой у нас находится на втором слое. Если вы будете создавать больше слоев – всегда следите за тем, на каком из них находится герой и на каком создается пуля. Номера слоев написаны слева от названия, под изображением замка.
Теперь сделаем все то же самое, но для левой стороны.
Новое событие – MouseKeyboard – On key pressed – выбираем X – Finish Создаем вторичное событие (Insert new condition) – Hero – Compare angel – 180 – Finish Создаем третичное событие (Insert new condition) – System – Compare и далее прописываем: Value 1 – bullet.count Comparison – Lower than Value 2 – 3 И создаем последнее событие (Insert new condition) – System – Every X milliseconds – 100 – Finish Опять-таки проследите, чтобы четвертое событие стояло на последнем месте.
Новое действие – New action – Hero – Spawn another object – Pick an object – Bullet – где Layer ставим 2, где Image point name or number ставим 1 – Finish Еще одно действие – New action – Bullet – Set angle – 180 – Finish
Можно проверить что получилось. По нажатию X из героя вылетает пуля, их число ограничено, интервал стрельбы тоже ограничен, пуля летит в нужную сторону. Все вроде ничего, но как сделать так, чтобы пуля вылетала не из другой части героя, а, к примеру, из его головы, руки или левой пятки? Перейдите в Layout Editor и щелкните два раза по спрайту Hero. Далее в Picture Editor, на левой панельке выберите Image points и поставьте его в ту точку, из которой хотите, чтобы пули вылетали.
Так, теперь нужно реализовать, чтобы призраки от выстрелов исчезали. Сделаем так, чтобы призрака можно было убить с двух выстрелов. Для этого нужно дать призраку переменную Life, и указать число при старте – 2.
Выбираем призрака – Properties – Private Variables – Add/Edit. Создаем новую переменную с именем Life, Type – Number, Initial – 2.
Переходим в редактор событий. Мы должны создать такое событие, когда при столкновении пули с призраком, у него отнималась одна единица жизни и пуля исчезала.
Новое событие – Bullet – On collision with another object – Pick an object – Ghost Действие – New action – Ghost – Subtract from value – Private variable: Life, Value: 1 – Finish Вторичное действие – New action – Bullet - Destroy
Далее нужно создать такое событие, что когда переменная Life = 0, призрак уничтожался.
Новое событие – Ghost – Compare a private variable – Private variable: Life, Compression: Equal to, Value: 0 – Finish Действие – New action – Ghost – Destroy
Проверяем. Еще было бы неплохо анимировать героя, когда он совершает выстрел. Но это, я думаю, вы теперь и сами сможете сделать.
Часть 6
Создаем удобства (ESC, рестарт)
Основная механика готова. Давайте, теперь реализуем некоторые удобства, такие, как выключение игры клавишей, растягивание на весь экран и рестарт уровня.
Первое – это совсем просто. Новое событие – MouseKeyboard – On key pressed – Escape Действие – New action – System – Close Готово.
Теперь реализуем растягивание уровня по всему экрану. Переходим в Layout Editor и дважды щелкаем по пустому месту на уровне. Выбираем объект Window. Переходим обратно в редактор событий. Новое событие – MouseKeyboard – On key pressed – F1 Действие – New action – Window – Maximize Это мы сделали растягивание по нажатию клавиши F1.
Новое событие – MouseKeyboard – On key pressed – F2 Действие – New action – Window – Restore А это мы уже реализовали возвращение экрана к первоначальным настройкам.
Все готово. А что там с рестартом? Здесь суть в том, что при включении игры, происходит сохранение, а при нажатии клавиши R – игра загружала это сохранение.
Новое событие – System – Start of layout Действие – New action – System – Quicksave / Quickload – Quicksave – Finish
Теперь при старте уровня игра сохраняется. Реализуем загрузку:
Новое событие – MouseKeyboard – On key pressed – R Действие – New action – System - Quicksave / Quickload – Quickload – Finish
Готово.
Часть 7
Интерфейс: жизни и очки
Наш интерфейс будет показывать жизни и очки. Для отображения жизней нам понадобиться 4 спрайта. Рисуем 1 кружок серого цвета, размером 21х21 . Не забудьте Hotspot выставить по центру. Копируем круг и вставляем три раза через Paste clone. Итого у нас должно получиться 4 спрайта, дайте им следующие имена: 1. Life1 2. Life2 3. Life3 4. Life4
Создаем новый слой, который будет расположен выше всех. Повторю, как это сделать: В правой панельке переходим во вкладку Layers и нажимаем на зеленую стрелку вверх. Имейте ввиду, чтобы жизни и очки отображались поверх всего остального в игре, нужно, чтобы только что созданный слой всегда был сверху.
Выделите слой, переименуйте его в Info. А также измените следующие параметры у слоя: Scroll X Rate – 0% (скорость прокрутки по X) Scroll Y Rate – 0% (скорость прокрутки по Y) Тем самым мы отключили прокрутку слоя Info.
Перетащите кружки на слой Info.
Переходим в редактор событий. Сейчас мы будем делать несколько событий, направленных на одно и то же действие – отображение здоровья. Но, прежде чем начать, для удобства, можно создать группу, в которой мы будем хранить все эти события. Делается это так: Правой кнопкой мыши по пустому месту в редакторе событий – Insert group. Title – это название группы, напишите Score and Lifes. Description – описание, напишите: “Здесь хранятся события, отображающие жизни и очки”. Сейчас вы можете наплевать на это действие, объяснив это тем, что итак знаете, что да где расположено. Но через некоторое время, когда вы решите что-то доработать или исправить, вы просто забудете, где, то самое событие, и вам придется перебирать все имеющееся.
Ближе к делу. Новое событие – bazis – Compare a private variable – Life, Equal to, 0 – Finish Действие 1 – New action – Life1 – Set position - -200 (минус двести); -200 (минус двести) - Finish Действие 2 – New action – Life2 – Set position - -200 (минус двести); -200 (минус двести) - Finish Действие 3 – New action – Life3 – Set position - -200 (минус двести); -200 (минус двести) - Finish Действие 4 – New action – Life4 – Set position - -200 (минус двести); -200 (минус двести) - Finish
Сейчас мы сделали так, что когда у героя не остается жизней, все круги выходят за пределы экрана, т.е. становятся для игрока невидимыми. Теперь нужно сделать почти аналогичные действия, но для событий, когда у героя остается 1, 2, 3 или 4 жизней.
Новое событие – bazis – Compare a private variable – Life, Equal to, 1 – Finish Действие 1 – New action – Life1 – Set position - 35; 25 - Finish Действие 2 – New action – Life2 – Set position - -200 (минус двести); -200 (минус двести) - Finish Действие 3 – New action – Life3 – Set position - -200 (минус двести); -200 (минус двести) - Finish Действие 4 – New action – Life4 – Set position - -200 (минус двести); -200 (минус двести) - Finish
У этого события два отличия от предыдущего: 1. Рассматривается событие, когда у игрока осталась 1 жизнь 2. Когда у игрока осталась одна жизнь, три круга вылетают за экран, но один остается на позиции 35; 25, т.е. остается там, где ему и положено быть.
Продолжаем. Новое событие – bazis – Compare a private variable – Life, Equal to, 2 – Finish Действие 1 – New action – Life1 – Set position - 35; 25 - Finish Действие 2 – New action – Life2 – Set position - 70; 25 - Finish Действие 3 – New action – Life3 – Set position - -200 (минус двести); -200 (минус двести) - Finish Действие 4 – New action – Life4 – Set position - -200 (минус двести); -200 (минус двести) - Finish
Новое событие – bazis – Compare a private variable – Life, Equal to, 3 – Finish Действие 1 – New action – Life1 – Set position - 35; 25 - Finish Действие 2 – New action – Life2 – Set position - 70; 25 - Finish Действие 3 – New action – Life3 – Set position - 105; 25 - Finish Действие 4 – New action – Life4 – Set position - -200 (минус двести); -200 (минус двести) - Finish
Новое событие – bazis – Compare a private variable – Life, Equal to, 4 – Finish Действие 1 – New action – Life1 – Set position - 35; 25 - Finish Действие 2 – New action – Life2 – Set position - 70; 25 - Finish Действие 3 – New action – Life3 – Set position - 105; 25 - Finish Действие 4 – New action – Life4 – Set position - 140; 25 - Finish
Вот и все готово.
Приступим к реализации очков. Если мы хотим, чтобы очки продолжали накапливаться на всех уровнях, а не каждый раз заново, то частная переменная нам не поможет. Для этих целей нам понадобится глобальная переменная. Глобальные переменные сохраняются на протяжении всех уровней, а частные – только на выбранном.
Создаем глобальную переменную: В правой панели переходим во вкладку Project – щелкаем правой кнопкой мыши на папке Global Variable – Add global variable Name – Score Type – Number Initial - 0
Глобальная переменная добавлена. Далее добавляем текст, который будет отображать переменную. Переходим в Layout Editor. Правой кнопкой мыши – Insert an object – Text – щелкаем в любое место. Выделяем текст – Properties: Name – text_score X – 704 Y – 20
Ниже, во вкладке Properties настраиваем: Size (размер) – 24 Ставим галочку напротив Bold (жирный) и Italics (курсив) Color (цвет) – Light Grey (4 ряд, 8 место)
Также проследите за тем, чтобы текст был на слое Info.
Возвращаемся в редактор событий. Находим наше самое первое событие Always, к нему добавляем новое действие: New action – text_score – Set text (установить текст) – внизу, из списка объектов, выбираем System – Get global variable (получить глобальную переменную): Теперь в поле Text вы увидите строку global(‘Variable name’). Если вместо Variable name просто вписать имя глобальной переменной (score), то на экране будут отображаться только цифры (очки). Нам же нужно, чтобы перед цифрами была надпись, которая показывает, что это за цифры. Для этого перед global(‘Variable name’) нужно написать тот текст в кавычках, который мы хотим видеть перед цифрами, и соединить текст и цифры знаком &. Итого в поле Text пишем: "Score: "&global('Score')
Готово, теперь на экране есть надпись, показывающая очки. Что теперь? А теперь мы сделаем сбор очков и назначим награду за призраков.
Сперва разберемся с призраками: Найдите наше событие Ghost: Value ‘Life’ Equal to 0 Как вы помните, оно означает, что когда здоровье у призрака равно 0 – он исчезает. Добавим за это награду: New action – System – Add to value – Variable: Score, а в пункте Value ставим награду, допустим в 10 единиц - Finish Готово, теперь за убийство призраков дается 10 очков.
Организуем сбор очков. Нам понадобится новый круглый спрайт, размером 10х10, желтого цвета. Рисуем, сохраняем, переименовываем в Point, расставляем их по уровню. Проследите за тем, чтобы Point были расположены на слое Carcas.
Заходим в редактор событий. В нашей группе Score and Lifes создаем новое событие – Hero – On collision with another object – Pick an object – Point – Finish Вторичное событие – System – For Each Object – Pick an object – Point – Finish Проследите за тем, чтобы событие For Each Object было выше события On collision… New action – Point – Destroy New action – System – Add to value – Variable: Score, Value: 10 – Finish
Если не прописывать событие For Each Object, то вы можете столкнуться с такой проблемой: когда герой взаимодействует сразу с двумя спрайтами Point, очки добавляются только за один спрайт.
Часть 7
Переход на новый уровень
Перед тем, как устраивать переход на другой уровень, нужно, чтобы этот самый другой уровень существовал. Опять-таки есть два способа создания уровней: 1. На правой панели переходим во вкладку Project – нажимаем правой кнопкой мыши по Layouts – Add layout. Уровень создан. Но он…совершенно пустой. А если вы хотите, чтобы все настройки со старого уровня перенеслись на новый? Тогда читаем второй способ.
2. На правой панели переходим во вкладку Project – нажимаем правой кнопкой мыши по Layout 1 – Clone layout. Все готово, теперь у вас 2 идентичных уровня, причем при изменении местоположения спрайтов или их удаление на одном уровне, не будут сказываться на другом. Но! Если изменять спрайты в Picture Editor – то они будут изменяться на обоих уровнях сразу!
Обратите внимание, что в созданном новом уровне, отсутствуют настройки из редактора событий первого уровня. Их нужно просто скопировать.
Допустим, вы создали два уровня. Как теперь их соединить? Суть в том, что когда спрайт соприкасается с невидимым объектом, запускается событие, которое переносит нас на другой уровень. Значит, нам нужен этот самый невидимый спрайт. Создаем новый спрайт, размерами 30х200, ставим его в конец уровня, где будет осуществляться переход, изменим имя на Next, а ниже, во вкладке Appearance ставим галочку напротив Invisible on start.
Переходим в редактор событий. Новое событие – Hero – On collision with another object – Pick an object – Next – Finish Действие – System – Next layout – Finish
Готово.
Эпилог
Эпилог
Вот и все. Я надеюсь, что дал вам необходимую информацию по созданию 2D платформера а-ля Ghost Quest. Удачи в разработке. Создавайте только хорошее =)
Сообщение отредактировал: Loko™ - Суббота, 28.07.2012, 07:09
Хочу задать вопрос Loko: Создал монстра, все сделал как вы тут писали, все ок. Но когда я создал другого монстра (круче) то он стал не убиваем, все сделал как вы пишите в части 5. Он ходит, плюется слизью, но не убиваем… подскажите, в чем может быть косяк!
Сообщение отредактировал: Гость8558 - Среда, 12.12.2012, 06:18
Гость8558, проверь вот эту функцию: Bullet – On collision with another object – Pick an object – Ghost Вместо Ghost, ты ставил значение своего второго монстра?
Если да, то в этой функции: Ghost – Compare a private variable – Private variable: Life, Compression: Equal to, Value: 0 – Finish Действие – New action – Ghost – Destroy Вместо Ghost прописывал своего второго монстра?
p.s. если вопрос не решен - скинь исходник в ЛС, я посмотрю
разобрался... в части пять вы пишите "Создаем новую переменную с именем Life, Type – Number, Initial – 2." но когда я ставил минус перед значением, монстры не убиваемы. Убрал минус(значение положительное) и монстр погибает Вот такая фигня... (два дня сидел так тупил)
Добавлено (14.12.2012, 07:03) --------------------------------------------- Еще один вопрос к автору. Я сделал слизь на потолке, типа чтобы капало и убирала жизни при столкновении с каплей. Но мои попытки, что бы слизь капала не по горизонтали а в низ увенчались крахам. Забил для нее такие задачи. задача Sistem - Every X Milliseconds - Milliseconds:2000 действие Sliz_bed(которая весит на потолке)- Spawan another object - object: Sliz(капли слизи), layer:1, Image...:"point" действие Sliz(капли слизи)- Set angle-Angle:90 Подскажите плиз, в чем касяк!
Сообщение отредактировал: Гость8558 - Пятница, 14.12.2012, 10:39
Создаешь 2 объекта: icicle (сосулька) - это объект, в котором будет создаваться капля drop (капля) - собственно объект, который будет падать вниз
Даешь капле поведение Physics. Ставишь галочку напротив Gravity. World Y scale - скорость падения.
В редакторе событий: Событие: System - Every X milliseconds - 1000 - Finish Действие: System - Create object relative to object - в поле Object кликаем на Pick an object - drop - в поле Object to position to - icicle - не забываем указать нужный слой - Finish
Добавлено (15.12.2012, 07:51) --------------------------------------------- Блин, теперь другой касяк с этой слизью: капли капают только из одной слизи на потолке, при копировании слизи на другое место, капоте не из всех, а только из первосозданной... в чем может быть косяк...?
Сообщение отредактировал: Гость8558 - Суббота, 15.12.2012, 08:07
Гость8558, прости, как-то не подумал про множество капель =) Функция System - Create... - создает капли в одной указанной области. А если нужно создать во всех областях одного вида, то используется Spawn.
Т.е. то действие замени на: icicle - Spawn another object - Pick an object - drop - Finish
p.s. если будут еще вопросы, задавай их здесь: Вопрос - Ответ
Сообщение отредактировал: Loko™ - Суббота, 15.12.2012, 09:09