В первой части этой серии из двух частей мы заложили основу для перехода между экранами и рисования палача с помощью API рисования Corona. Во второй и последней части этой серии мы реализуем игровую логику и перейдем к экрану побед, где палач будет танцевать вместе с музыкой. Давайте начнем.
1. Создание слова, чтобы угадать
Шаг 1: Чтение текстового файла
Игра читает словами из текстового файла, который содержит тысячи слов. Мы отфильтруем слова по их длине и добавим их в один из трех списков: слова длиной не более 5 символов, длиной не более 9 символов и длиной не более 13 символов.
Имея три отдельных списка слов, мы можем интегрировать уровень сложности на основе длины слова. Мы не будем этого делать в этом уроке, но слова уже будут разделены на отдельные списки, если вы решите воспользоваться этим вариантом самостоятельно.
Добавьте следующий код в gamescreen.lua .
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
function readTextFile()
local path = system.pathForFile( «wordlist.txt», system.ResourceDirectory)
local file = io.open( path, «r» )
for line in file:lines() do
—If targeting Windows Operating System comment the following line out
— line = string.sub(line, 1, #line — 1)
if(#line >=3 and #line <=5)then
table.insert(words5,line)
elseif (#line >=3 and #line<=9)then
table.insert(words9,line)
elseif (#line >=3 and #line<=13)then
table.insert(words13,line)
end
end
io.close( file )
file = nil
end
|
Функция readTextFile
читает текстовый файл wordlist.txt . Мы перебираем каждую строку wordlist.txt и, в зависимости от длины слова, вставляем ее в одну из трех таблиц words5
, words9
или words13
.
Системы на базе Windows и Unix по-разному обрабатывают окончания строк. В Windows будет дополнительный символ, который мы можем удалить с string.sub
метода string.sub
. Если вы используете компьютер с Windows, вам нужно добавить эту строку кода, удалив предшествующий символ.
Всякий раз, когда вы читаете файл, важно помнить, что когда вы закончите, вы должны close
и nil
файл, как показано в приведенной выше реализации.
Вызовите эту функцию в scene:create
. Я поместил его в самый верх, над другими вызовами функций.
1
2
3
4
5
6
|
function scene:create( event )
local group = self.view
readTextFile()
drawChalkBoard(1,1,1)
—SNIP—
end
|
Шаг 2: CreateGuessWord
Функция createGuessWord
отвечает за получение случайного слова из списка и его возврат. Добавьте следующий код в gamescreen.lua .
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
function createGuessWord()
guessWord = {}
local randomIndex = math.random(#words5)
theWord = words5[randomIndex];
print(theWord)
for i=1, #theWord do
local character= theWord:sub(i,i)
if(character == «‘»)then
guessWord[i] =»‘»;
elseif(character==»-«)then
guessWord[i] = «-«
else
guessWord[i]=»?»;
end
end
local newGuessWord = table.concat(guessWord)
return newGuessWord;
end
|
Мы используем таблицу guessWord
, чтобы хранить каждую букву слова. Причина этого заключается в том, что строки в Lua неизменны, а это означает, что мы не можем изменить символ строки.
Сначала мы генерируем случайное число randomIndex
, которое будет числом от 1 до randomIndex
элементов в таблице. Затем мы используем это число, чтобы получить слово из таблицы.
Мы перебираем слово и получаем ссылку на текущий символ, используя метод string.sub
. Если текущий символ — апостроф или тире, мы помещаем это в guessword
таблицы, в противном случае мы ставим знак вопроса в таблице.
Затем мы преобразовываем таблицу guessWord
в строку newGuessWord
используя метод newGuessWord
. Наконец, мы возвращаем newGuessWord
.
Шаг 3: CreateGuessWordText
Функция createGuessWordText
создает Text
в верхней части игровой области, который будет меняться в зависимости от предположения игрока.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
function createGuessWordText()
local options =
{
text = createGuessWord(),
x = 384,
y = 70,
width = 700, —required for multi-line and alignment
font = native.systemFontBold,
fontSize = 50,
align = «center» —new alignment parameter
}
guessWordText = display.newText(options)
guessWordText:setFillColor(0,0,0)
scene.view:insert(guessWordText)
end
|
Таблица options
содержит различные параметры конфигурации для Text
. Поскольку функция createGuessWord
возвращает слово в виде строки, мы можем просто вызвать его при установке свойства text
.
Мы создаем Text
, вызывая метод newText
в Display
, передавая таблицу параметров. Затем мы устанавливаем его цвет и вставляем его в вид сцены.
Вызовите эту функцию в scene:create
как показано ниже.
1
2
3
4
5
|
function scene:create( event )
—SNIP—
drawGallows()
createGuessWordText()
end
|
Слово о метатаблицах
В языке программирования Lua нет встроенной системы классов. Однако с помощью метатабельной конструкции Lua мы можем эмулировать систему классов. На веб-сайте Corona есть хороший пример , показывающий, как это реализовать.
Важно отметить, что объекты Display
Corona не могут быть установлены как метатабельные. Это связано с тем, как базовый язык C взаимодействует с ними. Простой способ обойти это — установить объект Display
в качестве ключа для новой таблицы, а затем установить эту таблицу в качестве метатабельной. Это подход, который мы будем использовать в этом уроке.
Если вы прочтете приведенную выше статью на веб-сайте Corona, вы __Index
что в метатаблице использовался __Index
. __Index
работает так: когда вы пытаетесь получить доступ к отсутствующему полю в таблице, он вызывает интерпретатор для поиска __Index
. Если __Index
есть, он будет искать поле и предоставлять результат, в противном случае это приведет к nil
.
2. Реализация класса GrowText
В игре есть Text
который будет расти от маленького до большого за короткий промежуток времени, когда пользователь выигрывает или проигрывает игру. Мы создадим эту функциональность как модуль . Имея этот код в качестве модуля, мы можем повторно использовать его в любом проекте, который требует этой функциональности.
Добавьте следующее к growtext.lua , который вы создали в первой части этой серии.
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
31
32
33
34
35
36
37
38
39
40
41
42
43
|
local growText = {}
local growText_mt = {__index = growText}
function growText.new(theText,positionX,positionY,theFont,theFontSize,theGroup)
local theTextField = display.newText(theText,positionX,positionY,theFont,theFontSize)
local newGrowText = {
theTextField = theTextField}
if(theGroup ~=nil)then
theGroup:insert(theTextField)
end
return setmetatable(newGrowText,growText_mt)
end
function growText:setColor(r,b,g)
self.theTextField:setFillColor(r,g,b)
end
function growText:grow()
transition.to( self.theTextField, { xScale=4.0, yScale=4.0, time=2000, iterations = 1,onComplete=function()
local event = {
name = «gameOverEvent»,
}
self.theTextField.xScale = 1
self.theTextField.yScale = 1
Runtime:dispatchEvent( event )
end
} )
end
function growText:setVisibility(visible)
if(visible == true)then
self.theTextField.isVisible = true
else
self.theTextField.isVisible = false
end
self.theTextField.xScale = 1
self.theTextField.yScale = 1
end
function growText:setText(theText)
self.theTextField.text = theText
end
return growText
|
Мы создаем основную таблицу growText
и таблицу, которая будет использоваться как growText_mt
, growText_mt
. В new
методе мы создаем объект Text
и добавляем его в таблицу newGrowText
которая будет установлена как метатабельная. Затем мы добавляем объект Text
в group
которая была передана в качестве параметра, который будет группой scene
, в которой мы создаем экземпляр GrowText
.
Важно убедиться, что мы добавили его в группу scene
, чтобы он был удален при удалении сцены. Наконец, мы устанавливаем метатаблицу.
У нас есть четыре метода, которые обращаются к объекту Text
и выполняют операции над его свойствами.
setColor
Метод setColor
устанавливает цвет Text
, вызывая метод setFillColor
, который принимает в качестве параметров значения значений R, G и B от 0 до 1 .
grow
Метод grow
использует библиотеку Transition для увеличения размера текста. Увеличивает текст, используя свойства xScale
и yScale
. Функция onComplete
вызывается после завершения перехода.
В этой функции onComplete
мы сбрасываем свойства Text
xScale
и yScale
в 1 и отправляем событие. Причина, по которой мы отправляем событие здесь, состоит в том, чтобы сообщить игровому экрану, что Text
завершил свой переход, и, следовательно, игровой раунд окончен.
Это все станет ясно в ближайшее время, но вы можете прочитать о dispatchEvent
в документации.
setVisibility
Метод setVisibility
просто устанавливает видимость Text
зависимости от того, было ли передано значение true
или false
в качестве параметра. Мы также сбросили свойство xScale
и yScale
на 1 .
setText
Метод setText
используется для установки фактического свойства text
зависимости от того, какая строка была передана в качестве параметра.
Наконец, мы возвращаем объект growText
.
3. createWinLoseText
Функция createWinLoseText
создает объект GrowText
который будет отображать либо «ВЫ ВЫИГРЫВАЕТЕ!» или «ВЫ ПОТЕРЯЕТЕ!», в зависимости от того, выиграл пользователь или проиграл в раунде. Добавьте следующий код в gamescreen.lua .
1
2
3
4
|
function createWinLoseText()
winLoseText = growText.new( «YOU WIN»,display.contentCenterX,display.contentCenterY-100, native.systemFontBold, 20,scene.view)
winLoseText:setVisibility(false)
end
|
Мы вызываем эту функцию в scene:create
как показано ниже.
1
2
3
4
5
|
function scene:create( event )
—SNIP—
drawGallows()
createWinLoseText()
end
|
4. setupButtons
Функция setupButtons
устанавливает кнопки, выводит их на экран и добавляет прослушиватель событий, который вызовет функцию checkLetter
. Функция checkLetter
— это место, где происходит логика игры.
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
31
|
function setupButtons()
local xPos=150
local yPos = 600
for i=1, #alphabetArray do
if (i == 9 or i == 17) then
yPos = yPos + 65
xPos = 150
end
if (i == 25) then
yPos = yPos + 65
xPos = 330
end
local tempButton = widget.newButton{
label = alphabetArray[i],
labelColor = { default ={ 1,1,1}},
onPress = checkLetter,
shape=»roundedRect»,
width = 40,
height = 40,
cornerRadius = 2,
fillColor = { default={0, 0, 0, 1 }, over={ 0.5, 0.5, 0.5, 0.4 } },
strokeColor = { default={ 0.5, 0.5, 0.5, 0.4 }, over={ 0, 0, 0, 1 } },
strokeWidth = 5
}
tempButton.x = xPos
tempButton.y = yPos
xPos = xPos + 60
table.insert(gameButtons,tempButton)
end
end
|
Сначала мы устанавливаем начальные x
и y
позиции кнопок. Затем мы запускаем цикл for
alphabetArray
, который, в свою очередь, создает кнопку для каждой буквы alphabetArray
. Нам нужно восемь кнопок на строку, поэтому мы проверяем, равен ли i
9 или 17 , и, если это правда, мы увеличиваем переменную yPos
чтобы создать новую строку и вернуть xPos
в xPos
позицию. Если i
равен 25 , мы находимся в последнем ряду, и мы центрируем последние две кнопки.
Мы создаем tempButton
, используя метод newButton
класса виджета, который принимает таблицу параметров. Есть несколько способов повлиять на внешний вид кнопок. Для этой игры мы используем опцию Shape Construction . Я настоятельно рекомендую вам прочитать документацию по объекту Button, чтобы узнать больше об этих параметрах.
Мы устанавливаем label
путем индексации на onPress
и устанавливаем свойство onPress
для вызова checkLetter
. Остальные параметры связаны с визуальным оформлением и лучше объясняются при чтении документации, как упоминалось ранее. Наконец, мы вставляем tempButton
в таблицу gameButtons
чтобы мы могли ссылаться на нее позже.
Если вы теперь вызываете этот метод из scene:create
, вы должны увидеть, что кнопки нарисованы на экране. Мы пока не можем их коснуться, потому что мы не создали функцию checkLetter
. Мы сделаем это на следующем шаге.
1
2
3
4
5
6
|
function scene:create( event )
—SNIP—
createGuessWordText()
createWinLoseText()
setupButtons()
end
|
5. checkLetter
Логика игры живет в функции checkLetter
. Добавьте следующий код в gamescreen.lua .
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
31
32
33
|
function checkLetter(event)
local tempButton = event.target
local theLetter = tempButton:getLabel()
theLetter = string.lower(theLetter)
local correctGuess = false
local newGuessWord = «»
tempButton.isVisible = false
for i =1 ,#theWord do
local character= theWord:sub(i,i)
if(character == theLetter)then
guessWord[i] = theLetter
correctGuess = true
end
end
newGuessWord = table.concat(guessWord)
guessWordText.text = newGuessWord
if(correctGuess == false)then
numWrong = numWrong +1
drawHangman(numWrong);
end
if(newGuessWord == theWord)then
wonGame = true
didWinGame(true)
end
if(numWrong == 6) then
for i =1 , #theWord do
guessWord[i] = theWord:sub(i,i)
newGuessWord = table.concat(guessWord)
guessWordText.text = newGuessWord;
end
didWinGame(false)
end
end
|
Первое, что мы делаем, это получаем письмо, которое угадал пользователь, вызывая метод getLabel
для кнопки. Это возвращает label
кнопки, заглавную букву. Мы преобразуем эту букву в нижний регистр, вызывая метод lower
для string
, который принимает в качестве параметра строку для нижнего регистра.
Затем мы устанавливаем correctGuess
в false
, а newGuessWord
— в пустую строку и скрываем кнопку, которую нажал пользователь, потому что мы не хотим, чтобы пользователь мог нажимать кнопку более одного раза за раунд.
Затем мы перебираем theWord
, получаем текущий символ с помощью метода string.sub
и сравниваем этот символ с theLetter
. Если они равны, то пользователь сделал правильное предположение, и мы обновляем эту конкретную букву в guessWord
, устанавливая correctGuess
на true
Мы создаем newGuessWord
, используя метод guessWordText
, и обновляем guessWordText
чтобы отразить любые изменения.
Если correctGuess
все еще false
, это означает, что пользователь сделал неверное предположение. В результате мы увеличиваем переменную numWrong
и drawHangman
функцию drawHangman
, передавая значение numWrong
. В зависимости от того, сколько неправильных предположений сделал пользователь, функция drawHangman
будет рисовать палача соответствующим образом.
Если newGuessWord
равен theWord
, это означает, что пользователь угадал слово, а мы обновили wonGame
до true
, вызывая функцию didWinGame
и передавая true
.
Если numWrong
равно 6 , это означает, что пользователь израсходовал все свои догадки, и палач был полностью прорисован. Мы перебираем theWord
и устанавливаем каждый символ guessWord
равный символам в theWord
. Затем мы показываем пользователю правильное слово.
Этот фрагмент кода должен иметь смысл, поскольку мы уже делали нечто подобное пару раз раньше. Наконец, мы вызываем didWinGame
и передаем false
.
6. Победа и поражение
Шаг 1: didWinGame
Функция didWinGame
вызывается, когда использование либо выигрывает, либо проигрывает раунд.
01
02
03
04
05
06
07
08
09
10
11
12
|
function didWinGame(gameWon)
hideButtons()
winLoseText:setVisibility(true)
if(gameWon == true)then
winLoseText:setText(«YOU WIN!!»)
winLoseText:setColor(0,0,1)
else
winLoseText:setText(«YOU LOSE!!»)
winLoseText:setColor(1,0,0)
end
winLoseText:grow()
end
|
Первое, что мы делаем, это вызываем hideButtons
, который, как следует из названия, скрывает все кнопки. Мы устанавливаем, чтобы winLoseText
был видимым, и, в зависимости от того, выиграл пользователь или проиграл в раунде, установите его текст и цвет в зависимости от ситуации. Наконец, мы вызываем метод grow
в winLoseText
.
Как мы видели ранее в этом уроке, как только текст закончил расти, он отправляет событие. Нам нужно использовать Runtime
для прослушивания этого события. Мы будем кодировать эту функциональность на следующих этапах.
Шаг 2: Отображение и скрытие кнопок
Функции showButtons
и hideButtons
показывают и скрывают кнопки, gameButtons
таблицу gameButtons
, устанавливая видимость каждой кнопки.
01
02
03
04
05
06
07
08
09
10
11
|
function hideButtons()
for i=1, #gameButtons do
gameButtons[i].isVisible = false
end
end
function showButtons()
for i=1, #gameButtons do
gameButtons[i].isVisible = true
end
end
|
Шаг 3: drawHangman
Функция drawHangman
принимает число в качестве параметра. В зависимости от того, что это число, оно привлекает определенную часть палача.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
function drawHangman(drawNum)
if(drawNum== 0) then
drawGallows();
elseif(drawNum ==1)then
drawHead();
elseif(drawNum == 2) then
drawBody();
elseif(drawNum == 3) then
drawArm1();
elseif(drawNum == 4) then
drawArm2();
elseif(drawNum == 5) then
drawLeg1();
elseif(drawNum == 6) then
drawLeg2();
end
end
|
Шаг 4: Прогресс теста
Прошло довольно много времени с тех пор, как мы проверили наш прогресс, но если вы протестируете сейчас, вы сможете сыграть несколько раундов. Для сброса игры перейдите в « Файл»> «Перезапустить» в Corona Simulator. Помните, правильное слово выводится на консоль, так что это должно помочь вам проверить, что все работает как надо.
Когда winLoseText
закончит расти, мы начнем новый раунд. Если пользователь выиграл раунд, мы отправимся в новую сцену, где палач будет танцевать счастливым. Если пользователь проиграл, мы сбросим все в gamescreen.lua и начнем новый раунд.
Однако прежде чем мы сделаем что-либо из этого, нам нужно прослушать gameOverEvent
, который отправляется из класса growText
.
7. Игра окончена
Шаг 1: Прослушивание для gameOverEvent
Добавьте к scene:show
метод scene:show
.
1
2
3
4
5
6
|
function scene:show( event )
—SNIP—
if ( phase == «did» ) then
Runtime:addEventListener( «gameOverEvent», gameOver )
end
end
|
Мы передаем gameOverEvent
в качестве первого аргумента метода addEventListener
. Когда gameOverEvent
, gameOver
функция gameOver
.
Мы должны также удалить слушателя события в некоторый момент. Мы делаем это в методе scene:hide
как показано ниже.
1
2
3
4
5
6
|
function scene:hide( event )
local phase = event.phase
if ( phase == «will» ) then
Runtime:removeEventListener( «gameOverEvent», gameOver )
end
end
|
Шаг 2: gameOver
Добавьте следующий код в gamescreen.lua .
1
2
3
4
5
6
7
8
|
function gameOver()
winLoseText:setVisibility(false)
if(wonGame == true)then
composer.gotoScene(«gameoverscreen»)
else
newGame()
end
end
|
Если пользователь выиграл игру, мы gotoScene
метод gotoScene
для объекта composer
и переходим на экран игры . Если нет, мы вызываем метод newGame
, который сбрасывает игру и создает новое слово.
Шаг 3: newGame
Функция newGame
сбрасывает некоторые переменные, устанавливает видимость кнопок, очищает hangmanGroup
и создает новое слово.
1
2
3
4
5
6
7
|
function newGame()
clearHangmanGroup()
drawHangman(0)
numWrong = 0
guessWordText.text = createGuessWord()
showButtons()
end
|
Большая часть этого кода должна выглядеть вам знакомой. Функция clearHangmanGroup
— единственная новинка, и мы рассмотрим эту функцию на следующем шаге.
Шаг 4: clearHangmanGroup
clearHangmanGroup
просто перебирает hangmanGroup
numChildren
и удаляет их. По сути, мы все очищаем, чтобы начать рисовать заново.
1
2
3
4
5
|
function clearHangmanGroup()
for i = hangmanGroup.numChildren, 1 ,-1 do
hangmanGroup[i]:removeSelf()
hangmanGroup[i]=nil
end
|
Шаг 5: Прогресс теста
Мы находимся в точке, где мы можем проверить прогресс еще раз. Если вы протестируете игру, вы можете проиграть, и новая игра должна начаться. Вы можете делать это столько, сколько пожелаете. На следующем этапе мы настроим игровой экран .
8. Игра закончена
Создайте новый файл gameoverscreen.lua и добавьте в него следующий код.
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
local composer = require( «composer» )
local scene = composer.newScene()
local hangmanSprite
local hangmanAudio
function scene:create( event )
local group = self.view
drawChalkBoard()
local options = { width = 164,height = 264,numFrames = 86}
local hangmanSheet = graphics.newImageSheet( «hangmanSheet.png», options )
local sequenceData = {
{ start=1, count=86, time=8000, loopCount=1 }
}
hangmanSprite = display.newSprite( hangmanSheet, sequenceData )
hangmanSprite.x = display.contentCenterX
hangmanSprite.y = display.contentCenterY
hangmanSprite.xScale = 1.5
hangmanSprite.yScale = 1.5
group:insert(hangmanSprite)
end
function scene:show( event )
local phase = event.phase
local previousScene = composer.getSceneName(«previous»)
composer.removeScene(previousScene)
if ( phase == «did» ) then
hangmanSprite:addEventListener( «sprite», hangmanListener )
hangmanSprite:play()
hangmanAudio = audio.loadSound( «danceMusic.mp3» )
audio.play(hangmanAudio)
end
end
function scene:hide( event )
local phase = event.phase
if ( phase == «will» ) then
hangmanSprite:removeEventListener( «sprite», hangmanListener )
audio.stop(hangmanAudio)
audio.dispose(hangmanAudio)
end
end
function drawChalkBoard()
local chalkBoard = display.newRect( 0, 0, display.contentWidth, display.contentHeight )
chalkBoard:setFillColor(1,1,1 )
chalkBoard.anchorX = 0
chalkBoard.anchorY = 0
scene.view:insert(chalkBoard)
end
function hangmanListener( event )
if ( event.phase == «ended» ) then
timer.performWithDelay(1000,newGame,1)
end
end
function newGame()
composer.gotoScene(«gamescreen»)
end
scene:addEventListener( «create», scene )
scene:addEventListener( «show», scene )
scene:addEventListener( «hide», scene )
return scene
|
hangmanSprite
— это SpriteObject
который будет использоваться для танцевальной анимации. hangmanAudio
— это AudioObject
который будет использоваться для воспроизведения музыки во время танца палача.
Шаг 1: Анимация Палача
Как я уже упоминал, hangmanSprite
— это экземпляр SpriteObject
и если hangmanSprite
будет спрайтом вместо обычного изображения, мы можем его анимировать. hangmanSprite
имеет 86 отдельных изображений, каждое из которых представляет собой отдельный кадр для анимации. Вы можете увидеть это, открыв hangmanSheet.png в графическом редакторе.
Таблица параметров содержит width
, height
и количество numFrames
отдельных изображений в увеличенном изображении. Переменная numFrames
содержит значение числа меньших изображений. hangmanSheet
является экземпляром объекта ImageSheet
, который принимает в качестве параметров изображение и таблицу параметров.
Переменная sequenceData
используется экземпляром SpriteObject
, ключ start
— это изображение, с которого вы хотите запустить последовательность или анимацию, а ключ count
— это общее количество изображений в анимации. Клавиша time
показывает, сколько времени потребуется для воспроизведения анимации, а клавиша loopCount
— сколько раз вы хотите, чтобы анимация воспроизводилась или повторялась.
Наконец, вы создаете экземпляр SpriteObject
, передавая экземпляр ImageSheet
и sequenceData
.
Мы устанавливаем hangmanSprite
x
и y
hangmanSprite
и масштабируем его до 1,5 по сравнению с его обычным размером, используя свойства xScale
и yScale
. Мы вставляем его в group
чтобы убедиться, что он удаляется при удалении scene
.
Шаг 2. Воспроизведение аудио
Внутри scene:show
, мы удаляем предыдущую сцену, добавляем прослушиватель событий в hangmanSprite
и вызываем его метод play
. Мы создаем экземпляр hangmanAudio
, вызывая метод loadSound
, передавая danceMusic.mp3 . Наконец, мы вызываем метод play
чтобы начать воспроизведение звука.
В методе scene:hide
мы удаляем прослушиватель событий из hangmanSprite
, вызываем stop
для экземпляра аудио и вызываем метод hangmanSprite
. Метод dispose
обеспечивает освобождение памяти, выделенной для экземпляра audio
.
Шаг 3: Очистка
В hangmanListener
мы проверяем, находится ли он в end
фазе, и, если true, это означает, что анимация закончилась. Затем мы вызываем timer.performWithDelay
. Таймер срабатывает через одну секунду, вызывая метод newGame
, который использует composer для перехода обратно на игровой экран, чтобы начать новую игру.
Вывод
Это был довольно длинный урок, но теперь у вас есть функциональная игра-палач с приятным поворотом. Как уже упоминалось в начале этого урока, попробуйте включить уровни сложности. Одним из вариантов будет иметь экран параметров и реализовать SegmentedControl
где пользователь может выбирать между списками из 5, 9 и 13 букв слова.
Я надеюсь, что вы нашли этот урок полезным и узнали что-то новое. Спасибо за прочтение.