Статьи

Создайте игру сурка — логика геймплея

В этой серии уроков мы создадим игру Whack-a-Groundhog. Цель игры — стучать по суркам до того, как они исчезнут. Читай дальше!


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


Как и сейчас, сурки оживляют вечно и, похоже, не возвращаются обратно в свои норы. Нам нужно добавить еще несколько ключей в нашу sequenceData чтобы это исправить. Добавьте следующее в setupGameScreen() :

1
2
3
4
5
6
7
local sequenceData = {
    {name=»show», start=2 , count = 3,time=800,loopCount=1,loopDirection=»bounce»},
    {name = «blank»,start=1,count=1},
    {name = «hit1»,start=5,count=1},
    {name = «hit2», start=6,count=1},
    {name = «hit3», start=7,count=1}
}

«Пустая» последовательность представляет собой пустое прозрачное изображение, которое является частью листа спрайта, а последовательности «hit1», «hit2» и «hit3» представляют собой 3 различных состояния «попадания» сурка. Посмотрите на изображение «groundhogsheet.png», чтобы убедиться в этом.

Убедитесь, что вы установили loopCount равным 1 в последовательности «show».

Теперь измените следующий блок кода:

1
2
tempGroundHog:setSequence(«blank»)
tempGroundHog:addEventListener(‘tap’, groundHogHit);

Здесь мы установили последовательность как «пустую» и добавили прослушиватель касаний к спрайту сурка.

Затем удалите следующую строку кода:

1
tempGroundHog:play()

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


Когда сурка постукивают, мы определим, было ли оно вне его отверстия. Если это так, мы изменим его последовательность на одно из трех состояний попадания, которые мы добавили на предыдущем шаге.

Добавьте следующее в groundHogHit() :

01
02
03
04
05
06
07
08
09
10
local thisSprite = e.target
thisSprite:removeEventListener( «sprite», groundHogSpriteListener )
    local function hide()
        thisSprite:setSequence(«blank»)
    end
    if(thisSprite.sequence == «show») then
        local randomIndex = math.random(3)
    thisSprite:setSequence(«hit»..randomIndex)
    timer.performWithDelay(1000, hide)
    end

Здесь мы e.target на Sprite, на который нажал e.target и удалим e.target событий. Затем мы проверяем, равна ли его последовательность «show». Если это так, мы генерируем число от 1 до 3 и устанавливаем его последовательность равной "hit"..randomIndex . Все, что это делает, это генерирует строки «hit1», «hit2» или «hit3». Наконец, мы вызываем локальную функцию hide через 1000 миллисекунд, которая устанавливает последовательность Sprites в «пустое».


Функция getRandomGroundHog() получает случайного сурка и позволяет ему начать анимацию. Введите следующее внутри функции getRandomGroundHog() function :

