Шукати в цьому блозі

Практичне керівництво розробки ігор в Gideros 2.1

Частина 2/4.1

Зміст

*****************************************
  • Менеджер сцен Gideros
  • Створення глобального файлу конфігурації
  • Створення початкової сцени
  • Створення про сцени about
  • Створення сцени options
  • Створення класу settings

*****************************************

Менеджер сцен Gideros


Тепер, коли ми знаємо, як Gideros OOП дійсно працює, давайте застосуємо його для створення нашої першої сцени

Основна ідея керування сценами полягає в тому, що кожна сцена насправді є об'єктом Sprite (або, точніше, об'єктом, успадкованим від Sprite), який містить всі інші об'єкти для відтворення. Існує менеджер сценаріїв, який в основному керує, яку сцену потрібно додати для відтворення ієрархії та яку видаляти, переходячи з однієї сцени в іншу.
Таким чином, ми можемо контролювати, що відображається на якій сцені.

Окрім того, менеджер сценарію видаляє попередню сцену, щоб звільнити пам'ять, тому в більшості випадків ми не повинні думати про керування пам'яттю між сценами.

Теоретично ми можемо створити власний менеджер сценаріїв, але вже є такий, який є неймовірно популярним, з багатьма переходами та доповненнями ефектів, тому я не бачу причин витрачати час на писати його з нуля

Ви можете завантажити останню версію сценарію Gideros від

Щоб використовувати його, просто скопіюйте scenemanager.lua до папки свого проекту та додайте його в Gideros Studio у папку classes.

Тепер створіть нову папку із назвою scenes всередині панелі «Project», щоб зберегти наші сцени там. І створити новий файл Lua з ім'ям StartScene.lua, який буде нашою першою сценою.

Відкрийте StartScene.lua і давайте створимо клас для нашої першої сцени з таким ім'ям StartScene. Пам'ятайте, що його потрібно успадкувати від Sprite для додати до ієрархії візуалізації.

Ви також можете перемістити код кнопки з main.lua до StartScene методу  init і замість того, щоб додати його до stage, додайте його до внутрішнього екземпляру сцени StartScene за допомогою self:addChild(button). Таким чином, ця кнопка буде відображатися та видалятися разом із сценою.
StartScene = Core.class(Sprite)
function StartScene:init()
 local texture = Texture.new("images/ball.png", true)
 local bmp = Bitmap.new(texture)
 local button = Button.new(bmp)
 button:addEventListener("click", function()
 print("ти натиснув мене")
 end)
 self:addChild(button)
end
Тепер, коли ми перенесли код кнопки з main.lua, він повинен бути порожнім. Що потрібно зробити тут, це створити екземпляр SceneManager, створивши таблицю з усіма сценами та ключами до сцен, і з допомогою sceneManager  відобразити StartScene за допомогою методу changeScene.
--визначити сцени
sceneManager = SceneManager.new({
 --список всіх ваших сцен тут
 --start сцена
 ["start"] = StartScene,
})
--додати менеджера до stage
stage:addChild(sceneManager)
--запустити сцену  start 
sceneManager:changeScene("start", 1, SceneManager.fade)
Зауважте, що коментарі у коді починаються з двох тире (--).

  • Перший аргумент,переданий методу changeScene, ключ сцени, який використовується для передачі сцени до конструктора SceneManager
  • Другий аргумент - час переходу в секундах
  • І третій - це тип спецефекту появлення сцени, у нашому випадку SceneManager.fade
Існує також необов'язковий четвертий аргумент, який є функцією easing для переходу. Для цього потрібна програма easing.lua, яку ви можете знайти в тій папкі що і  SceneManager. Все, що вам потрібно зробити, це додати його до проекту, а потім ви можете передавати такі функції, як sceneManager:changeScene("start", 1, SceneManager.fade, easing.outBack).

Тепер, якщо ми запускаємо наш проект, він автоматично повинен показувати початкову сцену з нашим зображенням-кнопкою в ній.

Створення глобального файлу конфігурації

Зазвичай, щоб ваша гра була більш послідовною, ви будете повторно використовувати ті самі переходи зі сцен, ті ж самі функції та повторне використання інших однакових значень. Тепер ми безпосередньо надамо кожному методу changeScene такий перехід, як SceneManager.fade. Як зробити , якщо ми хочемо змінити тип переходу за умовчанням для всіх наших сцен?

Ми повинні редагувати всі виклики changeScene у всіх файлах нашого проекту.

Але, набагато розумніше створити який-небудь глобальний файл конфігурації, який буде тримати загальні дані, які ми будемо використовувати повторно, щоб ми також могли легко їх змінити.

Створіть файл config.lua всередині Gideros Studio і збережіть там деякі загальні значення в простій  таблиці conf.
conf = {
 transition = SceneManager.fade,
 transitionTime = 1,
 easing = easing.outBack,
 width = application:getContentWidth(),
 height = application:getContentHeight(),
 dx = application:getLogicalTranslateX() /application:getLogicalScaleX(),
 dy = application:getLogicalTranslateY() /application:getLogicalScaleY(),
}
Оскільки ми не визначили local у  змінній conf, ми зробили її глобальною, і тепер вона може легко отримати доступ до цих значень в інших файлах, таких як conf.width для отримання ширини програми або викликати метод changeScene з нашими значеннями за замовчуванням.

У main.lua змініть:
sceneManager:changeScene("start", 1, SceneManager.fade)
На:
sceneManager:changeScene("start", conf.transitionTime, conf.transition, conf.easing)

Створення початкової сцени

Ми вже маємо обгортку для стартової сцені. Тепер видаліть  вивід тексту тестової кнопки, який ми маємо в ній, і давайте додамо деякий реальний вміст. Весь код, який ми будемо додавати, слід додати до методу init в сцені, якщо не вказано інше.

