В этой серии из двух частей я покажу вам, как создать классическую игру палача. Однако эта версия имеет неожиданное окончание. Если вы выиграли игру, палач исполняет счастливый танец. Кроме того, вы узнаете об API рисования Corona, управлении сценами, отправке пользовательских событий, о том, как использовать таблицу спрайтов и как использовать модули для эмуляции классов на языке программирования Lua.
Во второй части этой серии мы будем танцевать палача, если пользователь выиграет раунд. Во время танца палача мы играем музыку , созданную knarmahfox , лицензированную по лицензии Creative Commons Attribution .
1. Новый проект
Откройте Corona Simulator, нажмите « Новый проект» и настройте проект, как показано ниже.
Выберите место для сохранения вашего проекта и нажмите ОК . Это создаст папку с несколькими значками и тремя интересующими нас файлами: main.lua , config.lua и build.settings . Мы рассмотрим каждый файл в следующие несколько шагов.
2. Настройки сборки
Файл build.settings отвечает за свойства времени сборки проекта. Откройте этот файл, удалите его содержимое и заполните его следующей конфигурацией.
01
02
03
04
05
06
07
08
09
10
11
|
settings =
{
orientation =
{
default =»portrait»,
supported =
{
«portrait»
},
},
}
|
В build.settings мы устанавливаем ориентацию по умолчанию и ограничиваем приложение только поддержкой книжной ориентации. Вы можете узнать, какие другие настройки вы можете включить в build.settings, изучив документацию Corona .
3. Конфигурация приложения
Файл 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 .
4. Точка входа
Файл main.lua — это файл, который приложение загружает первым и использует для начальной загрузки приложения. Мы будем использовать main.lua, чтобы установить несколько настроек по умолчанию для приложения, и библиотеку Composer для загрузки первого экрана.
Если вы не знакомы с библиотекой Corona Composer, то я рекомендую дать
Документация быстрого чтения. Короче говоря, Composer — это встроенное решение для создания и управления сценой (экраном) в Corona. Библиотека предоставляет разработчикам простой способ создания и перехода между сценами.
Более новый модуль Composer заменяет старый и теперь устаревший модуль StoryBoard . Доступно руководство по миграции, которое поможет преобразовать ваши старые проекты в Composer.
Шаг 1: Скрыть строку состояния
Мы не хотим, чтобы строка состояния отображалась в нашем приложении. Добавьте следующий фрагмент кода в main.lua, чтобы скрыть строку состояния.
1
|
display.setStatusBar(display.HiddenStatusBar)
|
Шаг 2. Установите точки привязки по умолчанию
Чтобы установить точки привязки по умолчанию или точки регистрации, добавьте следующий блок кода в main.lua .
1
2
|
display.setDefault( «anchorX», 0.5)
display.setDefault( «anchorY», 0.5)
|
anchorX
и anchorY
указывают, где вы хотите, чтобы точка регистрации ваших экранных объектов была. Обратите внимание, что значение варьируется от 0,0 до 1,0 . Например, если вы хотите, чтобы точка регистрации находилась в верхнем левом углу экранного объекта, вы должны установить оба свойства на 0.0 .
Шаг 3: Генератор случайных семян
Наша игра будет использовать функцию Lua math.random
для генерации случайных чисел. Чтобы убедиться, что числа действительно случайны при каждом запуске приложения, необходимо указать начальное значение. Если вы не предоставите начальное значение, приложение будет каждый раз генерировать одну и ту же случайность.
Хорошее начальное значение — это функция Lua os.time
так как она будет отличаться каждый раз, когда
приложение запущено. Добавьте следующий фрагмент кода в main.lua .
1
|
math.randomseed( os.time() )
|
Шаг 4: Требовать Composer
Прежде чем мы сможем использовать модуль Composer, мы должны сначала потребовать его. Добавьте следующее в main.lua .
1
|
local composer = require( «composer» )
|
Шаг 5: Загрузите сцену GameScreen
Добавьте следующий фрагмент кода в main.lua . Это заставит приложение перейти на сцену с именем gamescreen , которая также является файлом Lua, gamescreen.lua . Вам не нужно добавлять расширение файла при вызове функции gotoScene
.
1
|
composer.gotoScene( «gamescreen» )
|
5. 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.
Шаг 1: Локальные переменные
Следующий фрагмент содержит локальные переменные, которые нам понадобятся для игровой сцены.
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 .
Шаг 2: События Composer
Если вы потратили время на чтение документации библиотеки Composer, на которую я ссылался ранее, вы заметите, что документация содержит шаблон, который содержит все возможные события композитора. Комментарии очень полезны, так как они указывают, какие события использовать для инициализации ресурсов, таймеров и т. Д. Нам интересны методы scene:create
, scene:show
и scene:hide
для этого урока.
scene:create
Добавьте следующий фрагмент кода в gamescreen.lua .
1
2
3
|
function scene:create( event )
local group = self.view
end
|
Этот метод вызывается, когда вид сцены еще не существует. Здесь вы должны инициализировать экранные объекты и добавить их в сцену. Переменная group
указывает на self.view
, который является GroupObject
для всей сцены.
scene:show
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
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
|
Шаг 3: Добавьте слушателей сцены
Нам нужно добавить слушателей сцены для методов 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 )
|
Шаг 4: Прогресс теста
Теперь вы должны протестировать проект, чтобы убедиться в отсутствии ошибок. Простой способ подтвердить, что проект работает должным образом, — добавить оператор 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» было распечатано. Вы можете удалить оператор печати теперь, когда вы убедились, что проект работает должным образом.
6. Рисование Доске
Мы нарисуем «классную доску», которая будет использоваться в качестве фона для игры. Введите следующий код в 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
|
7. Рисование API
Corona SDK предоставляет API рисования через класс Display
. В этом уроке мы будем использовать только методы рисования newCircle
и newLine
. Мы использовали newRect
рисования newRect
на предыдущем шаге. Класс Display
также предоставляет метод для рисования полигонов. Проверьте документацию для получения дополнительной информации.
Шаг 1: Добавление hangmanGroup
Игра нарисует палача и поместит его в 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
|
Шаг 2: Рисуем Палача
drawGallows
Добавьте следующий код в 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
|
Если вы протестируете игру в этот момент, вы должны увидеть виселицу, нарисованную на экране.
drawHead
Следующий код рисует голову.
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
Функция 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
|
drawArm1
и drawArm2
Функции drawArm1
и drawArm2
рисуют руки палача.
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
Функции 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
|
8. Прогресс тестирования
Теперь, когда у нас есть все методы для рисования палача, мы можем проверить и убедиться, что все работает как надо. Все, что нам нужно сделать, это вызвать каждый из предыдущих методов в 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
.
Вывод
На этом первая серия из двух частей заканчивается. Во второй части мы будем реализовывать игровой процесс и танцевать палача под веселую музыку. Спасибо за чтение, и я надеюсь увидеть вас во второй части.