1
2
3
4
5
6
7
8
9
local randomIndex = math.random(#allGroundHogs)
    local randomGroundHog = allGroundHogs[randomIndex]
    if(randomGroundHog.sequence ~=»blank») then
         getRandomGroundHog()
    else
        randomGroundHog:addEventListener( «sprite»,groundHogSpriteListener )
    randomGroundHog:setSequence(«show»)
    randomGroundHog:play()
    end

Здесь мы получаем randomIndex из таблицы allGroundHogs . Далее мы устанавливаем randomGroundHog равным индексу. Затем мы проверяем, не равна ли его последовательность «пустым», и, если это не так, мы снова вызываем getRandomGroundHog() . В противном случае мы добавляем groundHogSpriteListener чтобы установить его последовательность в «show» и воспроизводить последовательность.


groundHogSpriteListener() проверяет, закончилась ли последовательность «show». Если это так, он устанавливает его в «пустую» последовательность. Введите следующее в groundHogSpriteListener() :

1
2
3
4
5
6
local thisSprite = event.target —«event.target» references the sprite
    if ( event.phase == «ended» ) then
        if(thisSprite.sequence == «show») then
            thisSprite:setSequence(«blank»)
        end — a half second delay
    end

С учетом всего вышесказанного мы получаем случайных анимированных сурков. Добавить следующее в нижней части
setUpGameScreen() :

1
groundHogTimer = timer.performWithDelay(groundHogSpeed, getRandomGroundHog,0)

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

Когда вы закончите тестирование, удалите только что введенную строку. Нам это нужно было только для тестирования.


На этом этапе мы начнем настраивать заставку. Введите следующий код внутри функции setUpIntroScreen :

1
2
3
4
5
6
7
8
media.playSound(«gameTrack.mp3»,soundComplete)
introScreenGroup = display.newGroup()
local titleScreen = display.newImage(«titleScreen.png»)
local playButton = display.newImage(«playButton.png»,100,100)
local optionsButton = display.newImage(«optionsButton.png»,100,170)
introScreenGroup:insert(titleScreen)
introScreenGroup:insert(playButton)
introScreenGroup:insert(optionsButton)

Здесь мы запускаем саундтрек, настраиваем заставку и добавляем playButton и optionsButton .

Теперь вызовите setUpIntroScreen() ниже которой вы вызываете setUpGameScreen() .

1
2
setUpGameScreen()
setUpIntroScreen()

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


Введите следующее под кодом, который вы ввели на шаге выше:

1
2
3
4
5
6
7
8
playButton:addEventListener(«tap»,function ()
    transition.to(introScreenGroup, {time = 300, x = -480, onComplete = function()
        groundHogTimer = timer.performWithDelay(groundHogSpeed, getRandomGroundHog,0)
     end
     })
    isPlaying = true
end
)

Когда кнопка воспроизведения нажата, мы анимируем заставку слева, устанавливаем наш groundHogTimer для генерации случайных сурков, а затем устанавливаем для переменной isPlaying значение true.

Если вы проведете тестирование сейчас, вы сможете запустить новую игру, но мы хотели бы, чтобы некоторые опции были также доступны. Мы сделаем это дальше.


Введите следующее под кодом, который вы ввели на шаге выше.

1
2
3
4
5
6
7
optionsButton:addEventListener(«tap», function()
    transition.to(optionsScreenGroup, {time = 300, y = 0, onComplete = function()
         introScreenGroup.
    end
    })
end
)

Этот код анимирует экран опций сверху вниз. Когда анимация завершена, она выводит introScreenGroup с основного экрана влево.

Если вы протестируете сейчас и нажмете кнопку параметров, вы ничего не увидите, потому что мы еще не создали экран параметров.


Введите следующее внутри функции setUpOptionsScreen() :

01
02
03
04
05
06
07
08
09
10
optionsScreenGroup = display.newGroup()
    local optionsScreen = display.newImage(«optionsScreen.png»)
    local backButton = display.newImage(«backButton.png»,130,240)
    local soundOnText = display.newText( «Sound On/Off», 75,105, native.systemFontBold, 16 )
    local groundHogSpeedText = display.newText(«Speed», 75,145,native.systemFontBold,16)
    optionsScreenGroup:insert(optionsScreen)
    optionsScreenGroup:insert(backButton)
    optionsScreenGroup:insert(soundOnText)
    optionsScreenGroup:insert(groundHogSpeedText)
    optionsScreenGroup.y = -325

Здесь мы настраиваем optionsScreen , добавляем backButton и добавляем пару текстов.

Теперь вызовите эту функцию, где вы вызываете setUpIntroScreen :

1
2
setUpIntroScreen()
setUpOptionsScreen()

Если вы тестируете игру сейчас, вы должны увидеть экран опций, скользящий сверху вниз.


Мы будем использовать виджет флажка, чтобы позволить пользователю включать / выключать звук. Введите следующее в самом верху файла «main.lua».

1
local widget = require( «widget» )

Чтобы иметь возможность использовать Switch и другие виджеты, мы должны сначала потребовать модуль «widget»

Теперь введите следующее под кодом, который вы ввели выше в setUpOptionsScreen .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
local soundCheckBox = widget.newSwitch
{
   left = 210,
   top = 98,
   style = «checkbox»,
   initialSwitchState = true,
   onPress = function(e)
    local check = e.target
    if(check.isOn) then
        media.playSound(«gameTrack.mp3»,soundComplete)
    else
      media.stopSound()
    end
   end
}
optionsScreenGroup:insert(soundCheckBox)

Это устанавливает наш виджет-флажок, устанавливая «style» равным «checkbox». Мы проверяем, установлен ли флажок (если он установлен), и если это так, мы играем в «gameTrack.mp3». Если нет, мы прекращаем звук.

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


Мы используем SegmentedControl, чтобы позволить пользователю выбирать, как быстро должны появляться GroundHogs. Введите следующее под кодом для флажка, который вы ввели на шаге выше:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
local speedControl = widget.newSegmentedControl
{
   left = 210,
   top = 140,
   segments = { «slow», «medium», «fast»},
   segmentWidth = 50,
   defaultSegment = 1,
   onPress = function(event)
    local target = event.target
        if(target.segmentNumber == 1)then
            groundHogSpeed = 1500
        elseif (target.segmentNumber == 2)then
            groundHogSpeed = 1000
        else
            groundHogSpeed = 700
        end
   end
}
 
optionsScreenGroup:insert(speedControl)

Здесь мы создаем SegmentedControl с 3 сегментами («медленный», «средний», «быстрый»). В зависимости от того, какой сегмент нажал пользователь, мы соответственно устанавливаем переменную groundHogSpeed .

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


backButton возвращает нас к backButton экрану. Введите следующий код под вышеуказанным шагом:

01
02
03
04
05
06
07
08
09
10
11
12
backButton:addEventListener(«tap», function()
    if(isPlaying == false)then
        introScreenGroup.x = 0
     end
     transition.to(optionsScreenGroup, {time = 300, y = -325, onComplete = function()
         if(isPlaying == true) then
         groundHogTimer = timer.performWithDelay(groundHogSpeed, getRandomGroundHog,0)
      end
     end
     })
end
)

Здесь мы проверяем, началась ли игра. Если нет, мы помещаем introScreenGroup обратно в игровую зону. Затем мы возвращаем экран настроек обратно. Если игра началась, мы устанавливаем groundHogtimer для генерации случайных сурков.


Нам нужно иметь возможность попасть на экран настроек с основного экрана игры. Добавьте следующее ниже, куда вы вставляете gameBackground в gameScreenGroup() .

1
2
3
gameScreenGroup:insert(gameBackground)
local optionsButton = display.newImage(«optionsButton.png»,1,270)
gameScreenGroup:insert(optionsButton)

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

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

1
2
3
4
5
6
7
8
optionsButton:addEventListener(«tap», function(e)
    timer.cancel(groundHogTimer)
    transition.to(optionsScreenGroup, {time = 300, y = 0, onComplete = function()
 
    end
    })
end
)

Здесь мы отменяем groundHogTimer и groundHogTimer наш экран настроек вниз.

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


Если вы играли достаточно долго, чтобы закончить саундтрек, возможно, вы заметили, что он не начинается заново. Введите следующее в soundComplete() .

1
media.playSound( «gameTrack.mp3», soundComplete )

Это только начинает воспроизведение саундтрека после его завершения.


В этой серии мы узнали, как создать веселую и интересную игру Whack-a-Groundhog. При этом вы узнали, как использовать спрайт-листы и звук. Я надеюсь, что вы нашли этот урок полезным, и спасибо за чтение!