Статьи

Портирование игр ActionScript для iOS с помощью Corona SDK: Часть 1

В этом руководстве будет рассказано о портировании Flash / Flex-игры на Corona SDK. В частности, мы будем портировать с ActionScript на Lua с конечной целью играть в игры, которые раньше были только для Flash, на iPhone. В дополнение к демонстрации языковых и API-различий, эта серия учебников также будет учитывать аппаратные ограничения, такие как размер экрана и отсутствие физических кнопок на iPhone.

Прежде чем мы перейдем к собственному кодированию, я хотел бы дать краткий обзор программного обеспечения, которое мы будем
использовать. Corona SDK — это продукт Ansca Mobile для создания игр для устройств iPhone, iPod Touch, iPad и Android. На момент написания этой статьи здесь была доступна бесплатная неограниченная пробная версия комплекта. Он включает в себя все функции платной версии, за исключением публикации в соответствующих магазинах приложений на устройствах iPhone и Android. Из этого туториала вы узнаете мощь и эффективность Corona.

В этом уроке мы будем портировать игру на основе флекселя от Андреаса Зечера. Эта игра была создана с помощью руководства Андреаса по библиотеке flixel с открытым исходным кодом и языку ActionScript. Оригинальный код доступен здесь (Андреас был любезен выпустить его как открытый исходный код). Если вы заинтересованы в создании флеш-игр, обязательно ознакомьтесь с оригинальным руководством. Там есть действительно полезная информация!

Набор для разработки программного обеспечения Ansca Mobile использует язык программирования lua и расширяет их API. Луа очень чистый язык. Удовлетворяя новичков, я обнаружил, что он очень мощный и очень мало кода. Луа это не
объектно-ориентированный язык, но его можно заставить следовать объектно-ориентированной модели с некоторой тонкой настройкой.

При этом давайте посмотрим на наше первое препятствие: Lua синтаксически отличается от ActionScript.

Переменные в Lua обрабатываются иначе, чем в ActionScript. В ActionScript переменные имеют статическую типизацию. Это означает, что они объявляют свой тип и сохраняют значения только этого типа, если они не преобразованы явно.

1
2
3
4
5
6
7
8
9
private var _ship: Ship;
private var _aliens: FlxGroup;
private var _bullets: FlxGroup;
private var _scoreText: FlxText;
private var _gameOverText: FlxText;
private var _spawnTimer: Number;
private var _spawnInterval: Number = 2.5;

В lua переменные типизируются динамически. Переменная Lua может содержать любой тип в любое время. Другой
Следует отметить, что переменные в Lua являются локальными или глобальными. Переменная локальная
(доступно только для файла .lua или его функции и т. д., если перед ним стоит «local»).
объявление переменной. В противном случае он считается «глобальным» по объему. Лучшая практика в Lua — всегда использовать
локальные переменные. Этот урок будет придерживаться этой практики.

01
02
03
04
05
06
07
08
09
10
local _ship — Variables do not declare their type.
            — a string.
local _aliens
local _bullets
local _scoreText
local _gameOverText
local _spawnTimer = nil — This variable has an assignment and a declaration on the same line.
local _spawnInterval = 2.5 — So does this one.

Как вы, наверное, уже заметили, комментарии обрабатываются в Lua иначе, чем в ActionScript.

01
02
03
04
05
06
07
08
09
10
// This is a comment in ActionScript
/*
This
is
a
multiline
comment
in
ActionScript
*/
01
02
03
04
05
06
07
08
09
10
— This is a comment in lua
—[[
This
is
a
multiline
comment
in
lua
—]]

