Difference between revisions of "Tuto tiny-ecs demo Part 2 Menu"

From GiderosMobile
(Created page with "__TOC__ == Init == == Main == == Menu scene == Okay, we are all set up, aren't we? Prev.: Tuto tiny-ecs_demo Part 1 Setup</br> '''Next: xxx''' '''Tutorial -...")
 
Line 1: Line 1:
 
__TOC__
 
__TOC__
 +
 +
Setting up ''scenemanager'' is not the purpose of this tutorial but it adds a nice touch to our demo, so I will quickly go over it.
 +
 +
'''Hopefully the comments are plenty'''!
 +
 
== Init ==
 
== Init ==
 +
Create the '''init.lua''' file:
 +
<syntaxhighlight lang="lua">
 +
-- plugins
 +
require "scenemanager"
 +
require "easing"
 +
 +
-- app size we could use
 +
myappleft, myapptop, myappright, myappbot = application:getLogicalBounds()
 +
myappwidth, myappheight = myappright - myappleft, myappbot - myapptop
 +
 +
-- ttf fonts
 +
myttf = TTFont.new("fonts/Cabin-Regular-TTF.ttf", 8*4)
 +
</syntaxhighlight>
  
 
== Main ==
 
== Main ==
 +
Create the '''main.lua''' file which contains the ''scenemanager'' and a list of scene transitions and easings:
 +
<syntaxhighlight lang="lua">
 +
-- scene manager
 +
scenemanager = SceneManager.new(
 +
{
 +
["menu"] = Menu,
 +
["levelX"] = LevelX,
 +
}
 +
)
 +
stage:addChild(scenemanager)
 +
scenemanager:changeScene("menu")
 +
 +
-- transitions & easings
 +
transitions = {
 +
SceneManager.moveFromRight, -- 1
 +
SceneManager.moveFromLeft, -- 2
 +
SceneManager.moveFromBottom, -- 3
 +
SceneManager.moveFromTop, -- 4
 +
SceneManager.moveFromRightWithFade, -- 5
 +
SceneManager.moveFromLeftWithFade, -- 6
 +
SceneManager.moveFromBottomWithFade, -- 7
 +
SceneManager.moveFromTopWithFade, -- 8
 +
SceneManager.overFromRight, -- 9
 +
SceneManager.overFromLeft, -- 10
 +
SceneManager.overFromBottom, -- 11
 +
SceneManager.overFromTop, -- 12
 +
SceneManager.overFromRightWithFade, -- 13
 +
SceneManager.overFromLeftWithFade, -- 14
 +
SceneManager.overFromBottomWithFade, -- 15
 +
SceneManager.overFromTopWithFade, -- 16
 +
SceneManager.fade, -- 17
 +
SceneManager.crossFade, -- 18
 +
SceneManager.flip, -- 19
 +
SceneManager.flipWithFade, -- 20
 +
SceneManager.flipWithShade, -- 21
 +
}
 +
easings = {
 +
easing.inBack, -- 1
 +
easing.outBack, -- 2
 +
easing.inOutBack, -- 3
 +
easing.inBounce, -- 4
 +
easing.outBounce, -- 5
 +
easing.inOutBounce, -- 6
 +
easing.inCircular, -- 7
 +
easing.outCircular, -- 8
 +
easing.inOutCircular, -- 9
 +
easing.inCubic, -- 10
 +
easing.outCubic, -- 11
 +
easing.inOutCubic, -- 12
 +
easing.inElastic, -- 13
 +
easing.outElastic, -- 14
 +
easing.inOutElastic, -- 15
 +
easing.inExponential, -- 16
 +
easing.outExponential, -- 17
 +
easing.inOutExponential, -- 18
 +
easing.linear, -- 19
 +
easing.inQuadratic, -- 20
 +
easing.outQuadratic, -- 21
 +
easing.inOutQuadratic, -- 22
 +
easing.inQuartic, -- 23
 +
easing.outQuartic, -- 24
 +
easing.inOutQuartic, -- 25
 +
easing.inQuintic, -- 26
 +
easing.outQuintic, -- 27
 +
easing.inOutQuintic, -- 28
 +
easing.inSine, -- 29
 +
easing.outSine, -- 30
 +
easing.inOutSine, -- 31
 +
}
 +
</syntaxhighlight>
  
 
== Menu scene ==
 
== Menu scene ==
 +
The Menu is a scene, so to better organise our code, please create a folder called "'''scenes'''" for example and create the ''menu.lua'' file inside it.
 +
 +
