Статьи

Corona SDK: создание игры с алфавитным супом — Взаимодействие

Это вторая часть нашего учебника Corona SDK Alphabet Soup Game. В сегодняшнем уроке мы добавим наш интерфейс и начнем программировать взаимодействие с игрой. Читай дальше!


Объявите все функции как локальные в начале.

01
02
03
04
05
06
07
08
09
10
11
12
local Main = {}
local addTitleView = {}
local startBtnuttonListeners = {}
local showCredits = {}
local hideCredits = {}
local showGameView = {}
local gameListeners = {}
local buildSoup = {}
local startDraw = {}
local hitTestObjects = {}
local detectLetters = {}
local alert = {}

Далее мы создадим функцию, которая будет инициализировать всю игровую логику:

1
2
3
function Main()
    addTitleView()
end

Теперь мы помещаем TitleView в сцену и вызываем функцию, которая добавит прослушиватели касаний к кнопкам.

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 addTitleView()
    titleBg = display.newImage(‘titleBg.png’)
     
    title = display.newImage(‘title.png’)
    title.x = display.contentCenterX
    title.y = 120
     
    startBtn = display.newImage(‘startBtn.png’)
    startBtn.x = display.contentCenterX
    startBtn.y = display.contentCenterY + 20
     
    aboutBtn = display.newImage(‘aboutBtn.png’)
    aboutBtn.x = display.contentCenterX
    aboutBtn.y = display.contentCenterY + 65
     
    titleView = display.newGroup()
    titleView:insert(titleBg)
    titleView:insert(title)
    titleView:insert(startBtn)
    titleView:insert(aboutBtn)
     
    startButtonListeners(‘add’)
end
end

Эта функция добавляет необходимых слушателей к кнопкам TitleView .

1
2
3
4
5
6
7
8
9
function startButtonListeners(action)
    if(action == ‘add’) then
        aboutBtn:addEventListener(‘tap’, showCredits)
        startBtn:addEventListener(‘tap’, showGameView)
    else
        aboutBtn:removeEventListener(‘tap’, showCredits)
        startBtn:removeEventListener(‘tap’, showGameView)
    end
end

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

1
2
3
4
5
6
7
8
9
function showCredits:tap()
    aboutBtn.isVisible = false
    startBtn.isVisible = false
    about = display.newImage(‘about.png’)
    about.x = about.width * 0.474
    about.y = display.contentHeight + about.height
 
    transition.to(about, {time = 300, y = display.contentHeight — about.height/2.4, onComplete = function() about:addEventListener(‘tap’, hideCredits) end})
end

При нажатии на экран кредитов, он будет отключен со сцены и удален.

1
2
3
function hideCredits()
    transition.to(about, {time = 300, y = display.contentHeight+about.height, onComplete = function() aboutBtn.isVisible = true startBtn.isVisible = true about:removeEventListener(‘tap’, hideCredits) display.remove(about) about = nil end})
end

При нажатии кнопки « Пуск» вид заголовка изменяется и удаляется, открывая вид игры.

1
2
3
function showGameView:tap()
    transition.to(titleView, {time = 300, y = -titleView.height, onComplete = function() display.remove(titleView) titleView = nil buildSoup() gameListeners(‘add’) end})
end

Этот код добавляет прослушиватели касаний к фону игры, и они будут использоваться для рисования линии выделения и идентификации выбранных букв.

01
02
03
04
05
06
07
08
09
10
function gameListeners(action)
     
    if(action == ‘add’) then
        gameBg:addEventListener(‘touch’, startDraw)
        gameBg:addEventListener(‘touch’, detectLetters)
    else
        gameBg:removeEventListener(‘touch’, startDraw)
        gameBg:removeEventListener(‘touch’, detectLetters)
    end
end

Одна из основных функций игры; при этом будет просмотр таблицы Map для создания всех текстовых полей и их размещения на этапе, перейдите к следующему шагу, чтобы увидеть его поведение.

1
2
3
function buildSoup()
    — Code…
end