Что важно знать о комментариях в Lua, так это то, что все, что после «-» — это комментарий, кроме
за «—[[«. Это учитывает аккуратный трюк. Если вы добавите дополнительную черту в начале мультилинии
комментарий «— [[«, он комментирует многострочную часть. Это происходит потому, что все после первого
две черты это комментарий. Теперь посмотрите в конце комментария «-]]». Это уже комментарий, потому что это тоже
после двух тире. Это фактически становится переключателем для выключения и включения битов кода!

1
2
3
4
5
6
7
8
—[[
This is a comment
—]]
 
—[[
This is code and will be executed as such.
In this case, an error would be thrown.
—]]

Циклы, скобки и операторы определяются словами в Lua:

1
2
3
4
5
6
// ActionScript
if(_spawnTimer < 0)
{
    spawnAlien();
    resetSpawnTimer();
}
1
2
3
4
5
— lua
if(_spawnTimer < 0) then
    spawnAlien()
    resetSpawnTimer()
end

Lua использует «if-then», «else», «elseif-then», «end», «and», «or» и т. Д. Также обратите внимание, что Lua не использует
точки с запятой в конце каждой строки. Без всех скобок и точек с запятой код Lua выглядит намного более
как английский язык, чем другие языки программирования.

Еще одна вещь, которую стоит отметить, прежде чем мы начнем — Lua не поддерживает ярлыки назначений.

1
2
// ActionScript
_spawnInterval *= 0.95;
1
2
3
— lua
_spawnInterval *= 0.95 — This will result in an error in lua
_spawnInterval = _spawnInterval*0.95 — This is proper Lua code

Теперь, когда мы понимаем некоторые фундаментальные различия между ActionScript и Lua, мы можем начать
процесс переноса игры между ними. Исходный код этого урока и прикрепленный к нему пост содержит
оригинальный исходный код и готовый код для сегодняшнего проекта.

Чтобы упростить портирование, мы начнем с преобразования всего синтаксиса в нашем источнике.
файлы, не касаясь нас с реальной логикой приложения. Таким образом, когда мы начинаем работать над логикой,
код уже будет правильно отформатирован. Давайте начнем процесс с файла Main.as, который выглядит
что-то вроде этого:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
package {
    import org.flixel.*;
    import de.pixelate.flixelprimer.*;
     
    [SWF(width=»640″, height=»480″, backgroundColor=»#ABCC7D»)]
    [Frame(factoryClass=»Preloader»)]
 
    public class Main extends FlxGame
    {
        public function Main():void
        {
            super(640, 480, PlayState, 1);
        }
    }
}

Здесь особо нечего делать. Нам не нужно объявление «package», поэтому мы можем удалить верхнюю и нижнюю строки кода.

01
02
03
04
05
06
07
08
09
10
11
12
13
import org.flixel.*;
import de.pixelate.flixelprimer.*;
     
[SWF(width=»640″, height=»480″, backgroundColor=»#ABCC7D»)]
[Frame(factoryClass=»Preloader»)]
 
public class Main extends FlxGame
{
    public function Main():void
    {
        super(640, 480, PlayState, 1);
    }
}

Поскольку в Lua нет классов, мы можем удалить строку «открытый класс Main extends FlxGame», и это
соответствующие скобки.

01
02
03
04
05
06
07
08
09
10
import org.flixel.*;
import de.pixelate.flixelprimer.*;
     
[SWF(width=»640″, height=»480″, backgroundColor=»#ABCC7D»)]
[Frame(factoryClass=»Preloader»)]
 
public function Main():void
{
    super(640, 480, PlayState, 1);
}

Теперь мы можем работать с функцией Main (). Прежде всего, обратите внимание на «публичное» объявление метода.
У Lua нет отдельных типов функций, поэтому мы можем удалить это. Помните, что в lua функции
не объявляйте их тип возвращаемого значения. В конце объявления функции есть ключевое слово «: void».
Это означает, что эта функция не будет возвращать значение, которое не обязательно в lua. Так что мы можем бросить
Это. Вы можете закомментировать это для справки позже. Наконец, удалите скобки вокруг
Основной(). В Луа мы используем слова. Добавьте «конец» в конце функции.

1
2
3
4
5
6
7
8
9
import org.flixel.*;
import de.pixelate.flixelprimer.*;
     
[SWF(width=»640″, height=»480″, backgroundColor=»#ABCC7D»)]
[Frame(factoryClass=»Preloader»)]
 
function Main() —:void
    super(640, 480, PlayState, 1);
end

Чтобы обернуть вещи, удалите все точки с запятой «;» и закомментируйте все строки кода. Эта
Кстати, мы можем начать портирование логики без получения ошибок.

1
2
3
4
5
6
7
8
9
—import org.flixel.*
—import de.pixelate.flixelprimer.*
     
—[SWF(width=»640″, height=»480″, backgroundColor=»#ABCC7D»)]
—[Frame(factoryClass=»Preloader»)]
 
—function Main() —:void
— super(640, 480, PlayState, 1)
—end

На этом этапе вы захотите создать папку проекта для хранения ваших файлов. Я назвал мой
«Alien_shooter». Это папка, которую вы передадите в Corona, когда будете готовы запустить
код. Внутри папки Corona ищет файл «main.lua». Корона чувствительна к регистру, так что вы
не должен начинаться с заглавной буквы, как в «Main.as». Сохраните приведенный выше код как main.lua.

Давайте перейдем к следующему файлу. Сегодня мы будем работать только с двумя исходными файлами. Секунда
Файл находится по адресу «de / pixelate / flixelprimer / PlayState.as» в прилагаемом исходном коде. Этот файл где
весь игровой процесс обрабатывается. Таким образом, это самый длинный файл. Мы изменим синтаксис небольшими порциями.
Как и основной файл, этот код имеет объявление пакета и класса. Удалить строки, которые начинаются
с «package» и «public class PlayState» и их скобками.

Теперь мы видим список локальных переменных.

1
2
3
4
5
6
7
8
9
private var _ship: Ship;
private var _aliens: FlxGroup;
private var _bullets: FlxGroup;
private var _scoreText: FlxText;
private var _gameOverText: FlxText;
private var _spawnTimer: Number;
private var _spawnInterval: Number = 2.5;

Помните ранее, что переменные в Lua являются локальными или глобальными, и что им не нужно
объявить их тип. Измените переменные так, чтобы они выглядели так:

1
2
3
4
5
6
7
local _ship;
local _aliens;
local _bullets;
local _scoreText;
local _spawnInterval = 2.5;

Теперь переместимся вниз по списку объявлений функций, начиная с create (). Удалите все объявления типов функций, такие как public
или «переопределить публику». Закомментируйте или удалите все возвращаемые типы для функций. Почти все эти функции «: void». Замените скобки функции на «конец». Create () теперь должен выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function create() —:void
    FlxG.score = 0;
             
    bgColor = 0xFFABCC7D;
             
    _ship = new Ship();
    add(_ship);
             
    _aliens = new FlxGroup();
    add(_aliens);
             
    _bullets = new FlxGroup();
    add(_bullets);
 
    _scoreText = new FlxText(10, 8, 200, «0»);
    _scoreText.setFormat(null, 32, 0xFF597137, «left»);
    add(_scoreText);
             
    resetSpawnTimer();
                         
    super.create();
end

Когда мы достигаем таких функций, как update (), нам также приходится иметь дело с операторами if-then. Только
замените открывающую скобку «{» на «then», а закрывающую скобку «}» на «end». Любой «&&» должен
заменить на «и». «||» следует заменить на «или».

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function update() —:void
    FlxU.overlap(_aliens, _bullets, overlapAlienBullet);
    FlxU.overlap(_aliens, _ship, overlapAlienShip);
             
    if(FlxG.keys.justPressed(«SPACE») and _ship.dead == false) then
        spawnBullet(_ship.getBulletSpawnPosition());
    end
 
    if(FlxG.keys.ENTER and _ship.dead) then
        FlxG.state = new PlayState();
    end
             
    _spawnTimer -= FlxG.elapsed;
             
    if(_spawnTimer < 0) then
        spawnAlien();
        resetSpawnTimer();
    end
                         
    super.update();
end

Некоторые функции, такие как overlapAlienBullet (), принимают аргументы. В ActionScript мы должны объявить тип аргументов, которые мы будем передавать. Функция overlapAlienBullet () принимает переменную иностранца (типа Alien) и переменную с именем bullet (типа Bullet). Эти объявления типов должны быть удалены. Кроме того, overlapAlienBullet () имеет локальные переменные. Удалите объявления типов из них. Примечание: объявления локальных переменных должны иметь ключевое слово local перед ними.

Перед:

01
02
03
04
05
06
07
08
09
10
11
12
private function overlapAlienBullet(alien: Alien, bullet: Bullet):void
{
    var emitter:FlxEmitter = createEmitter();
    emitter.at(alien);
    alien.kill();
    bullet.kill();
    FlxG.play(SoundExplosionAlien);
    FlxG.score += 1;
    _scoreText.text = FlxG.score.toString();
}

После:

01
02
03
04
05
06
07
08
09
10
11
function overlapAlienBullet(alien, bullet) —:void
    local emitter = createEmitter();
    emitter.at(alien);
    alien.kill();
    bullet.kill();
    FlxG.play(SoundExplosionAlien);
    FlxG.score += 1;
    _scoreText.text = FlxG.score.toString();
end

Самая последняя функция createEmitter () имеет оператор for-do. Мы не будем использовать эту функцию
в финальной игре, но мы должны взглянуть на это утверждение:

1
2
3
4
5
6
7
for(var i: int = 0; i < particles; i++)
{
    var particle:FlxSprite = new FlxSprite();
    particle.createGraphic(2, 2, 0xFF597137);
    particle.exists = false;
    emitter.add(particle);
}

В верхней строке кода создается переменная «i» со значением 0. Код в скобках повторяется
само по себе, в то время как «я» меньше, чем переменная «частицы». Каждый цикл, переменная «я» получает
увеличивается на 1.

1
2
3
for i=0, particles-1 do
end

Приведенный выше оператор Lua создает переменную «i» со значением 0. Код в скобках
повторяется до тех пор, пока «i» не станет равным переменной «частиц» минус 1 (так же, как проверка, если «i»
меньше «частиц»). Переменная «i» также увеличивается на 1 в каждом цикле.

Теперь мы можем завершить работу только с синтаксисом. Удалите все точки с запятой. Закомментируйте весь код как
с основным файлом. Добавьте однострочные комментарии перед отдельными строками кода.

1
2
3
4
5
—local _ship
—local _aliens
—local _bullets
—local _scoreText
—local _spawnInterval = 2.5

Добавьте многострочные комментарии вокруг функций и фрагментов кода.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
—[[
function create() —:void
    FlxG.score = 0
             
    bgColor = 0xFFABCC7D
             
    _ship = new Ship()
    add(_ship)
             
    _aliens = new FlxGroup()
    add(_aliens)
             
    _bullets = new FlxGroup()
    add(_bullets)
 
    _scoreText = new FlxText(10, 8, 200, «0»)
    _scoreText.setFormat(null, 32, 0xFF597137, «left»)
    add(_scoreText)
             
    resetSpawnTimer()
                         
    super.create()
end
—]]

Сохраните этот файл как PlayState.lua в папке вашего проекта. Не помещайте это в подкаталог
как исходный код. Корона имеет проблемы с модулями в подкаталогах.

Теперь мы готовы начать портирование логики этой игры. Давайте сначала поговорим о файловой логике.
В нашем исходном коде ActionScript файл Main.as выполняется первым. Другие файлы, такие как
PlayState.as, называются пакетами. Эти пакеты импортируются в основной файл. В Луа
Файл main.lua запускается первым. Другие файлы называются модулями и требуются в
основной файл. В ActionScript пакеты имеют объявление пакета. В Lua модули также должны иметь
декларации, или основной файл не может их видеть. Это означает, что нам нужно изменить наш файл PlayState.lua.
Вверху файла или любого другого файла модуля добавьте эту строку, чтобы main.lua мог работать с
модуль.

1
module(…, package.seeall)

Теперь вернитесь к файлу main.lua, чтобы мы могли загрузить наш модуль. Это должно выглядеть так:

1
2
3
4
5
6
7
8
9
—import org.flixel.*
—import de.pixelate.flixelprimer.*
     
—[SWF(width=»640″, height=»480″, backgroundColor=»#ABCC7D»)]
—[Frame(factoryClass=»Preloader»)]
 
—function Main() —:void
— super(640, 480, PlayState, 1)
—end

Мы видим, что оригинальный код ActionScript импортировал все пакеты в «org / flixel» и в
«Де / Pixelate / flixelprimer». Замените эти строки, чтобы сделать это:

1
2
3
4
5
6
7
8
local PlayState = require(«PlayState»)
     
—[SWF(width=»640″, height=»480″, backgroundColor=»#ABCC7D»)]
—[Frame(factoryClass=»Preloader»)]
 
—function Main() —:void
— super(640, 480, PlayState, 1)
—end

Этот код создает новую переменную (локальную по отношению к основному файлу) для хранения требуемого модуля. Мы
Теперь можно получить доступ к любому коду из файла PlayState.lua из переменной «PlayState».

Прежде чем мы продолжим работу с main.lua, нам нужно внести некоторые изменения в PlayState.lua. Если мы посмотрим на
оригинальный файл PlayState.as, мы видим, что все функциональные возможности обернуты внутри класса
называется PlayState. Мы не можем создавать классы с помощью lua, но мы можем организовать наш код таким образом, чтобы
это объектно-ориентированный. Обернув всю функциональность функцией конструктора, мы можем достичь
тот же эффект. Сохраняя весь ваш код закомментированным, добавьте эти строки вокруг всего кода.

1
2
3
function PlayState()
… code goes here …
end

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

Вот пример модуля, демонстрирующего эту функциональность:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module(…, package.seeall)
 
local numberOfInstances = 0
— this function mimics a class method
function getNumberOfInstances()
    return numberOfInstances
end
 
— this function mimics a class
function Instance()
    local Instance = {}
    numberOfInstances = numberOfInstances + 1
     
    local instanceNumber = numberOfInstances
     
    — this function mimics an instance method
    function Instance:getInstanceNumber()
        return instanceNumber
    end
     
    — this function mimics a private method
    function create()
        return Instance
    end
     
    — this calls the private method after all of the functions have been declared
    return create()
end

Если вы хотите поиграть с приведенным выше кодом, вот файл main.lua, демонстрирующий использование (при условии
модуль сохраняется как test.lua):

1
2
3
4
5
6
7
8
9
local test = require(«test»)
 
local instance1 = test.Instance()
local instance2 = test.Instance()
local instance3 = test.Instance()
local instance4 = test.Instance()
     
print(test.getNumberOfInstances())
print(instance2:getInstanceNumber())

Обратите внимание, что функции модуля используют точечный синтаксис, в то время как все другие функции Lua (и даже некоторые из
их объявления, как мы только что видели) используют точку (:) вместо точки. Это может сбивать с толку, так как
свойства в Lua доступны с использованием точечного синтаксиса. Из-за этого мы оставили все вызовы функций
в одиночку при переносе синтаксиса ранее. Мы решим, использовать ли двоеточие или точку для каждого случая
мы сталкиваемся.

Теперь, когда у нас есть все функциональные возможности в PlayState.lua внутри функции PlayState (), все
теперь функции имитируют закрытые функции в ActionScript. Что именно
что мы хотим. Добавьте локальную переменную PlayState вверху функции.

1
2
3
4
5
function PlayState()
    local PlayState = {}
     
    …
end

Теперь, продолжайте, раскомментируйте функцию create () и переместите ее вниз (непосредственно перед
окончательный конец). Добавьте однострочные комментарии ко всем строкам внутри функции, чтобы мы могли
увидеть логику, но она не выдает никаких ошибок.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
module(…, package.seeall)
 
function PlayState()
    local PlayState = {}
     
    … a whole bunch of commented code …
     
    function create() —:void
        —FlxG.score = 0
             
        —bgColor = 0xFFABCC7D
             
        —_ship = new Ship()
        —add(_ship)
             
        —_aliens = new FlxGroup()
        —add(_aliens)
             
        —_bullets = new FlxGroup()
        —add(_bullets)
 
        —_scoreText = new FlxText(10, 8, 200, «0»)
        —_scoreText.setFormat(null, 32, 0xFF597137, «left»)
        —add(_scoreText)
             
        —resetSpawnTimer()
                         
        —super.create()
    end
end

Оригинальная игра ActionScript была построена с использованием библиотеки flixel, обсуждаемой в начале этого
урок. К сожалению, на момент написания статьи нет порта Lua flixel. Итак, мы будем
реализовать всю логику фликселя с помощью API Corona SDK.

Первое, на что стоит обратить внимание, это возвращение в файл main.lua. В flixel функция Main () автоматически
вызывается при запуске программы. В Corona файл main.lua запускается сверху вниз.
Таким образом, для достижения того же эффекта, что и в исходном коде, добавьте Main () в конец main.lua.

01
02
03
04
05
06
07
08
09
10
local PlayState = require(«PlayState»)
     
—[SWF(width=»640″, height=»480″, backgroundColor=»#ABCC7D»)]
—[Frame(factoryClass=»Preloader»)]
 
function Main() —:void
— super(640, 480, PlayState, 1)
end
 
Main()

Кроме того, в большинстве игр flixel во время работы программы отображается предзагрузчик с логотипом flixel.
погрузка. Нам это не нужно для нашего приложения, поэтому мы не будем создавать файл preloader.lua. Добавление строк
предварительный загрузчик и настройка размера программы / фона могут быть удалены (мы не можем изменить приложение
размер).

1
2
3
4
5
6
7
local PlayState = require(«PlayState»)
 
function Main() —:void
— super(640, 480, PlayState, 1)
end
 
Main()

Пока мы здесь, создайте новый PlayState в Main ().

1
2
3
4
5
6
7
local PlayState = require(«PlayState»)
 
function Main() —:void
    PlayState.PlayState()
end
 
Main()

Возвращаясь к PlayState.lua, мы замечаем, что create () не вызывается. В flixel создать () и
update () автоматически обрабатываются. Мы должны позаботиться об этом сами в Короне. Добавить
вызов для создания () до последнего конца.

01
02
03
04
05
06
07
08
09
10
11
12
13
module(…, package.seeall)
 
function PlayState()
    local PlayState = {}
     
    … a whole bunch of commented code …
     
    function create() —:void
        … commented create() logic …
    end
     
    create()
end

Прежде чем мы продолжим, давайте посмотрим на то, что мы имеем до сих пор. Теперь у нас есть файл main.lua, который
требует PlayState.lua и запускает PlayState (). PlayState () создает новый экземпляр PlayState, а затем
вызовы create (). Create () — это то место, куда уходит весь установочный код для игры. Теперь у нас есть рамки
строить нашу логику вокруг.

Теперь нам нужно начать добавлять функции в нашу функцию create (), чтобы настроить нашу игру. Давайте начнем с
создавая зеленый фон игры. В нашем коде мы закомментировали эту строку в нашем
создать () функцию.

1
—bgColor = 0xFFABCC7D;

Это говорит нам шестнадцатеричное значение для исходного зеленого цвета. Простой способ сделать фон
В Corona нужно сделать цветной прямоугольник того же размера, что и экран. Это можно сделать с помощью
Экранные объекты Corona. Подобно ActionScript, Corona предоставляет нам API для отображения объектов
экран. Мы можем использовать дисплейный модуль для множества различных задач. Может использоваться для создания
новые объекты или группы объектов, или для поиска ширины / высоты экрана. Давайте создадим новый
прямоугольник и сохраните его как свойство нашей переменной PlayState.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
module(…, package.seeall)
 
function PlayState()
    local PlayState = {}
     
    … a whole bunch of commented code …
     
    function create() —:void
        PlayState._background = display.newRect(0, 0, display.contentWidth, display.contentHeight)
        … commented create() logic …
    end
     
    create()
end

Здесь мы создали новый прямоугольник от (0,0) до (ширина экрана, высота экрана) и сохранили
это в переменной _background. Я поместил подчеркивание там, чтобы подражать оригинальному коду. Все
личных переменных в версии ActionScript игры начинаются с подчеркивания.
_background является приватным для каждого экземпляра PlayState, поэтому я отформатировал его, как и другие переменные.

Обратите внимание на синтаксис точки. Если вы помните ранее, это означает, что _background теперь является свойством
PlayState. Поскольку мы создали переменную PlayState вне функции create (), она доступна
Теперь ко всем функциям. Если бы мы создали PlayState внутри create () следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
module(…, package.seeall)
 
function PlayState()
     
    function create()
        — PlayState is now local to create()
        local PlayState = {}
         
        — PlayState can still be used in create, but it is not available outside.
        PlayState._aNumber = 10
    end
     
    function otherFunction()
        — This will throw an error.
        print(PlayState._aNumber)
    end
     
    create()
    otherFunction()
end

Мы не смогли бы использовать его в otherFunction (). Так как мы создали PlayState в начале
PlayState (), все функции могут использовать его.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
module(…, package.seeall)
 
function PlayState()
    — PlayState is now local to PlayState()
    local PlayState = {}
         
    function create()
        — PlayState (and its properties) can be used in create and anywhere else.
        PlayState._aNumber = 10
    end
     
    function otherFunction()
        PlayState._aNumber = PlayState._aNumber + 4
        — This will print 14
        print(PlayState._aNumber)
    end
     
    create()
    otherFunction()
end

Если вы запустите код с новым прямоугольником, вы увидите белый фон. Нам нужно изменить его
залейте цвет до зеленого. Для этого нам нужно преобразовать шестнадцатеричный код (ABCC7D) в RGB, что
Корона использует для заполнения экранных объектов. Вы можете вставить этот код в любой из шестнадцатеричных сайтов RGB.
Результат будет (171, 204, 125). Теперь используйте метод экземпляра setFillColor (обратите внимание на двоеточие) на
PlayState._background.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
module(…, package.seeall)
 
function PlayState()
    local PlayState = {}
     
    … a whole bunch of commented code …
     
    function create() —:void
        PlayState._background = display.newRect(0, 0, display.contentWidth, display.contentHeight)
        PlayState._background:setFillColor(171, 204, 125)
        … commented create() logic …
    end
     
    create()
end

Теперь у нас есть начало игры. Давайте внесем еще несколько изменений, прежде чем подведем итоги.
Давайте добавим переменную в каждый экземпляр PlayState, чтобы узнать, запущена игра или нет.

1
module(…, package.seeall) function PlayState() local PlayState = {} … a whole bunch of commented code … function create() —:void PlayState._inGame = true PlayState._background = display.newRect(0, 0, display.contentWidth, display.contentHeight) PlayState._background:setFillColor(171, 204, 125) … commented create() logic … end create() end

Это станет очень полезным позже. Давайте также избавимся от строки состояния в верхней части iPhone.
Мы хотим, чтобы это делалось только один раз при запуске приложения, поэтому добавьте это в main.lua.

1
2
3
4
5
6
7
8
9
local PlayState = require(«PlayState»)
 
function Main() —:void
    display.setStatusBar( display.HiddenStatusBar )
 
    PlayState.PlayState()
end
 
Main()

Другим важным шагом при создании приложения Corona является добавление файла конфигурации, который сообщит Corona, как
масштабировать ваше приложение на других платформах. В этом уроке мы касаемся только iPhone
размер экрана (хотя приложение будет работать на Android тоже). Создайте файл с именем config.lua и заполните его
с этим.

1
2
3
4
5
6
7
8
9
application =
{
content =
{
width = 320,
height = 480,
scale = «letterbox»
},
}

Теперь наше приложение будет работать и на дисплеях сетчатки. Примечание: этот файл будет работать с любым приложением Corona.

Теперь у нас есть рабочая основа, на которой можно начать строить. Наше приложение пока не очень похоже, но мы
охватили много важных шагов при переносе с одного языка на другой. В следующий
Урок этой серии мы начнем делать играбельной игрой.