Статьи

Создать игру «Танцующий палач» в Corona: Настройка проекта

Конечный продукт
Что вы будете создавать

В этой серии из двух частей я покажу вам, как создать классическую игру палача. Однако эта версия имеет неожиданное окончание. Если вы выиграли игру, палач исполняет счастливый танец. Кроме того, вы узнаете об API рисования Corona, управлении сценами, отправке пользовательских событий, о том, как использовать таблицу спрайтов и как использовать модули для эмуляции классов на языке программирования Lua.

Во второй части этой серии мы будем танцевать палача, если пользователь выиграет раунд. Во время танца палача мы играем музыку , созданную knarmahfox , лицензированную по лицензии Creative Commons Attribution .

Откройте Corona Simulator, нажмите « Новый проект» и настройте проект, как показано ниже.

настройки симулятора короны

Выберите место для сохранения вашего проекта и нажмите ОК . Это создаст папку с несколькими значками и тремя интересующими нас файлами: main.lua , config.lua и build.settings . Мы рассмотрим каждый файл в следующие несколько шагов.

Файл build.settings отвечает за свойства времени сборки проекта. Откройте этот файл, удалите его содержимое и заполните его следующей конфигурацией.

01
02
03
04
05
06
07
08
09
10
11
settings =
{
    orientation =
    {
        default =»portrait»,
        supported =
        {
          «portrait»
        },
    },
}

В build.settings мы устанавливаем ориентацию по умолчанию и ограничиваем приложение только поддержкой книжной ориентации. Вы можете узнать, какие другие настройки вы можете включить в build.settings, изучив документацию Corona .

Файл config.lua обрабатывает конфигурацию приложения. Как и в случае с build.settings , откройте этот файл, удалите его содержимое и добавьте следующую конфигурацию.

01
02
03
04
05
06
07
08
09
10
application =
{
    content =
    {
      width = 768,
      height = 1024,
      scale = «letterbox»,
      fps = 30,
    }
}

Это устанавливает ширину и высоту экрана по умолчанию, использует почтовый ящик для масштабирования изображений и устанавливает частоту кадров 30 . Посетите документацию Corona, чтобы узнать больше о других свойствах, которые вы можете установить в config.lua .

Файл main.lua — это файл, который приложение загружает первым и использует для начальной загрузки приложения. Мы будем использовать main.lua, чтобы установить несколько настроек по умолчанию для приложения, и библиотеку Composer для загрузки первого экрана.

Если вы не знакомы с библиотекой Corona Composer, то я рекомендую дать
Документация быстрого чтения. Короче говоря, Composer — это встроенное решение для создания и управления сценой (экраном) в Corona. Библиотека предоставляет разработчикам простой способ создания и перехода между сценами.

Более новый модуль Composer заменяет старый и теперь устаревший модуль StoryBoard . Доступно руководство по миграции, которое поможет преобразовать ваши старые проекты в Composer.

Мы не хотим, чтобы строка состояния отображалась в нашем приложении. Добавьте следующий фрагмент кода в main.lua, чтобы скрыть строку состояния.

1
display.setStatusBar(display.HiddenStatusBar)

Чтобы установить точки привязки по умолчанию или точки регистрации, добавьте следующий блок кода в main.lua .

1
2
display.setDefault( «anchorX», 0.5)
display.setDefault( «anchorY», 0.5)

anchorX и anchorY указывают, где вы хотите, чтобы точка регистрации ваших экранных объектов была. Обратите внимание, что значение варьируется от 0,0 до 1,0 . Например, если вы хотите, чтобы точка регистрации находилась в верхнем левом углу экранного объекта, вы должны установить оба свойства на 0.0 .

Наша игра будет использовать функцию Lua math.random для генерации случайных чисел. Чтобы убедиться, что числа действительно случайны при каждом запуске приложения, необходимо указать начальное значение. Если вы не предоставите начальное значение, приложение будет каждый раз генерировать одну и ту же случайность.

Хорошее начальное значение — это функция Lua os.time так как она будет отличаться каждый раз, когда
приложение запущено. Добавьте следующий фрагмент кода в main.lua .

1
math.randomseed( os.time() )

Прежде чем мы сможем использовать модуль Composer, мы должны сначала потребовать его. Добавьте следующее в main.lua .

1
local composer = require( «composer» )

Добавьте следующий фрагмент кода в main.lua . Это заставит приложение перейти на сцену с именем gamescreen , которая также является файлом Lua, gamescreen.lua . Вам не нужно добавлять расширение файла при вызове функции gotoScene .

1
composer.gotoScene( «gamescreen» )

Создайте новый файл Lua с именем gamescreen.lua в главном каталоге проекта. Это будет файл композитора, а это значит, что нам нужен модуль Composer и создать сцену композитора. Добавьте следующий фрагмент к gamescreen.lua .

1
2
3
local composer = require( «composer» )
local scene = composer.newScene()
return scene

Вызов newScene делает gamescreen.lua частью иерархии сцен композитора. Это означает, что он становится экраном в игре, на котором мы можем вызывать методы композитора.

