construct 2 создание меню
Как сделать игру в Construct 2? Добавляем меню и сохраняем прохождение игры
В первых трех статьях вы узнали, как создать проект, оформить уровни и сделать переходы между уровнями. В этой четвёртой статье мы сделаем меню игры, сделаем сохранение прохождения игры и добавим новый уровень.
Создание меню игры
Сначала добавим макет для меню. При добавлении макета выберите создание новой страницы событий, см. картинку.
Макет для меню назовите «Menu», а страницу событий для меню назовите «MenuEvents».
Выставьте такие же размеры для макета (1080 x 1920) и свойству «Unbounded scrolling» установите значение «Yes».
В свойствах проекта сразу установите первый макет, который по умолчанию будет стартовать. У нас – это макет «Menu».
Для меню я буду использовать другую фоновую картинку, поэтому на новый макет добавьте спрайт с именем «MenuBackground» и загрузите фоновую картинку (которую я заранее нарисовал). Как это сделать было описано во второй статье про создание игры с помощью Construct 2. Моя картинка имеет те же размеры, что и макет, поэтому её достаточно отцентрировать, чтобы она закрыла всё пространство макета. После центрирования, нужно на страницу событий «MenuEvents» добавить обработчик события «On resized» объекта «Browser», по которому нужно подровнять ширину фоновой картинки (как это описано в третьей статье про создание игры с помощью Construct 2). В результате у вас должна получиться обработка события, как показано на картинке.
На самом деле вы можете просто скопировать всю обработку события со страницы «Event sheet 1», вставить всё на страницу «MenuEvents», а затем просто поменять объект с которым вы производите действия. Для этого щёлкните правой кнопкой мышки по действию и выберите пункт меню «Replace object».
После этого выберите другой объект, с которым нужно произвести действие. В нашем случае – это спрайт «MenuBackground».
После смены вы увидите, что по событию «On resized» будет изменяться размер объекта «MenuBackground».
Также, нужно сделать фон чёрным, сделать плавное появление меню и подровнять фоновую картинку, как это было описано в третьей статье. Для этого на странице «MenuEvents» добавьте несколько действий по событию «On start layout», см. картинку.
Теперь на страницу меню добавим карту уровней. По карте уровней игрок будет видеть, сколько всего в игре уровней и какие из них доступны для прохождения. Для начала добавьте на макет новый объект «Sprite» (пункт контекстного меню «Insert new object»), который назовите «Level».
Увеличьте размер картинки до 500×500.
Задайте размер для кисти 299, жесткость 20, цвет белый и один раз щёлкните примерно посередине.
После этого обрежьте картинку (кнопка «Crop transparent edges»).
И отцентрируйте исходную точку.
Пройденные уровни будем отображать белыми кругами с сине-красным свечением по краям, непройденный, но доступный для прохождения уровень – белым кругом с белым свечением вокруг, все остальные уровни будут чёрными кругами с чёрным свечением вокруг. Чтобы в будущем менять картинку обозначающую уровень, будем использовать три кадра анимации. Тогда нам просто нужно будет отображать один из трёх кадров, в зависимости от состояния уровня. Для начала добавим в наш объект «Level» ещё два кадра анимации. Для этого щёлкните по пустому пространству окошка «Animation frames» правой кнопкой мышки и выберите пункт «Add frame».
Теперь точно также как мы сделали белую картинку, сделайте чёрную картинку: увеличьте картинку кадра до размера 500×500, нарисуйте точку чёрной кистью диаметром 299 и жёсткостью 20, обрежьте картинку и центрируйте исходную точку. В результате у нас получилось два кадра. Один кадр с белой картинкой, второй кадр – с чёрной.
Теперь добавьте ещё один кадр, в котором будет картинка, обозначающая пройденные уровни. Здесь я воспользовался сторонним графическим редактором, чтобы нарисовать красно-синее свечение. Я сохранил белую картинку (кнопка «Save the image to a file»), подрисовал цветное свечение и загрузил картинку в новый кадр (с помощью кнопки «Load an image from a file»). После того как все кадры будут готовы и исходные точки отцентрированы выставьте кадры в следующем порядке, как показано на картинке, см. окно «Animation frames».
Запустите макет и посмотрите, что получилось. После запуска мы видим чёрную картинку, потому, что анимация отработала и остановилась на последнем кадре. Это нормально.
Теперь добавьте столько картинок-уровней, сколько уровней в игре. У нас пока три уровня, поэтому всего будет три картинки. Чтобы добавить уровни можно просто нажать клавишу Ctrl и, не отпуская её, схватить картинку мышкой, перетащить её и отпустить. После этого создастся копия.
После добавления переменной она появится прямо на панели свойств «Properties».
Теперь для каждой картинки, обозначающей уровень, можно задать номер. По очереди выделите каждый экземпляр объекта «Level» на макете «Menu» и на панели «Properties» задайте номера 1, 2 и 3. После этого мы сможем отличать наши экземпляры.
Теперь добавим в проект глобальную переменную «OpenLevels», в которой будем хранить количество открытых для прохождения уровней. Глобальную переменную в проекте Construct 2 можно добавить на любой странице событий. Для того чтобы это сделать, откройте страницу событий «MenuEvents», щёлкните правой кнопкой мышки на пустом пространстве страницы и в контекстном меню выберите пункт меню «Add global variable».
В появившемся диалоге «New global variable» укажите имя переменной в поле «Name», тип «Number» в поле «Type» и значение по умолчанию 1 в поле «Initial value».
Когда всё указано, нажмите кнопку «OK». После этого переменная появится на странице событий, см. картинку.
Теперь при старте макета по событию «On start layout» нужно показать белыми с красно-синим свечением столько уровней, сколько хранится в переменной «OpenLevels» минус 1. Белым нужно показать уровень, номер которого соответствует значению переменной «OpenLevels». Все остальные уровни должны отображаться чёрными. Чтобы это сделать, нужно в цикле сравнить значение переменной «Num» каждого экземпляра объекта «Level» со значением глобальной переменной «OpenLevels». И если значение переменной «Num» меньше значения переменной «OpenLevels», то уровень должен выглядеть сине-красным, если равно значению «OpenLevels», то белым, иначе – чёрным.
В поднявшемся диалоге «Add event» выберите «System» и нажмите «Next».
На следующем шаге выберите событие «For Each» (это событие произойдёт для всех экземпляров указанного объекта). Нажмите «Next».
В диалоге «Parameters for System: For Each» выберите объект «Level», ведь у всех экземпляров этого объекта нам нужно проверять переменную «Num». Нажмите «Done».
В появившемся диалоге опять выберите «System» и нажмите «Next». На следующем шаге выберите событие «Compare variable» (сравнить переменную) и нажмите «Next».
В следующем диалоге «Parameters for System: Compare variable» укажите переменную, значение которой нужно проверить в поле «Variable», в нашем случае это переменная «OpenLevels». Также в поле «Comparison» (сравнение) укажите, как сравнивать, в нашем случае – это «> Greater then» (больше чем). В поле «Value» нужно указать, с чем сравнивается переменная. В нашем случае сравнение производится с переменной «Num» экземпляра объекта «Level», поэтому здесь мы пишем так: Level.Num.
Кстати, можно воспользоваться полупрозрачным окошком помощи «Objects with expressions» для поиска нужного объекта и свойства (на картинке у окошка в заголовке написано «‘Level’ expressions»). Т.е. сначала ищите нужный объект в этом окошке, дважды щёлкаете по нему, затем ищите нужное свойство выбранного объекта или переменную и также дважды щёлкаете для выбора.
Нажмите «Done», чтобы подтвердить ввод и закрыть окно.
Теперь нужно добавить обработку событий. Для каждого экземпляра объекта «Level», независимо от значения переменной «Num» нужно остановить анимацию. Поэтому сначала добавляем действие для события «For each». Для этого щёлкните по ссылке «Add action» справа от события.
В появившемся диалоге «Add action» выберите объект «Level» и нажмите «Next».
На следующем шаге выберите действие «Stop» в категории «Animations», чтобы остановить анимацию, и нажмите «Done».
Теперь нужно выставить нужный кадр анимации, чтобы отобразить красно-синюю, белую или чёрную картинку. Для этого щёлкните по ссылке «Add action» справа от события сравнения переменных.
В диалоге «Add action» также выберите объект «Level» и на следующем шаге выберите действие «Set frame» (установка кадра анимации). После этого в последнем диалоге «Parameters for Level: Set frame» задайте номер кадра в поле «Frame number». В нашем случае, нужно отобразить белый кружок с красно-синим свечением, это будет кадр 0.
Аналогично добавьте условия для двух оставшихся кадров 2 и 3. У вас должно получиться следующее:
Запустите макет и проверьте, как отображаются уровни. Как видите первый уровень белый (т.е. он непройденный, но открытый для прохождения), а остальные два уровня – чёрные. Подкраска уровней получилась, всё в порядке.
Теперь, чтобы пользователю был виден путь от уровня к уровню, нужно соединить уровни линиями. Линии тоже нарисуем сами. Добавьте объект «Sprite» с названием «LevelLine». Выставьте толщину кисти 18, жесткость – 0, цвет – белый и точками обозначьте линию. Т.е. линия получилась состоящая из светящихся точек. Чтобы результат был виден лучше можно сделать фон редактора тёмным. Для этого нажмите на кнопку «Toggle background brightness» (на картинке кнопка обведена красным). После этого обрежьте картинку с помощью кнопки «Crop transparent edges». После обрезки не забудьте центрировать исходную точку.
Запустите макет и посмотрите, как это должно выглядеть. Теперь игрок будет наглядно видеть, сколько всего уровней, какие из них пройдены и каков порядок прохождения.
Для красоты добавим немного эффектов. Выделите все уровни (чтобы задать им одинаковые свойства), на панели свойств щёлкните по ссылке «Behaviors», в окне «Level: Behaviors» добавьте два поведения «Sine». Свойства поведений выставьте, как показано на рисунке. Хотя вы можете поставить и свои значения, здесь дело вкуса. Здесь первое поведение будет плавно менять размер картинки, а второе поведение вращать её.
Теперь выделите обе линии и аналогичным образом добавьте сразу три поведения «Sine». Первое поведение будет менять угол, второе чуть двигать линию и третье менять длину линии. Все вместе эти эффекты будут создавать иллюзию движения. Какие значения для поведений я выставил, можно посмотреть в примере.
Теперь нужно обработать прикосновение к уровню. Т.е. когда пользователь касается определённого уровня его нужно открыть. Чтобы это сделать, откройте страницу событий и добавьте событие «On tap object» объекта «Touch». В окне «Pick an object» выберите объект «Level».
Далее для этого события нужно добавить затемнение и переход к уровню. Для этого скопируйте действия «Create object» и «Wait» со страницы событий «Event sheet 1» (там мы это уже делали) и вставьте в наше событие. Затем добавьте сюда действие «Go to layout (by name)» и в качестве имени задайте «Level» & Level.Num. Здесь мы к строке «Level» в конец добавляем цифру, взятую из переменной Num уровня, на который тапнул пользователь.
В результате у вас должно получиться следующее, см. картинку.
Затем перетащите все действия внутрь этого события. Вот, что должно у вас получиться, см. картинку.
Проверьте, как работает условие: запустите макет и удостоверьтесь, что при касании белого уровня, происходит переход к этому уровню, а при касании чёрного – ничего не происходит.
Кнопка возврата в меню из уровня игры
Теперь сделаем кнопку возврата в меню из уровня. Для начала её нужно нарисовать. Я добавил объект «Sprite» с именем «BackToMenu» на макет «Level1» и, воспользовавшись той же кистью, что и для рисования линий уровня в меню, нарисовал значок, обозначающий меню.
Затем этот значок я поставил на всех макетах с уровнями и сделал для всех значков одинаковые координаты. Получилось вот так:
Когда пользователь будет прикасаться к значку, мы будем возвращать его в меню. Чтобы это сделать на страницу событий «Event sheet 1» добавьте событие «On tap object» объекта «Touch», как мы это уже делали выше, только здесь будем отслеживать прикосновения к объекту «BackToMenu». Для обработки события добавьте действия для затемнения (скопируйте их из события «On «EndOfLevel»»), затем добавьте действие «Go to layout» и в диалоге выбора макета выберите макет «Menu». У вас должно получиться так же как на картинке.
Сохранение прохождения в игре
Добавленное действие перетащите на самый верх. У вас должно получиться как на картинке снизу.
В Construct 2 есть два варианта сохранения прохождения игры. Первый способ – это вызов действий «Save» (собственно, сохранение) и «Load» (последующая загрузка). Оба эти действия вы сможете найти у объекта «System». Работает это следующим образом: при вызове действия «Save», полностью сохраняются координаты и состояния объектов, текущий макет, значения переменных. Позже при вызове действия «Load» вы увидите на экране тот самый макет и все те объекты в тех же местах, в каких они находились при сохранении. Чтобы как то управлять таким процессом сохранения в Construct 2 есть поведение «No Save» (запрещает сохранение объекта) и события «On load complete» (вызывается после успешной загрузки сохранения), «On load failed» (вызывается, если загрузка не удалась, например, сохранения нет), «On save complete» (вызывается после успешного сохранения). В нашем случае такое сохранение не подходит, т.к. нам нужно сохранять только значение переменной «OpenLevels».
Второй способ – использование объекта «WebStorage» (веб-хранилище). С помощью этого объекта можно сохранять только строки. Модель сохранения очень проста – каждая строка сохраняется под именованным ключом. Для хранения можно выбирать либо локальное хранилище, либо сессионное хранилище. Локальное хранилище постоянно (помните, что в браузере пользователь может очистить кэш). Если пользователь вернулся в игру на следующий день, то локальное хранилище продолжает хранить сохранённые данные. Сессионное хранилище хранит данные только для текущей сессии браузера и, когда пользователь вернётся в игру на следующий день, хранилище будет пустым. Следует также помнить, что в браузере в режиме инкогнито локальное хранилище будет работать как сессионное.
Также при работе с объектом «WebStorage» нужно помнить, что браузеры ограничивают максимальный размер сохраняемых данных. В общем случае – это 5 МБ. Если вы превысили размер хранилища, вы получите сообщение «On quota exceeded» (квота превышена) от объекта «WebStorage».
В нашем случае для сохранения игры подходит локальное хранилище объекта «WebStorage». Добавим этот объект в проект. Щёлкните по любому макету правой кнопкой мышки и выберите пункт контекстного меню «Insert new object». Затем выберите в диалоге объект «WebStorage» и нажмите «Insert».
Теперь на странице событий «Event sheet 1» добавьте в событие «On collision with» действие «Set local value» объекта «WebStorage».
В диалоге «Parameters for WebStorage: Set local value» введите имя ключа «OpenLevels» (пусть имя ключа совпадает с именем переменной) и значение (в нашем случае –значение берётся из переменной).
После того как действие будет добавлено, перетащите его наверх, сразу под строку, в которой корректируется значение переменной «OpenLevels», см. картинку.
Добавленное событие обязательно перетащите наверх, чтобы оно находилось до цикла, в котором подкрашиваются уровни, см. картинку. Это важно, т.к. сначала должно считаться значение переменной «OpenLevels» и только потом, можно подкрашивать уровни сине-красным, белым или чёрным.
Теперь можно добавить действие для чтения из хранилища. Итак, внутрь нового события, добавьте действие «Set value» объекта «System».
В следующем диалоге выберите переменную и выражение устанавливающее значение. В нашем случае это WebStorage.LocalValue(«OpenLevels»). Чтобы ввести это выражение можно воспользоваться полупрозрачным окошком подсказок, на картинке оно сверху.
А вот, что у вас должно получиться:
Чтобы теперь очистить хранилище в браузере Chrome нужно перейти в настройки браузера, щёлкнуть по ссылке «Показать дополнительные настройки», нажать на кнопку «Очистить историю. », затем, в поднявшемся диалоге, установить галку «Файлы cookie и другие данные для сайтов и плагинов» и нажать кнопку «Очистить историю» (см. картинку). Также при очистке учитывайте период, за который вы очищаете сохранения (на картинке – это прошедший час).
Аналогично почистить хранилище можно и в других браузерах. В Construct 2 для чистки хранилища можно выполнить действие «Clear local storage» объекта «WebStorage».
Убираем подтормаживания при завершении уровня
Прохождение последнего уровня
Осталась ещё небольшая нерешённая проблема. После прохождения последнего уровня ничего не происходит. Сделаем так, чтобы происходил возврат в меню. Чтобы определить какой уровень является последним, нужно узнать сколько всего уровней у нас в игре. Конечно, можно добавить константу с количеством уровней, но так придётся всё время поправлять её значение после добавления новых уровней. Сделаем лучше подсчёт количества уровней при старте макета «Menu», а подсчитанное количество запишем в новую глобальную переменную «LevelCount». Для подсчёта можно воспользоваться уже имеющимся циклом. Вот, что у меня получилось:
Запустив макет «Menu» в режиме отладки вы можете увидеть, что количество уровней посчиталось правильно.
Теперь на странице событий «Event sheet 1» в событии «On collision with Blue» нужно добавить вложенное событие с проверкой номера текущего уровня и, если текущий уровень последний, то перейти в меню. Для сравнения двух значений будем использовать событие «Compare two values» (сравнить два значения). Сравнивать будем цифру из названия макета и значение переменной «LevelCount». Вот, что должно получиться.
И напоследок я добавил в пример ещё один уровень. Теперь, чтобы добавить уровень нужно не только скопировать макет уровня, но и отобразить уровень в меню.
Открыть игру на весь экран
Проект для этого этапа можете скачать здесь: