Corona SDK — для начинающих. Работа с несколькими сценами при помощи Storyboard API

в 8:04, , рубрики: corona sdk, mobile development, storyboard, Разработка под android, разработка под iOS, метки: ,

Corona SDK — это кросс-платформенный движок для создания игр под iOS и Android. Лично мне он нравится своей простотой освоения: пятерка в школе по паскалю — достаточный багаж знаний для покорения «короны». На хабре уже есть несколько статей на эту тему, но подробных уроков для начинающих как на этом, так и на других русскоязычных сайтах очень мало.

В этой статье я расскажу об одном из ключевых вопросов работы с Corona SDK — организация нескольких сцен в одном приложении.

Для этого существует специально разработанное средство — StoryBoard API, которое пришло на смену стороннему классу Director.

Рассмотрим небольшой пример, который объяснит как:

  • создавать сцены
  • переключаться между сценами с различными эффектами
  • передавать переменные между сценами

Наше приложение при запуске будет показывать меню, состоящее из трех кнопок, каждая из которых ведет нас на отдельную сцену. Соответственно, у нас будет 4 сцены, для каждой из них нам понадобится создать файл с одноименными названиями (menu.lua, scene1.lua, scene2.lua, scene3.lua) и основной файл main.lua:

Схема приложения

Начнем наполнять приложение по порядку. В основном файле проекта main.lua запишем следующие строки:

local storyboard = require "storyboard"
storyboard.prevScene = 0
storyboard.gotoScene( "menu" )

Первая строка подключает библиотеку storyboard к нашему приложению, во второй строке мы храним переменную prevScene, которую потом передадим в другие сцены, ну а третья строка перенаправляет на сцену menu.

Файл menu.lua, как и любую другую сцену наполняем по шаблону, который отлично расписан на оф. сайте Ansca. Дублировать его полностью здесь не вижу смысла. Ознакомиться с ним можно по этой ссылке. Остановлюсь лишь на самых важных моментах.

Во-первых, перед тем, как добавлять свой код в четыре стандартных события (createScene, enterScene, exitScene, destroyScene) следует объявить используемые нами переменные. В меню у нас будут задействованы переменные для фона, трех кнопок и текстовой надписи с мониторингом памяти.

local background, tap1, tap2, tap3, text

Далее создаем наш фон, кнопки и надпись внутри функции function scene:createScene( event ). Также, в этой части нашей программы размещаем функции, которые будут менять сцены по нажатию кнопки. Все это однотипные простейшие функции создания изображений и текста из стандартного набора Corona. Поэтому, для сокращения количества текста, приведу здесь лишь строчки, отвечающие за первую кнопку, остальное по аналогии. Ну а всем кому интересно, могут скачать полные исходники в конце топика.

function scene:createScene( event )
  local group = self.view

  local function GoToScene1 (event)
    storyboard.gotoScene( true, "scene1", "fromRight", 800  )
  end 

   tap1 = ui.newButton{
      default = "img/tap1.png",
      over = "img/tap1_over.png",
      onRelease = GoToScene1,
  }
  tap1.x = display.contentCenterX; tap1.y = 150;
  group:insert(tap1);
	
end

Отмечу лишь, что параметр «fromRight» у функции storyboard.gotoScene() задает эффект появления новой сцены справа. Соответственно, можно задать эффект появления слева, сверху или снизу(fromLeft,fromTop или fromBottom), плюс классическое затемнение (fade). Параметр 800 — это время выполнения эффекта в милисекундах. Это не все эффекты, полный список можно почитать в официальной документации разработчиков.

Теперь надо поставить небольшое условие, которое будет очищать память устройства от предыдущей сцены, в зависимости от значения переменной prevScene. Очень важно не забывать очищать память функцией storyboard.removeScene(), иначе ваше приложение будет потреблять много ресурсов и в конце концов может просто зависнуть.

Делаем мы это при загрузке новой сцены внутри функции function scene:enterScene ( event ), там же оставим стандартную функцию из примеров разработчиков Corona по мониторингу памяти.

function scene:enterScene( event )
	local group = self.view
     if storyboard.prevScene > 0 then storyboard.removeScene( "scene"..storyboard.prevScene ) end	
  
-- show memory on display
    local showMem = function()
    text.text = text.text .. collectgarbage("count")/1000 .. "MB"
    text.x = display.contentWidth * 0.5
    end
    local memTimer = timer.performWithDelay( 1000, showMem, 1 )
	
end

Сохраняем файл, запускаем симулятор и смотрим нашу первую сцену. Т.к. это menu.lua, то я решил сделать меню, но не программное, а для простой столовой:

Меню

Ну и наконец, создаем три сцены-клона нашего меню, но:
1. Без кнопок.
2. Каждая сцена со своим предметом на столе (тарелка борща, тарелка макарон или стакан компота)
3. Обновляем нашу общую у всех сцен переменную и немного меняем строчку с удалением из памяти предыдущей сцены, т.е. функция storyboard.removeScene() удаляет конкретно menu.lua, т.к. это единственно возможная предыдущая сцена:

   storyboard.prevScene = 1
   storyboard.removeScene( "menu" );

4. Добавляем возможность возврата в меню по нажатию на картинку-фон. Для этого добавим в раздел createScene функцию возврата в меню:

  local function onSceneTouch( self, event )
  if event.phase == "began" then
 
    storyboard.gotoScene( "menu", "fade", 400  )
    
    return true
  end

В разделе enterScene привяжем к нашему фону eventListener, который будет следить за прикосновениями, и в положительном случае отправит программу выполнять нашу функцию onSceneTouch():

background:addEventListener( "touch", background )

Ну и, разумеется, не забудем убрать eventListener, при выходе из сцены в разделе exitScene()

background:removeEventListener( "touch", background )

Заполним по этим правилам все три сцены:

Сцены
Тот же результат можно получить используя только две сцены: меню и еще одна, которая в зависимости от активированной кнопки будет показывать разные продукты(простое условие и одна глобальная переменная). В качестве закрепления изученного материала, попробуйте реализовать данный механизм.
Если мы все сделали верно, то память, занятая приложением, не должна увеличиваться с каждым переходом на другую сцену. Следите за этим в своих приложениях.

Ну вот и все. Разные сцены мы создали, с эффектами по ним прошлись, ну и переменную prevScene передали. На этом знакомство с storyBoard API можно считать завершенным.
Исходники урока можно скачать здесь.
Исходники примера работы storyboard API от разработчиков Corona SDK смотреть тут.

Информация по теме (на английском):
Introducing the Storyboard API
Storyboard Scene Events Explained
Common Storyboard API Questions

Автор: ok34

* - обязательные к заполнению поля