Двойной for используется для идентификации элементов в таблице Map, один для горизонтальных значений и один для вертикальных. Код создаст текстовое поле для каждого значения, найденного в таблице, а затем разместит их на сцене.

1
2
3
4
5
6
7
8
for i = 1, 10 do
        for j = 1, 12 do
            local tf = display.newText(», 0, 0, ‘Arial’, 19)
            tf:setTextColor(102, 102, 102)
            tf.width = 22
            tf.height = 21
            tf.x = math.floor(-10 + (31.3 * i))
            tf.y = math.floor(-10 + (35 * j))

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

1
2
3
4
5
6
7
8
9
— Change 0’s to Random Letters
            if(L1Map[j][i] == 0) then
                L1Map[j][i] = alphabet[math.floor(math.random() * table.maxn(alphabet))+1]
            end
     
            tf.text = L1Map[j][i]
            tfs:insert(tf)
        end
    end

Этот код создает два текстовых поля, которые будут содержать список значений для поиска и уже найденные значения.

01
02
03
04
05
06
07
08
09
10
11
12
13
— Add Words List
     
    local wordsString = »
     
    for i = 1, #L1 do
        wordsString = wordsString .. ‘ ‘ .. L1[i]
    end
     
    wordsList = display.newText(wordsString, 5, 430, ‘Arial’, 14)
    wordsList:setTextColor(238, 238, 238)
     
    currentWords = display.newText(», 5, 455, ‘Arial’, 14)
    currentWords:setTextColor(238, 146, 63)

Полупрозрачная линия будет использоваться для выделения букв на сцене, в следующей функции эта строка будет создана и добавлена ​​на сцену.

1
function startDraw:touch(e) if(e.phase == ‘began’) then initX = ex initY = ey elseif(e.phase == ‘ended’) then line = display.newLine(initX, initY, ex, ey) line.width = 16 line:setColor(255, 142, 42, 60) lines:insert(line) end end

Вот полный код, написанный в этом руководстве вместе с комментариями, чтобы помочь вам идентифицировать каждую часть:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
— Alphabet Soup Game
— Developed by Carlos Yanez
 
— Hide Status Bar
 
display.setStatusBar(display.HiddenStatusBar)
 
— Graphics
— [Background]
 
— [Game Background]
 
local gameBg = display.newImage(‘bg.png’)
 
— [Title View]
  
local titleBg
local title
local startBtn
local aboutBtn
 
— [TitleView Group]
 
local titleView
 
— [CreditsView]
 
local about
 
— [Words List Textfield]
 
local wordsList
local currentWords
 
— [Letter Texfields Container]
 
local tfs = display.newGroup()
 
— [Selection Line]
 
local line
local lines = display.newGroup()
 
— [Alert]
 
local alert
 
— [Sound]
 
local bell = audio.loadStream(‘bell.caf’)
 
— Variables
 