С этого момента код, добавленный в gamescreen.lua, должен быть помещен над оператором return.

Следующий фрагмент содержит локальные переменные, которые нам понадобятся для игровой сцены.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
local widget = require («widget») — Needed for the button widget
local growText = require(«growtext») — A module providing a growing text effect
local words5 = {} — Holds words 5 characters or less in length
local words9 = {} — Holds words 9 characters or less in length
local words13 = {} — Holds words 13 characters or less in length
local hangmanGroup
local alphabetArray = {«A»,»B»,»C»,»D»,»E»,»F»,»G»,»H»,»I»,»J»,»K»,»L»,»M»,»N»,»O»,»P»,»Q»,»R»,»S»,»T»,»U»,»V»,»W»,»X»,»Y»,»Z»}
local guessWordText
local theWord — The actual word
local guessWord — The word the player has guessed
local numWrong = 0
local gameButtons = {} — holds all the buttons
local winLoseText
local wonGame = false

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

Это важно помнить, если вы хотите, чтобы локальные переменные были повторно инициализированы при
вернуться к определенной сцене. Самый простой способ сделать это — удалить сцену из иерархии композитора, вызвав метод removeScence . В следующий раз, когда вы перейдете к этой сцене, сцена будет автоматически перезагружена. Именно такой подход мы будем использовать в этом уроке.

Чтобы иметь возможность использовать ButtonWidget в Corona, нам нужна библиотека виджетов . Модуль growText — это пользовательский модуль, который мы создадим для обеспечения растущего текстового эффекта. Создайте новый файл в папке вашего проекта с именем growtext.lua .

Если вы потратили время на чтение документации библиотеки Composer, на которую я ссылался ранее, вы заметите, что документация содержит шаблон, который содержит все возможные события композитора. Комментарии очень полезны, так как они указывают, какие события использовать для инициализации ресурсов, таймеров и т. Д. Нам интересны методы scene:create , scene:show и scene:hide для этого урока.

Добавьте следующий фрагмент кода в gamescreen.lua .

1
2
3
function scene:create( event )
    local group = self.view
end

Этот метод вызывается, когда вид сцены еще не существует. Здесь вы должны инициализировать экранные объекты и добавить их в сцену. Переменная group указывает на self.view , который является GroupObject для всей сцены.

scene:show композитора scene:show метод scene:show имеет две фазы. Фаза воли вызывается, когда сцена все еще находится вне экрана, но вот-вот появится. Фаза did вызывается, когда сцена находится на экране. Здесь вы хотите добавить код, чтобы оживить сцену, запустить таймеры, добавить прослушиватели событий, воспроизвести аудио и т. Д.

В этом уроке нас интересует только фаза did . Добавьте следующий фрагмент кода в gamescreen.lua .

01
02
03
04
05
06
07
08
09
10
11
12
function scene:show( event )
    local phase = event.phase
    local previousScene = composer.getSceneName( «previous» )
    if(previousScene~=nil) then
 
        composer.removeScene(previousScene)
    end
   if ( phase == «did» ) then
         
   end
 
end

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

scene:hide Composer scene:hide метод scene:hide также имеет две фазы. Фаза воли вызывается, когда сцена находится на экране, но собирается покинуть экран. Здесь вы захотите остановить любые таймеры, удалить прослушиватели событий, остановить звук и т. Д. Фаза did вызывается, когда сцена выходит за пределы экрана.

В этом уроке нас интересует только фаза воли .

1
2
3
4
5
6
function scene:hide( event )
    local phase = event.phase
    if ( phase == «will» ) then
     
    end
end

Нам нужно добавить слушателей сцены для методов create , show и hide . Добавьте следующий код в gamescreen.lua .

1
2
3
4
scene:addEventListener( «create», scene )
scene:addEventListener( «show», scene )
scene:addEventListener( «hide», scene )
scene:addEventListener( «destroy», scene )

Теперь вы должны протестировать проект, чтобы убедиться в отсутствии ошибок. Простой способ подтвердить, что проект работает должным образом, — добавить оператор print в scene:show метод scene:show как показано ниже.

1
2
3
4
5
6
7
function scene:show( event )
    local phase = event.phase
    —SNIP—
   if ( phase == «did» ) then
        print(«Working») — Temporary print statement
   end
end

Если вы протестируете приложение и загляните в консоль, вы увидите, что «Working» было распечатано. Вы можете удалить оператор печати теперь, когда вы убедились, что проект работает должным образом.

Мы нарисуем «классную доску», которая будет использоваться в качестве фона для игры. Введите следующий код в gamescreen.lua .

1
2
3
4
5
6
7
function drawChalkBoard(r,g,b)
local chalkBoard = display.newRect( 0, 0, display.contentWidth, display.contentHeight )
    chalkBoard:setFillColor(r,g,b)
    chalkBoard.anchorX = 0
    chalkBoard.anchorY = 0
    scene.view:insert(chalkBoard)
end

Метод newRect рисует прямоугольник на экране. Он принимает в качестве параметров x и y прямоугольника, а также ширину и высоту. Мы используем display.contentWidth и display.contentHeight , которые представляют исходную ширину и высоту содержимого в пикселях. По умолчанию это ширина экрана и высота.

setFillColor принимает в качестве параметров значения R, G и B в процентах, в диапазоне от 0 до 1 . Передавая значения R, G, B в качестве параметров, мы можем легко изменить цвет классной доски.

Ранее в этом уроке мы установили для anchorX по умолчанию и anchorY значение 0.5 . Мы установили их здесь на 0, поэтому прямоугольник будет отображаться в левом верхнем углу экрана. Мы вставляем chalkboard в вид scene , чтобы она была удалена при удалении самой scene .

Далее нам нужно вызвать этот метод в scene:create метод scene:create как показано в следующем фрагменте кода.

1
2
3
4
function scene:create( event )
    local group = self.view
    drawChalkBoard(1,1,1)
end

Corona SDK предоставляет API рисования через класс Display . В этом уроке мы будем использовать только методы рисования newCircle и newLine . Мы использовали newRect рисования newRect на предыдущем шаге. Класс Display также предоставляет метод для рисования полигонов. Проверьте документацию для получения дополнительной информации.

Игра нарисует палача и поместит его в GroupObject , hangmanGroup . Это позволит нам работать над нарисованными фигурами как группа. Добавьте следующее к scene:create метод scene:create .

1
2
3
4
5
6
7
function scene:create( event )
    —SNIP—
    hangmanGroup = display.newGroup()
    group:insert(hangmanGroup)
    hangmanGroup.x = 180
    hangmanGroup.y = 180
end

Добавьте следующий код в gamescreen.lua .

1
2
3
4
5
6
function drawGallows()
    local gallows = display.newLine( hangmanGroup,20,380,360, 380)
    gallows:append(290,380,290,50,180,50,180,90)
    gallows:setStrokeColor(0, 0, 0)
    gallows.strokeWidth = 3
end

Здесь мы используем метод newLine для рисования виселицы. Параметры для newLine — это группа, в которой рисуется линия, начальные x и y позиции линии и конечные x и y позиции линии.

Метод append позволяет нам добавлять дополнительные пары x и y к исходной строке. Метод setStrokeColor устанавливает цвет линии, а свойство strokeWidth устанавливает ширину линии.

Вызовите этот метод в scene:create .

1
2
3
4
5
6
function scene:create( event )
    —SNIP—
    hangmanGroup.x = 180
    hangmanGroup.y = 180
    drawGallows()
end

Если вы протестируете игру в этот момент, вы должны увидеть виселицу, нарисованную на экране.

рисование виселицы

Следующий код рисует голову.

1
2
3
4
5
6
7
8
function drawHead()
   local head = display.newCircle(hangmanGroup,150,90,30)
   head:setStrokeColor(0,0,0)
   head:setFillColor(0,0,0,0)
   head.strokeWidth = 3
   head.anchorX = 0
   head.anchorY = 0
end

Метод newCircle принимает в качестве параметров группу, в которую нужно нарисовать окружность, положения x и y и радиус окружности. С setFillColor метода setFillColor мы передаем дополнительный 0 , который является свойством альфа . Нам не нужен закрашенный круг, поэтому, передав 0, заливка будет полностью прозрачной. Другие варианты должны быть знакомы, если вы следовали.

Функция drawBody рисует вертикальную линию, представляющую тело палача.

1
2
3
4
5
function drawBody()
    local body = display.newLine(hangmanGroup,180,150,180,300)
    body:setStrokeColor(0, 0, 0)
    body.strokeWidth = 3
end
01
02
03
04
05
06
07
08
09
10
11
function drawArm1()
    local arm = display.newLine(hangmanGroup,180,200,130,190)
    arm:setStrokeColor(0, 0, 0)
    arm.strokeWidth = 3
end
 
function drawArm2()
    local arm= display.newLine(hangmanGroup,180,200,230,190)
    arm:setStrokeColor(0, 0, 0)
    arm.strokeWidth = 3
end

Функции drawLeg1 и drawLeg2 рисуют ноги палача.

01
02
03
04
05
06
07
08
09
10
11
function drawLeg1()
    local leg = display.newLine(hangmanGroup,180,300,130,330)
    leg:setStrokeColor(0, 0, 0)
    leg.strokeWidth = 3
end
 
function drawLeg2()
    local leg = display.newLine(hangmanGroup,180,300,230,330)
    leg:setStrokeColor(0, 0, 0)
    leg.strokeWidth = 3
end

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

01
02
03
04
05
06
07
08
09
10
function scene:create( event )
    —SNIP—
    drawGallows()
    drawHead()
    drawBody()
    drawArm1()
    drawArm2()
    drawLeg1()
    drawLeg2()
end
рисование палача

Теперь вы можете удалить все вызовы функций, которые мы только что добавили. Мы не хотим рисовать палача, как только игра начнется. Убедитесь, что вы оставили метод drawGallows .

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