The Menu scene contains a couple of buttons (buttonMonster) which allow to navigate with the mouse, finger or keyboard (here the arrow keys are used).
 +
 +
<syntaxhighlight lang="lua">
 +
Menu = Core.class(Sprite)
 +
 +
function Menu:init()
 +
-- bg
 +
application:setBackgroundColor(0x323232)
 +
-- tooltip layer
 +
local tooltiplayer = Sprite.new()
 +
-- buttons
 +
local btnsound = {sound=Sound.new("audio/ui/sfx_sounds_button1.wav"), time=0, delay=0.2}
 +
local volume = 0.5
 +
local mybtn = ButtonMonster.new({
 +
autoscale=false,
 +
pixelwidth=8*20, pixelheight=8*8,
 +
pixelscalexup=0.8, pixelscalexdown=0.9,
 +
pixelcolordown=0x00ff00,
 +
text="level 1", ttf=myttf,
 +
sound=btnsound, volume=volume,
 +
}, 1)
 +
local mybtn02 = ButtonMonster.new({
 +
autoscale=false,
 +
pixelwidth=8*20, pixelheight=8*8,
 +
pixelscalexup=0.8, pixelscalexdown=0.9,
 +
pixelcolordown=0x00ff00,
 +
text="level 2", ttf=myttf,
 +
sound=btnsound, volume=volume,
 +
tooltiptext="nothing here!", tooltipttf=myttf, tooltiptextcolor=0xff00ff,
 +
tooltipoffsetx=-8*16, tooltipoffsety=8*4,
 +
}, 2, tooltiplayer)
 +
local mybtn03 = ButtonMonster.new({
 +
autoscale=false,
 +
pixelwidth=8*20, pixelheight=8*8,
 +
pixelscalexup=0.8, pixelscalexdown=0.9,
 +
pixelcolorup=0xff0000,
 +
text="Exit", ttf=myttf,
 +
sound=btnsound, volume=volume,
 +
}, 3)
 +
-- btns table for keyboard navigation
 +
self.btns = {}
 +