Як ви пам'ятаєте порядок візуалізації, речі, які ми додаємо спочатку, з'являться під тим, що ми додаємо пізніше по осі z. Таким чином, як перший елемент давайте додамо ще одну фонову графіку. Тому скопіюйте будь-яке фонове зображення, яке ви хочете використовувати (пам'ятаєте, ми обговорювали, щоб використовувати роздільну здатність 852 x 600 пікселів) у папку проекту Gideros та додати її до папки зображень у Gideros Studio.

Потім створіть об'єкт Bitmap з текстурою цього зображення та розмістіть його в центрі екрана за допомогою точок прив'язки та розмірів дисплею, які ми вже визначили в нашому файлі config.lua, і, зрештою, додавайте його до сцени як завжди.
local bg = Bitmap.new(Texture.new("images/bg.jpg", true))
bg:setAnchorPoint(0.5, 0.5)
bg:setPosition(conf.width/2, conf.height/2)
self:addChild(bg)
Наступне, що повинно бути на фоні, - це, логотип. Скопіюйте свій logo.png у свою папку проекту Gideros та додайте її до папки images у Gideros Studio.

Тепер, створіть об'єкт Bitmap з цього логотипа та додайте його на сцену. Ви можете розмістити його за бажанням, але в цьому випадку я розміщую його трохи вище центру, тому ми маємо більше місця для інших кнопок.

Далі ми створимо кнопку Start Game. Ми не будемо використовувати зображення для такого роду кнопок, а, використаєм, текстове поле. Як ви пам'ятаєте, ми створили наш клас клавіш, щоб він міг прийняти всі успадковані об'єкти Sprite, такі як Bitmap та TextField. Але на цей раз, використовуючи TextField, ми використаємо шрифт TTF, а не вбудований шрифт.
І для цього вам потрібно додати шрифт TrueType у свій проект.

Створіть папку fonts і скопіюйте туди шрифт. Я буду використовувати чудовий шрифт , який називається Deftone Stylus, який є безкоштовним для комерційного використання. І ви можете завантажити його з http://www.1001fonts.com/deftone-stylus-font.html.

Важливо:Якщо вам потрібно виводити текст кирилицею,  то ваш шрифт повинен підтримувати кирилицю, інакше ви отримаєте замість тексту крякозябри

Тепер для використання шрифтів TTF у Gideros вам спочатку потрібно створити об'єкт TTFont, а потім перенести його в TextField як перший параметр.

Спочатку створивши об'єкт TTFont, ми вкажемо шлях до шрифту, а потім розмір, яким ми будемо використовувати наш шрифт. Далі ми можемо передавати символи, які ми хочемо кешувати у нашому шрифті, для швидшої візуалізації, але це потрібно лише, якщо ми зробимо багато змін у тексті. Оскільки цей TextField буде містити лише один текст без змін,
нам не потрібно зберігати кеш будь-яких символів. І, як останній параметр, ми вкажемо  true, щоб вказати, що ми хочемо включити фільтрацію до цього шрифту, тому він буде виглядати гладко, коли його буде масштабовано.

Щоб зробити дизайн нашої гри більш послідовним, ми будемо повторно використовувати той же шрифт в інших сценах; таким чином, додамо об'єкт TTFont, який ми створили в наш config.lua.

Ми додамо fontLarge до файлу config.lua з нашим вибраним шрифтом і вкажемо 70 px для розміру шрифту
conf = {
 transition = SceneManager.fade,
 transitionTime = 1,
 easing = easing.outBack,
 width = application:getContentWidth(),
 height = application:getContentHeight(),
 dx = application:getLogicalTranslateX() /
application:getLogicalScaleX(),
 dy = application:getLogicalTranslateY() /
application:getLogicalScaleY(),
 fontLarge = TTFont.new("fonts/deftone stylus.ttf", 70, true),
}
Тепер створіть кнопку у файлі StartScene.lua за допомогою нашого раніше створеного класу Button з TextField. Спочатку ми створюємо об'єкт TextField з нашим визначеним об'єктом TTFont. Потім ми встановили його колір жовтим кольором і створили екземпляр кнопки. Після цього ми просто розмістимо нашу кнопку у центрі-дні екрана та додамо до сцени.
local startText = TextField.new(conf.fontLarge, "Start Game")
startText:setTextColor(0xffff00)
local startButton = Button.new(startText)
startButton:setPosition(conf.width/2, conf.height - 80)
self:addChild(startButton)
Gideros використовує визначення кольорів RGB, які потрібно передавати у форматі HEX, починаючи з кольору 0x000000 (чорний) до 0xFFFFFF (білого) кольору. Кожні два букви - це кількість червоних, зелених або синіх каналів. Наприклад, для використання червоного кольору ми використовуємо максимум червоного каналу і нічого не використовуємо з інших каналів (0xFF0000).
І якщо ми змішамо канали червоного та зеленого кольорів, ми отримаємо жовтий колір (0xFFFF00).
І оскільки це кнопка, вона повинна зробити щось, коли натиснув. Давайте додамо слухача події  listener до цієї кнопки,   це приведе нас до іншої сцени. Ми ще не визначили таку сцену, тому натискання на неї призведе до помилки; але давайте додамо його зараз, щоб ми не забули це пізніше

Щоб додати слухача подій, як ми робили раніше, ми просто викликаємо метод addEventListener і передаємо функцію, яку ми хочемо виконати, коли відбувається подія - в цьому випадку відкрити сцену level. .
startButton:addEventListener("click", function()
 sceneManager:changeScene("level", conf.transitionTime, conf.transition, conf.easing)
end)
Тепер, подібним чином, давайте додамо кнопку "Options", яка відкриватиме сцену  параметрів. Ми додамо ще один рядок до нашого файлу config.lua, тепер створюємо новий об'єкт TTFont з тим самим шрифтом, але з меншим розміром - 50 пікселів. І назвемо це fontMedium
fontMedium = TTFont.new("fonts/deftone stylus.ttf", 50, true),
Після додавання нового шрифту з новим розміром, створіть кнопку "Options", як це було з кнопкою " Start Game".

Спочатку ми створюємо об'єкт TextField, вказуємо  шрифт з config.lua і текст. Ми також змінюємо колір на жовтий колір.

Потім ми створюємо кнопку з цим об'єктом TextField, встановлюємо його положення в лівому нижньому куті екрана та додаємо слухача події, щоб змінити сцену на параметри.
local optionsText = TextField.new(conf.fontMedium, "Options")
optionsText:setTextColor(0xffff00)
local optionsButton = Button.new(optionsText)
optionsButton:setPosition(50, conf.height - 50)
self:addChild(optionsButton)
optionsButton:addEventListener("click", function()
 sceneManager:changeScene("options", conf.transitionTime, conf.transition, conf.easing)
end)
І знову, використовуючи повністю таку ж процедуру, створіть кнопку "About" у правому нижньому куті.


  • Створіть TextField
  •  Встановіть його колір
  •  Створіть кнопку з TextField
  •  Встановіть свою позицію
  • Додайте його до сцени
  •  Додайте до нього слухача події, щоб перейти до іншої сцени


Ось код:
local aboutText = TextField.new(conf.fontMedium, "About")
aboutText:setTextColor(0xffff00)
local aboutButton = Button.new(aboutText)
aboutButton:setPosition(conf.width - aboutButton:getWidth() - 50,conf.height - 50)
self:addChild(aboutButton)
aboutButton:addEventListener("click", function()
 sceneManager:changeScene("about", conf.transitionTime, conf.transition, conf.easing)
end)
Останнє, що потрібно зробити, полягає в тому, щоб додати функцію  вийти з програми, коли ми натискаємо кнопку "back" Android на головному екрані. Для цього нам потрібно додати слухача події до нашої сцени та прослухати подію KEY_DOWN, яка створиться при натисканні  клавіші  back.

Усередині обробника подій потрібно буде перевірити, чи натиснута кнопка є кнопкою back, використовуючи константу KeyCode.BACK. Якщо це так, ми перевіряємо, чи є  телефон пристроєм Android, а потім вийти із програми, application:exit().
Зауважте, що директива: exit () працює лише на пристроях Android, і забороняється використовувати її в iOS за принципами Apple.
self:addEventListener(Event.KEY_DOWN, function(event)
 if event.keyCode == KeyCode.BACK then
 if application:getDeviceInfo() == "Android" then
 application:exit()
 end
 end
end)
Ми маємо типовий стартовий екран із фоновою графікою, логотипом та трьома кнопками. Тепер давайте додамо інші сцени, на які призведуть натискання цих кнопок
Якщо з'являється повідомлення про те, що SceneManager не визначено у вашій конфігурації. lua, це означає, що файл config.lua виконується перед файлом scenemanager.lua; отже, програма ще не бачить її
Щоб вирішити цю проблему (і подібні залежності коду), клацніть правою кнопкою миші на файлі config.lua і виберіть «Code Dependencies». У відкритому вікні перевірте файли scenemanager.lua та easing.lua, які будуть повідомляти Gideros Studio, що ці файли повинні завантажуватися до config.lua.

Створення про сцени about

Наступна сцена, яку ми створимо, - це about, де ми просто виведемо деяку інформацію про автора чи додаток або будь-яку іншу інформацію, яку ви хочете вивести, і мати можливість повернутися до початкової сцени.

Отже, перше, що потрібно зробити, це створити інший файл Lua для нашої сцени всередині папки scenes . Давайте назвемо це AboutScene.lua.

Тепер давайте відкриємо AboutScene.lua і визначимо наш об'єкт сцени всередині нього, дуже подібний, як це було з StartScene.lua. Ми визначаємо клас AboutScene, який успадкує всі властивості Sprite та визначить метод init для класу AboutScene, де зараз ми будемо просто виводити текст в консоль:

AboutScene = Core.class(Sprite)
function AboutScene:init()
 print("всередині сцени about")
end
Після цього давайте перейдемо до main.lua і додаємо AboutScene в менеджер сцен .

--визначити сцени
sceneManager = SceneManager.new({
 --сцена start 
 ["start"] = StartScene,
 --сцена about 
 ["about"] = AboutScene,
})
Тепер, якщо ми запустимо наш проект у Gideros і натиснемо кнопку about, ви побачите наше повідомлення "всередині сцени about", надруковане в консоль Output. Це означає, що ми успішно перейшли на нову сцену. Тепер давайте додамо деякий вміст.

Спочатку ми додамо фон до методу AboutScene:init(), як це було в StartScene.lua. В основному, ви можете скопіювати та вставити той самий код, змінивши наступні параметри:


  • Створіть Bitmap з текстури зображення
  • Встановити точки прив'язки до 0,5
  • Встановіть положення в центрі
  • Додайте його до сцени

Ось код:
local bg = Bitmap.new(Texture.new("images/bg.jpg", true))
bg:setAnchorPoint(0.5, 0.5)
bg:setPosition(conf.width/2, conf.height/2)
self:addChild(bg)
Подібно до того, що ми робили раніше, тепер додамо кнопку "back" у нижній частині екрана наступним чином:


  • Створіть TextField із шрифтом medium та текстом
  • Встановіть його колір
  • Створіть кнопку за допомогою об'єкта TextField
  • Встановіть кнопку на позицію
  • Додайте її до сцени
  • І додайте подію, що запускає  сцену start

local backText = TextField.new(conf.fontMedium, "Back")
backText:setTextColor(0xffff00)
local backButton = Button.new(backText)
backButton:setPosition((conf.width - backButton:getWidth())/2,conf.height - 50)
self:addChild(backButton)
backButton:addEventListener("click", function()
sceneManager:changeScene("start", conf.transitionTime, conf.transition, conf.easing)
end)
Запустіть проект знову; ви побачите, що, коли ми натискаючи кнопку "about", ми перейдемо до about This Game сценки з кнопкою "Back". Натискаючи кнопку Back, ми знову можемо повернутися до start сцени . Отже, ми зробили все правильно.

На платформі Android зазвичай є вбудована клавіша "Back", яку ми можемо використати для повернення до попередньої сцени, але оскільки пристрої iOS не мають таких кнопок, нам також потрібно накласти візуальну кнопку на екрані.

Отже, оскільки ми обробляли візуальну кнопку на екрані, давайте зробимо те ж саме для вбудованої клавіші Android.

self:addEventListener(Event.KEY_DOWN, function(event)
 if event.keyCode == KeyCode.BACK then
 sceneManager:changeScene("start", conf.transitionTime, conf.transition, conf.easing)
 end
end)
І, як останнє, давайте просто додамо деякий текст до about сцени , описуючи нашу гру. По-перше, створіть маленький шрифт, визначивши його всередині config.lua, як і раніше, тепер використовуємо розмір шрифту 30 пікселів.
fontSmall = TTFont.new("fonts/deftone stylus.ttf", 30, true),
Якщо ми хочемо написати багато тексту, нам доведеться його зробити в декілька рядків. На жаль, клас TextField не підтримує нові рядки, але існує ще один зовнішній клас, побудований на класі TextField, який називається TextWrap. Ви можете завантажити його з: https://github.com/ar2rsawseen/TextWrap

TextWrap підтримує обгортання тексту навколо передбаченої ширини, а також різними вирівнюваннями тексту, такими як вліво, вправо, в центрі та по ширині

Щоб скористатись TextWrap, просто скопіюйте його в папку проекту Gideros та додайте його до папки classes, в проекті Gideros Studio. Потім ми створюємо екземпляр TextWrap, виконавши наступні кроки:


  • вказати текст як перший параметр
  • вказати ширину, в яку потрібно вмістити текст
  • вказати параметр вирівнювання тексту, 
  • вказати між рядкамиу пікселях
  • вказати  шрифту, який ми визначили в config.lua

Далі ми просто вкажемо колір і положення, і додамо його до сцени.

local aboutText = TextWrap.new("Це приклад програми, клон гри Машбол, спеціально розроблений для цієї книги і призначений для навчальних цілей", 600, "justify", 5,conf.fontSmall)
aboutText:setTextColor(0xffff00)
aboutText:setPosition(100, 200)
self:addChild(aboutText)
Ми також можемо додати простий заголовок до цієї сцени, використовуючи наші шрифти medium . Як правило, ми створюємо TextField, встановлюємо його колір і положення, а також додаємо його до сцени.

local aboutHeading = TextField.new(conf.fontMedium, "Про Гру")
aboutHeading:setTextColor(0xffff00)
aboutHeading:setPosition((conf.width - aboutHeading:getWidth())/2,100)
self:addChild(aboutHeading)
Ми зробили нашу  сцену about.  Йдемо далі.

Створення сцени options

Далі ми створимо сцену options, де ми попросимо гравців написати ім'я користувача. Спершу створіть OptionsScene.lua всередині папки scenes і створіть у ній клас OptionsScene, як це було з двома попередніми сценами. Додамо фонову графіку, заголовок
і кнопка "back" (включаючи обробку клавіші "back" для Android) так само, як ми робили в файлі AboutScene.lua.

OptionsScene = Core.class(Sprite)
function OptionsScene:init()
 local bg = Bitmap.new(Texture.new("images/bg.jpg", true))
 bg:setAnchorPoint(0.5, 0.5)
 bg:setPosition(conf.width/2, conf.height/2)
 self:addChild(bg)

 local optionsHeading = TextField.new(conf.fontMedium, "Options")
 optionsHeading:setPosition((conf.width -optionsHeading:getWidth())/2, 100)
 optionsHeading:setTextColor(0xffff00)
 self:addChild(optionsHeading)

 local backText = TextField.new(conf.fontMedium, "Back")
 backText:setTextColor(0xffff00)
 local backButton = Button.new(backText)
 backButton:setPosition((conf.width - backButton:getWidth())/2, conf.height - 50)
 self:addChild(backButton)
 backButton:addEventListener("click", function()
 sceneManager:changeScene("start", conf.transitionTime, conf.transition, conf.easing)
 end)

 self:addEventListener(Event.KEY_DOWN, function(event)
 if event.keyCode == KeyCode.BACK then
 sceneManager:changeScene("start", conf.transitionTime, conf.transition, conf.easing)
 end
 end)
end
І не забудьте додати сцену до sceneManager у файлі main.lua.

--сцена options 
["options"] = OptionsScene,
Після цього ви можете запустити проект і побачити, що ми також можемо перейти до сцени options і повернутися до сцени start.

Тепер, коли ми хочемо зберегти ім'я нашого гравця, нам потрібно зберігати його  файл (для збереження його між сеансами гри), для цього ми створимо клас Settings.

Створення класу settings

Перш ніж зберігати інформацію в Gideros, дозвольте мені поділитися кількома словами про віртуальну файлову систему Gideros. У Gideros існує три різні види віртуальних каталогів файлової системи.

По-перше, є каталог Resource, в який   ми додавали зображення та файли Lua. Доступ до нього отримати, просто надавши шлях до файлу, як ми робили раніше, наприклад, Texture.new ("images / myimage .png ")

Хоча ви можете додавати файли з Gideros Studio, коли програма виконється , цей каталог буде доступний лише для читання. Це означає, що ви не можете створювати будь-які файли та писати що-небудь з програмно з гри.

Наступний , тип віртуального каталогу - це каталог Documents, до якого неможливо отримати доступ з програми Gideros Studio, і в основному призначений для використання всередині програми, щоб зберігати всю необхідну постійну інформацію. Цей каталог можна відкрити  програмно за допомогою | D | префіксу, тому, якщо б ми зберегли зображення в каталозі документів, нам доведеться отримати доступ до нього,
наприклад, Texture.new ("| D | image.png").

І останній тип каталогу - це каталог Temp для зберігання тимчасових файлів. Ви можете отримати доступ до нього за допомогою префіксу | T |, наприклад, Texture.new ("| T | image.png").

Ми будемо використовувати модуль Lua, який  називається dataSaver. Ви можете завантажити його з  https://github.com/ar2rsawseen/dataSaver і додати його до каталогу classes Gideros Studio.

Ви можете дізнатись більше про використання DataSaver з http://appcodingeasy.com/Gideros-Mobile/Save-and-load-data-module-for-Gideros-Mobile

Отже, ми трохи знаємо, як і де ми можемо постійно зберігати інформацію; нарешті, створімо settings.. Спочатку створіть Settings.lua всередині папки classes і відкрийте його для редагування.


Тепер створіть новий клас Settings і визначте його метод init. У цьому випадку нам не потрібно класу Settings успадковуватись від чого-небудь, оскільки нам не потрібно відправляти події або додавати його до ієрархії візуалізації, він буде тільки читати та зберігати дані.

Settings = Core.class()
function Settings:init()
end
Усередині методу init ми визначимо таблицю налаштувань з нашими початковими значеннями; поки ми хочемо визначити тільки ім'я користувача.

--наші початкові налаштування
local settings = {
 username = "Player",
}
Після цього нам потрібна змінна для позначення, якщо наші налаштування були змінені; давайте назвати це self. isChanged і зробити екземпляр налаштуань.

--щоб перевірити, чи змінилися налаштування
self.isChanged = false
 Чому ми визначили це як self.isChanged, а не просто isChanged, як і раніше? Визначивши його як self.isChanged, ми робимо це властивістю екземпляра.

Як ви знаєте, self - це посилання на себе,  , і кожен примірник матиме іншу інформацію про себе. Тому, додавши власність до self , ми робимо це значенням, яке може отримати доступ до поточного екземпляра.

Крім того, просто визначаючи його як локальну змінну, яка буде доступна лише в тому методі, який було визначено, властивість екземпляра буде доступним у всіх методах.

Далі, давайте спробуємо зчитати, чи було щось збережене раніше, за допомогою DataSaver і зчитати наш файл settings у каталозі «Documents». І тоді ми перевіряємо self.sets; якщо раніше нічого не було збережено, ми встановлюємо наші поточні налаштування як порожню таблицю.

--завантаження збережених налаштувань
self.sets = dataSaver.load("|D|settings")

if(not self.sets) then
 self.sets = {}
end
Наступне, що ми хочемо зробити, це зчитати наші початкові налаштування; ми зробимо це в циклі for шляхом доступу до ключа та значення кожного елемента у початковій таблиці налаштувань і перевірити, чи вона вже існує в наших збережених налаштуваннях, і якщо ні, ми не будемо зчитувати дані.

for key, val in pairs(settings) do
 if self.sets[key] == nil then
 self.sets[key] = val
self.isChanged = true
 end
end
Цим способом ми гарантуємо, що пізніше ми зможемо додати додаткові значення до початкових параметрів і не перевизначати існуючі налаштування.

Тепер ми завершили метод init. Давайте створимо метод, який зберігатиме наші налаштування у каталозі Documents

Спочатку ми перевіряємо, чи змінились параметри, перевіривши властивість self.isChanged, і якщо так, ми змінимо значення на false і зберігаємо нашу таблицю self.sets у файлі налаштувань в каталозі Documents

Зауважте, що, хоча ми визначили метод self.isChanged у методі init, ми все ще можемо отримати доступ до нього в іншому методі, оскільки, як я вже згадував раніше, це властивість екземпляра.

--зберегти налаштування
function Settings:save()
 --перевірте, чи було щось змінено
 if(self.isChanged)then
 self.isChanged = false
 dataSaver.save("|D|settings", self.sets)
 end
end
Далі давайте створимо метод, щоб зчитати значення з settings.. У цьому методі ми просто отримаємо ключ, такий як username, і запишемо значення в таблицю self.sets, в якому зберігаються наші поточні налаштування.

--отримати значення для конкретного налаштування
function Settings:get(key)
 return self.sets[key]
end
І останній метод буде встановлювати значення наданого ключа і, можливо, зберігати settings .

--set new value of specific setting
function Settings:set(key, value, autosave)
 if(self.sets[key] == nil or self.sets[key] ~= value) then
 self.sets[key] = value
self.isChanged = true
 end
 if autosave then
 self:save()
 end
end

Ми не повинні зберігати інформацію про кожну нову зміну, оскільки в деяких системах запис до файлу може бути дорогою операцією, що призведе до втрати продуктивності. Ось чому ми запропонували автоматичне збереження як опцію, і додатково ми можемо викликати метод збереження вручну, коли ми відчуваємо, що ми повинні його зберегти

Тепер клас Settings завершено, створіть глобальний екземпляр всередині файла main.lua.

sets = Settings.new()
Повернімося до сцени options та додамо метод, у який гравцеві буде питати ім'я користувача.
Спочатку давайте покажемо поточне ім'я користувача. Ми створимо TextField з текстом Ваше ім'я користувача: і витягуємо все, що зберігається в наших налаштуваннях під ім'ям ключа, викликаючи sets:get("username"). .

local usernameText = TextField.new(conf.fontSmall, "Ваше ім'я:"..sets:get("username"))
usernameText:setPosition(100, 200)
usernameText:setTextColor(0xffff00)
self:addChild(usernameText)
Тепер ми знаємо, як отримати значення з налаштувань. Додамо спосіб зміни його. Спочатку потрібно додати кнопку з назвою Change it, як ми вже робили раніше. Створіть TextField і змініть колір на зелений, просто виділіть текст. Потім створіть кнопку і розмістіть її на тому ж рядку, що й попередній текст. Після цього просто додайте його на сцену.

local changeText = TextField.new(conf.fontSmall, "Change it")
changeText:setTextColor(0x00ff00)
local changeButton = Button.new(changeText)
changeButton:setPosition(conf.width - changeButton:getWidth() - 100,200)
self:addChild(changeButton)


Тепер нам потрібно  прийняти дані від гравця. Ми можемо це зробити, додавши  TextInputDialog.

При створенні екземпляру TextInputDialog ми надаємо заголовок діалогового вікна як перший параметр, після чого ми вказуємо текст повідомлення. Третій параметр - дефотний текст у полі вводу . Останні два параметри, ми надаємо імена кнопок Скасувати та Зберегти.

Після цього ми додаємо слухача події до екземпляру TextInputDialog, де ми слухаємо подію, що покаже нам, що користувач завершив введення і натиснув будь-яку кнопку або відхилив діалогове вікно

Потім ми перевіряємо, чи є event.buttonIndex є nil.. Якщо це nil., це означає, що користувач або скасував або відхилив діалогове вікно. Якщо це не так, це означає, що користувач ввів текст та натиснув кнопку "Зберегти".

Потім ми беремо значення вхідного значення з event.text і зберігаємо його в наших налаштуваннях з username ключем   та надаємо true як третій параметр для автоматичного збереження.

Крім того, ми також змінюємо текст раніше заданого поля usernameText, щоб відобразити наше нове ім'я користувача після зміни, використовуючи метод setText класу TextField.

Після налаштування  прослуховування події, залишається лише показати діалогове вікно вводу за допомогою методу show.

changeButton:addEventListener("click", function()
 local textInputDialog = TextInputDialog.new("Змінити своє ім'я","Введіть своє нове ім'я", sets:get("username"), "Скасувати", "Зберегти")
 textInputDialog:addEventListener(Event.COMPLETE, function(event)
 if event.buttonIndex ~= nil then
 sets:set("username", event.text, true)
 usernameText:setText("Ваше ім'я користувача:"..sets:get("username"))
 end
 end)
 textInputDialog:show()
end)
  Ви можете запустити проект і перевірити його самостійно. Після натискання кнопки Change it, ви повинні побачити діалогове вікно вводу. Потім, коли ви зміните значення та натисните кнопку Зберегти, ім'я також зміниться на екрані. Тепер, навіть якщо ви вийдете з додатка та запустите  програму знову, вона все одно повинна зберегти ваші данні.


Підсумок

Ми успішно створили перші робочі сцени нашої гри. У цьому розділі ми дізналися, як створити класи Gideros, створивши клас Button та Settings. Потім ми дізналися, як керувати різними сценами, використовуючи GIDEROS OOП та scene manager. Ми також навчилися використовувати події та зберігати інформацію в файл.

далі

Немає коментарів:

Дописати коментар