local L1 = {‘IPHONE’, ‘ANDROID’, ‘CORONA’, ‘MOBILE’, ‘GAMES’}
local L1Map = {{0, 0, ‘I’, 0, 0, 0, ‘G’, 0, 0, 0},
               {0, 0, ‘P’, 0, 0, 0, ‘A’, 0, 0, 0},
               {0, 0, ‘H’, 0, 0, 0, ‘M’, 0, 0, 0},
               {0, ‘M’, ‘O’, ‘B’, ‘I’, ‘L’, ‘E’, 0, 0, 0},
               {0, 0, ‘N’, 0, 0, 0, ‘S’, 0, 0, 0},
               {0, 0, ‘E’, 0, 0, 0, 0, 0, 0, 0},
               {‘C’, ‘O’, ‘R’, ‘O’, ‘N’, ‘A’, 0, 0, 0, 0},
               {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
               {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
               {0, 0, ‘A’, ‘N’, ‘D’, ‘R’, ‘O’, ‘I’, ‘D’, 0},
               {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
               {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
 
local alphabet = {‘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 correct = 0
 
— Functions
 
local Main = {}
local addTitleView = {}
local startBtnuttonListeners = {}
local showCredits = {}
local hideCredits = {}
local showGameView = {}
local gameListeners = {}
local buildSoup = {}
local startDraw = {}
local hitTestObjects = {}
local detectLetters = {}
local alert = {}
 
function Main()
    addTitleView()
end
 
function addTitleView()
    titleBg = display.newImage(‘titleBg.png’)
     
    title = display.newImage(‘title.png’)
    title.x = display.contentCenterX
    title.y = 120
     
    startBtn = display.newImage(‘startBtn.png’)
    startBtn.x = display.contentCenterX
    startBtn.y = display.contentCenterY + 20
    —startBtn.name = ‘startBtn’
     
    aboutBtn = display.newImage(‘aboutBtn.png’)
    aboutBtn.x = display.contentCenterX
    aboutBtn.y = display.contentCenterY + 65
    —aboutBtn.name = ‘aboutBtn’
     
    titleView = display.newGroup()
    titleView:insert(titleBg)
    titleView:insert(title)
    titleView:insert(startBtn)
    titleView:insert(aboutBtn)
     
    startButtonListeners(‘add’)
end
 
function startButtonListeners(action)
    if(action == ‘add’) then
        aboutBtn:addEventListener(‘tap’, showCredits)
        startBtn:addEventListener(‘tap’, showGameView)
    else
        aboutBtn:removeEventListener(‘tap’, showCredits)
        startBtn:removeEventListener(‘tap’, showGameView)
    end
end
 
function showCredits:tap()
    aboutBtn.isVisible = false
    startBtn.isVisible = false
    about = display.newImage(‘about.png’)
    about.x = about.width * 0.474
    about.y = display.contentHeight + about.height
 
    transition.to(about, {time = 300, y = display.contentHeight — about.height/2.4, onComplete = function() about:addEventListener(‘tap’, hideCredits) end})
end
 
function hideCredits()
    transition.to(about, {time = 300, y = display.contentHeight+about.height, onComplete = function() aboutBtn.isVisible = true startBtn.isVisible = true about:removeEventListener(‘tap’, hideCredits) display.remove(about) about = nil end})
end
 
function showGameView:tap()
    transition.to(titleView, {time = 300, y = -titleView.height, onComplete = function() display.remove(titleView) titleView = nil buildSoup() gameListeners(‘add’) end})
end
 
function gameListeners(action)
     
    if(action == ‘add’) then
        gameBg:addEventListener(‘touch’, startDraw)
        gameBg:addEventListener(‘touch’, detectLetters)
    else
        gameBg:removeEventListener(‘touch’, startDraw)
        gameBg:removeEventListener(‘touch’, detectLetters)
    end
end
 
function buildSoup()
    for i = 1, 10 do
        for j = 1, 12 do
            local tf = display.newText(», 0, 0, ‘Arial’, 19)
            tf:setTextColor(102, 102, 102)
            tf.width = 22
            tf.height = 21
            tf.x = math.floor(-10 + (31.3 * i))
            tf.y = math.floor(-10 + (35 * j))
     
            — Change 0’s to Random Letters
     
            if(L1Map[j][i] == 0) then
                L1Map[j][i] = alphabet[math.floor(math.random() * table.maxn(alphabet))+1]
            end
     
            tf.text = L1Map[j][i]
            tfs:insert(tf)
        end
    end
     
    — Add Words List
     
    local wordsString = »
     
    for i = 1, #L1 do
        wordsString = wordsString .. ‘ ‘ .. L1[i]
    end
     
    wordsList = display.newText(wordsString, 5, 430, ‘Arial’, 14)
    wordsList:setTextColor(238, 238, 238)
     
    currentWords = display.newText(», 5, 455, ‘Arial’, 14)
    currentWords:setTextColor(238, 146, 63)
end
 
function startDraw:touch(e)
    if(e.phase == ‘began’) then
        initX = ex
        initY = ey
    elseif(e.phase == ‘ended’) then
        line = display.newLine(initX, initY, ex, ey)
        line.width = 16
        line:setColor(255, 142, 42, 60)
        lines:insert(line)
    end
end

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