self.btns[#self.btns + 1] = mybtn
 +
self.btns[#self.btns + 1] = mybtn02
 +
self.btns[#self.btns + 1] = mybtn03
 +
self.selector = 1 -- starting button
 +
-- positions
 +
mybtn:setPosition(12*myappwidth/16, 4*myappheight/16)
 +
mybtn02:setPosition(12*myappwidth/16, 8*myappheight/16)
 +
mybtn03:setPosition(12*myappwidth/16, 13*myappheight/16)
 +
-- order
 +
for k, v in ipairs(self.btns) do self:addChild(v) end
 +
self:addChild(tooltiplayer)
 +
-- btns listeners
 +
for k, v in ipairs(self.btns) do
 +
v:addEventListener("clicked", function() self:goTo() end)
 +
v:addEventListener("hovered", function(e) self.selector = e.currselector end)
 +
v.btns = self.btns -- for keyboard navigation
 +
end
 +
-- listeners
 +
self:addEventListener("enterEnd", self.onTransitionInEnd, self)
 +
-- let's go
 +
self:updateButton() -- update selected button state
 +
end
 +
 +
-- event listeners
 +
function Menu:onTransitionInEnd() self:myKeysPressed() end
 +
 +
-- update button state
 +
function Menu:updateButton()
 +
for k, v in ipairs(self.btns) do
 +
v.currselector = self.selector
 +
v:updateVisualState()
 +
if k == self.selector then v:selectionSfx() end
 +
end
 +
end
 +
 +
-- keyboard navigation
 +
function Menu:myKeysPressed()
 +
self:addEventListener(Event.KEY_DOWN, function(e)
 +
if e.keyCode == KeyCode.UP or e.keyCode == KeyCode.LEFT then
 +
self.selector -= 1 if self.selector < 1 then self.selector = #self.btns end
 +
self:updateButton()
 +
elseif e.keyCode == KeyCode.DOWN or e.keyCode == KeyCode.RIGHT then
 +
self.selector += 1 if self.selector > #self.btns then self.selector = 1 end
 +
self:updateButton()
 +
elseif e.keyCode == KeyCode.ENTER then
 +
self:goTo()
 +
end
 +
end)
 +
end
 +
 +
-- go to scenes
 +
function Menu:goTo()
 +
for k, v in ipairs(self.btns) do
 +
if k == self.selector then
 +
if v.isdisabled then print("btn disabled!", k)
 +
elseif k == 1 then scenemanager:changeScene("levelX", 1, transitions[1], easings[2])
 +
elseif k == 2 then print("button ", k)
 +
elseif k == 3 then
 +
if not application:isPlayerMode() then application:exit()
 +
else print("Exit button ", k)
 +
end
 +
end
 +
end
 +
end
 +
end
 +
</syntaxhighlight>
  
  
  
Okay, we are all set up, aren't we?
+
'''I wanted to get this part done pretty fast (sorry) so we could move to the ECS fun'''.
  
  
 
Prev.: [[Tuto tiny-ecs_demo Part 1 Setup]]</br>
 
Prev.: [[Tuto tiny-ecs_demo Part 1 Setup]]</br>
'''Next: [[xxx]]'''
+
'''Next: [[Tuto tiny-ecs_demo Part 3 tiny-ecs World]]'''
  
  
 
'''[[Tutorial - tiny-ecs demo]]'''
 
'''[[Tutorial - tiny-ecs demo]]'''
 
{{GIDEROS IMPORTANT LINKS}}
 
{{GIDEROS IMPORTANT LINKS}}

Revision as of 03:23, 17 December 2023

Setting up scenemanager is not the purpose of this tutorial but it adds a nice touch to our demo, so I will quickly go over it.

Hopefully the comments are plenty!

Init

Create the init.lua file:

-- plugins
require "scenemanager"
require "easing"

-- app size we could use
myappleft, myapptop, myappright, myappbot = application:getLogicalBounds()
myappwidth, myappheight = myappright - myappleft, myappbot - myapptop

-- ttf fonts
myttf = TTFont.new("fonts/Cabin-Regular-TTF.ttf", 8*4)

Main

Create the main.lua file which contains the scenemanager and a list of scene transitions and easings:

-- scene manager
scenemanager = SceneManager.new(
	{
		["menu"] = Menu,
		["levelX"] = LevelX,
	}
)
stage:addChild(scenemanager)
scenemanager:changeScene("menu")

-- transitions & easings
transitions = {
	SceneManager.moveFromRight, -- 1
	SceneManager.moveFromLeft, -- 2
	SceneManager.moveFromBottom, -- 3
	SceneManager.moveFromTop, -- 4
	SceneManager.moveFromRightWithFade, -- 5
	SceneManager.moveFromLeftWithFade, -- 6
	SceneManager.moveFromBottomWithFade, -- 7
	SceneManager.moveFromTopWithFade, -- 8
	SceneManager.overFromRight, -- 9
	SceneManager.overFromLeft, -- 10
	SceneManager.overFromBottom, -- 11
	SceneManager.overFromTop, -- 12
	SceneManager.overFromRightWithFade, -- 13
	SceneManager.overFromLeftWithFade, -- 14
	SceneManager.overFromBottomWithFade, -- 15
	SceneManager.overFromTopWithFade, -- 16
	SceneManager.fade, -- 17
	SceneManager.crossFade, -- 18
	SceneManager.flip, -- 19
	SceneManager.flipWithFade, -- 20
	SceneManager.flipWithShade, -- 21
}
easings = {
	easing.inBack, -- 1
	easing.outBack, -- 2
	easing.inOutBack, -- 3
	easing.inBounce, -- 4
	easing.outBounce, -- 5
	easing.inOutBounce, -- 6
	easing.inCircular, -- 7
	easing.outCircular, -- 8
	easing.inOutCircular, -- 9
	easing.inCubic, -- 10
	easing.outCubic, -- 11
	easing.inOutCubic, -- 12
	easing.inElastic, -- 13
	easing.outElastic, -- 14
	easing.inOutElastic, -- 15
	easing.inExponential, -- 16
	easing.outExponential, -- 17
	easing.inOutExponential, -- 18
	easing.linear, -- 19
	easing.inQuadratic, -- 20
	easing.outQuadratic, -- 21
	easing.inOutQuadratic, -- 22
	easing.inQuartic, -- 23
	easing.outQuartic, -- 24
	easing.inOutQuartic, -- 25
	easing.inQuintic, -- 26
	easing.outQuintic, -- 27
	easing.inOutQuintic, -- 28
	easing.inSine, -- 29
	easing.outSine, -- 30
	easing.inOutSine, -- 31
}

Menu scene

The Menu is a scene, so to better organise our code, please create a folder called "scenes" for example and create the menu.lua file inside it.

The Menu scene contains a couple of buttons (buttonMonster) which allow to navigate with the mouse, finger or keyboard (here the arrow keys are used).

Menu = Core.class(Sprite)

function Menu:init()
	-- bg
	application:setBackgroundColor(0x323232)
	-- tooltip layer
	local tooltiplayer = Sprite.new()
	-- buttons
	local btnsound = {sound=Sound.new("audio/ui/sfx_sounds_button1.wav"), time=0, delay=0.2}
	local volume = 0.5
	local mybtn = ButtonMonster.new({
		autoscale=false,
		pixelwidth=8*20, pixelheight=8*8,
		pixelscalexup=0.8, pixelscalexdown=0.9,
		pixelcolordown=0x00ff00,
		text="level 1", ttf=myttf,
		sound=btnsound, volume=volume,
	}, 1)
	local mybtn02 = ButtonMonster.new({
		autoscale=false,
		pixelwidth=8*20, pixelheight=8*8,
		pixelscalexup=0.8, pixelscalexdown=0.9,
		pixelcolordown=0x00ff00,
		text="level 2", ttf=myttf,
		sound=btnsound, volume=volume,
		tooltiptext="nothing here!", tooltipttf=myttf, tooltiptextcolor=0xff00ff,
		tooltipoffsetx=-8*16, tooltipoffsety=8*4,
	}, 2, tooltiplayer)
	local mybtn03 = ButtonMonster.new({
		autoscale=false,
		pixelwidth=8*20, pixelheight=8*8,
		pixelscalexup=0.8, pixelscalexdown=0.9,
		pixelcolorup=0xff0000,
		text="Exit", ttf=myttf,
		sound=btnsound, volume=volume,
	}, 3)
	-- btns table for keyboard navigation
	self.btns = {}
	self.btns[#self.btns + 1] = mybtn
	self.btns[#self.btns + 1] = mybtn02
	self.btns[#self.btns + 1] = mybtn03
	self.selector = 1 -- starting button
	-- positions
	mybtn:setPosition(12*myappwidth/16, 4*myappheight/16)
	mybtn02:setPosition(12*myappwidth/16, 8*myappheight/16)
	mybtn03:setPosition(12*myappwidth/16, 13*myappheight/16)
	-- order
	for k, v in ipairs(self.btns) do self:addChild(v) end
	self:addChild(tooltiplayer)
	-- btns listeners
	for k, v in ipairs(self.btns) do
		v:addEventListener("clicked", function() self:goTo() end)
		v:addEventListener("hovered", function(e) self.selector = e.currselector end)
		v.btns = self.btns -- for keyboard navigation
	end
	-- listeners
	self:addEventListener("enterEnd", self.onTransitionInEnd, self)
	-- let's go
	self:updateButton() -- update selected button state
end

-- event listeners
function Menu:onTransitionInEnd() self:myKeysPressed() end

-- update button state
function Menu:updateButton()
	for k, v in ipairs(self.btns) do
		v.currselector = self.selector
		v:updateVisualState()
		if k == self.selector then v:selectionSfx() end
	end
end

-- keyboard navigation
function Menu:myKeysPressed()
	self:addEventListener(Event.KEY_DOWN, function(e)
		if e.keyCode == KeyCode.UP or e.keyCode == KeyCode.LEFT then
			self.selector -= 1 if self.selector < 1 then self.selector = #self.btns end
			self:updateButton()
		elseif e.keyCode == KeyCode.DOWN or e.keyCode == KeyCode.RIGHT then
			self.selector += 1 if self.selector > #self.btns then self.selector = 1 end
			self:updateButton()
		elseif e.keyCode == KeyCode.ENTER then
			self:goTo()
		end
	end)
end

-- go to scenes
function Menu:goTo()
	for k, v in ipairs(self.btns) do
		if k == self.selector then
			if v.isdisabled then print("btn disabled!", k)
			elseif k == 1 then scenemanager:changeScene("levelX", 1, transitions[1], easings[2])
			elseif k == 2 then print("button ", k)
			elseif k == 3 then
				if not application:isPlayerMode() then application:exit()
				else print("Exit button ", k)
				end
			end
		end
	end
end


I wanted to get this part done pretty fast (sorry) so we could move to the ECS fun.


Prev.: Tuto tiny-ecs_demo Part 1 Setup
Next: Tuto tiny-ecs_demo Part 3 tiny-ecs World


Tutorial - tiny-ecs demo