Advertisement
  1. Code
  2. Corona SDK

Создайте игру Endless Runner / бесконечно бегущий человечек с нуля: Меню игры 

Scroll to top
Read Time: 10 min
This post is part of a series called Corona SDK: Build an Endless Runner Game From Scratch.
Build an Endless Runner Game From Scratch: Boss Battles
Build an Endless Runner Game From Scratch: App Store Publishing

() translation by (you can also view the original English article)

Добро пожаловать в последнюю версию серии Endless Runner. В сегодняшнем уроке  вы узнаете, как создавать игровое меню с помощью класса Director. Давайте начнем!

Поздравляем вас с этим знаменательным событием! Мы долго шли к этому дню, и теперь у нас есть   функциональная игра и, надеюсь, базовое понимание того, как добавить свои собственные компоненты для расширения функционала. Шаг, который мы собираемся сделать сейчас, - это добавить маленький уровень в систему меню, чтобы игра выглядела более полноценной.

Мы будем  использовать Director класс, который представляет собой небольшую, и одновременно, профессиональную библиотеку Рикардо Раубера, которая будет делать всю работу за вас. Как только вы увидите, насколько это легко, вы сможете быстро реализовать свои самые интересные идеи.

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

Теперь, когда у нас есть файл director.lua, поместите его в ту же папку, что и ваш main.lua. Говоря о файле main.lua, перейдите к нему и переименуйте. Неважно, какое имя вы ему присвоите, т.к. мы все равно его позже удалим. После этого создайте три новых файла в этой папке. И назовите их main.lua, menu.lua и game.lua. Суть того, как это будет работать, в том, что main.lua будет вызван для запуска игры. Это будет основой нашей программы, в то время как menu.lua и game.lua будут выступать в качестве компонентов (displayGroups), которые отображаются вместе с displayGroup внутри main.lua, почти так же, как и все другие группы в нашей игре, все они содержатся и отображаются на экране displayGroup в нашей текущей игре.

Итак, во-первых, давайте создадим новый файл main.lua. Откройте его и вставьте этот код:

1
2
display.setStatusBar(display.HiddenStatusBar)
3
--by telling Corona to require "director" we are
4
--telling it to include everything in that file,
5
--giving us easy access to its functions. This is
6
--also how you would include any functions or
7
--"classes" that you created in outside files.
8
local director = require("director")
9
local mainGroup = display.newGroup()
10
local main = function()
11
     --this creates a view that we will use to load
12
     --the other scenes into, so as our game progresses
13
     --technically we are staying in the main.lua file
14
     --and just loading new views or scenes into it
15
     mainGroup:insert(director.directorView)
16
     --we tell the director to load the first scene which
17
     --is going to be the menu
18
     director:changeScene("menu")
19
end
20
--be sure to actually call the main function
21
main()

Вот и все! Уберите комментарии, и вы увидите, что для запуска director класса требуется всего 5 строк. Как говорится в комментариях, способ, который действительно работает, - main.lua запускается первым, но затем вместо того, чтобы процесс игры был определён в файле main.lua, мы разрешаем классу сделать это. Мы создаем display.newGroup и сохраняем его как основной вид. Поэтому, когда игра действительно загружается, все, что вы видите, фактически просматривается из файла main.lua внутри этой группы. Здорово, не так ли! Итак, как только вы создаёте представление, нам просто нужно сказать классу Director, что сцена будет загружена, и он автоматически перенесёт нас туда. Удобно, правда?

Следующее, что нам нужно сделать, чтобы на самом деле все работало, - создать вид меню. Код действительно прост, большинство которого мы уже видели, поэтому я сначала опубликую весь файл, а затем объясню несколько простых вещей. Давайте откроем menu.lua и посмотрим, как легко создать простую систему меню. Скопируйте следующее в меню menu.lua:

1
2
--this line is required so that director knows that
3
--this is a scene that can be loaded into its view
4
module(..., package.seeall)
5
--we need to be able to access the director class of
6
--course so be sure to include this here
7
local director = require("director")
8
local sprite = require("sprite")
9
--everything that you want this scene to do should be
10
--included in the new function. Everytime the director
11
--loads a new scene it will look here to figure out what
12
--to load up.
13
new = function( params )
14
     --this function will be returned to the director
15
     local menuDisplay = display.newGroup()
16
     --everything from here down to the return line is what makes
17
     --up the scene so... go crazy
18
     local background = display.newImage("background.png")
19
     background.x = 240
20
     background.y = 160
21
     local spriteSheet = sprite.newSpriteSheet("monsterSpriteSheet.png", 100, 100)
22
     local monsterSet = sprite.newSpriteSet(spriteSheet, 1, 7)
23
     sprite.add(monsterSet, "running", 1, 6, 600, 0)
24
     local monster = sprite.newSprite(monsterSet)
25
     monster:prepare("running")
26
     monster:play()
27
     monster.x = 60
28
     monster.y = 200
29
     local monster2 = sprite.newSprite(monsterSet)
30
     monster2:prepare("running")
31
     monster2:play()
32
     monster2.x = 420
33
     monster2.y = 200
34
     monster2.xScale = monster2.xScale * -1
35
     local title = display.newImage("title.png")
36
     title.x = 240
37
     title.y = 80
38
     local playButton = display.newImage("playButton.png")
39
     playButton.x = 240
40
     playButton.y = 220
41
     menuDisplay:insert(background)
42
     menuDisplay:insert(monster)
43
     menuDisplay:insert(monster2)
44
     menuDisplay:insert(title)
45
     menuDisplay:insert(playButton)
46
     --this is what gets called when playButton gets touched
47
     --the only thing that is does is call the transition
48
     --from this scene to the game scene, "downFlip" is the
49
     --name of the transition that the director uses
50
     local function buttonListener( event )
51
          director:changeScene( "game", "downFlip" )
52
          return true
53
     end
54
     --this is a little bit different way to detect touch, but it works
55
     --well for buttons. Simply add the eventListener to the display object
56
     --that is the button send the event "touch", which will call the function
57
     --buttonListener everytime the displayObject is touched.
58
     playButton:addEventListener("touch", buttonListener )
59
     --return the display group at the end
60
     return menuDisplay
61
end

Здесь есть и кое-что новое director: changeScene(). Это работает так, как вы себе это представляете. Тем не менее, я хотел указать на второй параметр - downFlip. Есть много встроенных переходов, которые могут сделать вашу игру очень привлекательной при переключении между сценами, это зависит от того, как вы хотите, чтобы ваша игра выглядела. Вот образец нашего прогресса.

TransitionTransitionTransition

Не забудьте попробовать несколько разных переходов, чтобы найти тот, который лучше всего подходит для вашей игры. Вы можете найти их полный список в файле director.lua. Посмотрите все различные эффекты и дайте своим идеям волю. Еще несколько примеров, которые вы можете попробовать, но не хотите далеко копать, - это crossfade", "overfromtop", и "flipFromBottom, и это лишь некоторые из них! Итак, кроме этого, осталось совсем немного того, чего вы не видели раньше. Все это просто создаёт примитивный экран главного меню. Там есть пара вещей, которые вы должны принять к сведению, что потребуется в каждой сцене, которая нужна director. Первое:

1
2
module(..., package.seeall)

Легко и просто. Вам нужно, чтобы точная строка в верхней части каждого файла *.lua, а именно director использовалась в качестве сцены. После этого у вас есть функция new(), которая вызывается при входе в сцену, и все, что вы хотите, чтобы сцена выполняла, это была включенной. Первое, что вам нужно сделать, это отобразить Object, который будет возвращен к управляющему классу, который и будет показан, а затем убедитесь что он вернул значение в конце новой функции. Это всё. Звучит просто? Это действительно так! Класс director действительно делает все проще. Пока ваши изображения находятся справа в меню, вы должны запустить файл main.lua и запустим его без каких-либо проблем.

До сих пор у нас был основной файл и файл меню. Последнее, что нам нужно сделать, это внести некоторые изменения в игровой файл. Это тоже будет легко. Откройте файл game.lua и добавьте следующий код:

1
2
module(..., package.seeall)
3
local director = require("director")
4
new = function( params )
5
  local gameDisplay = display.newGroup()
6
	--paste code here
7
	return gameDisplay
8
end

Это то, что вам нужно для сцены. Кстати, это все, что вам нужно, чтобы получить ваш старый файл main.lua в файл game.lua. Если он у вас уже есть, единственное, что вам нужно сделать, это скопировать весь файл old.lua и вставить его там, где сказано «вставить код здесь». Сделайте это, и вы закончили… .почти! Мы собираемся внести некоторые изменения в то, как будет отображаться наша игра над сообщениями. Вместо того, чтобы создавать большую кнопку, мы возвращаемся в меню. Давайте изменим здесь кое-что (обратите внимание, что файл gameOver.png был изменен, это даст ему возможность соответствовать новому расположению кнопок. Размеры изображения по-прежнему остаются такими же, поэтому вам не придется делать никаких других корректировок). Первыми изменениями станут новые кнопки в игре.

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

1
2
local yesButton = display.newImage("yesButton.png")
3
yesButton.x = 100
4
yesButton.y = 600
5
local noButton = display.newImage("noButton.png")
6
noButton.x = 100
7
noButton.y = 600

Затем обязательно добавьте их и на экран.  А также в остальные вкладки экрана:

1
2
screen:insert(yesButton)
3
screen:insert(noButton)

Следующий этап - это переход к функции touched () и удаление первого оператора if/else, вот так он будет выглядеть:

1
2
function touched( event )
3
if(monster.isAlive == true) then
4
	if(event.phase == "began") then
5
		if(event.x < 241) then
6
			if(onGround) then
7
				monster.accel = monster.accel + 20
8
			end
9
			else
10
				for a=1, blasts.numChildren, 1 do
11
					if(blasts[a].isAlive == false) then
12
						blasts[a].isAlive = true
13
						blasts[a].x = monster.x + 50
14
						blasts[a].y = monster.y
15
						break
16
					end
17
				end
18
			end
19
		end
20
	  end
21
     end

Делая это, он делает функцию touched той, которая только обрабатывает внутриигровые взаимодействия. Мы собираемся переместить логику, которая перезапускает игру до ее собственной функции. Добавьте эти функции ниже функции touched():

1
2
function noListener(event)
3
	director:changeScene( "menu", "downFlip" )
4
	return true
5
end
6
function yesListener(event)
7
	restartGame()
8
	return true
9
end

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

1
2
yesButton:addEventListener("touch", yesListener )
3
noButton:addEventListener("touch", noListener )

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

1
2
noButton.x = 100
3
noButton.y = 600
4
yesButton.x = 100
5
yesButton.y = 600

Затем перейдите к функции collisions check(), где вы должны увидеть эти строки повторяющиеся несколько раз:

1
2
gameOver.x = display.contentWidth*.65
3
gameOver.y = display.contentHeight/2

Добавьте этот блок в любой его экземпляр (всего должно быть 4, по одному для каждого пути):

1
2
yesButton.x = display.contentWidth*.65 - 80
3
yesButton.y = display.contentHeight/2 + 40
4
noButton.x = display.contentWidth*.65 + 80
5
noButton.y = display.contentHeight/2 + 40

После того, как вы внесете все изменения, вы должны быть готовы запустить игру из файла main.lua и вернуться к игре через меню, погибнуть, и затем выбрать хотите ли вы продолжить игру или выйти в меню. Итак, если все хорошо, это конец, теперь у нас есть наша игра. Мы делали всё очень быстро, большую часть времени. Если у вас возникнут какие-либо проблемы на любом этапе, дайте мне знать в комментариях, и я помогу вам с этим. Новая папка в загруженном файле также содержит конечный продукт, и также вы всегда можете использовать его в качестве образца. Надеюсь, эта серия помогла вам в том, что теперь вы начали заниматься разработкой игр с помощью Corona SDK. Corona SDK является мощным и очень дружественным инструментом, когда вы освоите основы. Надеюсь, вы сможете продвигаться вперед и создавать разные удивительные игры.

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

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.