Difference between revisions of "Tuto tiny-ecs demo Part 2 Menu"
(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 -...") |
|||
(One intermediate revision by the same user not shown) | |||
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> | ||
− | + | == Next? == | |
+ | '''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: [[ | + | '''Next: [[Tuto tiny-ecs_demo Part 3 tiny-ecs World]]''' |
'''[[Tutorial - tiny-ecs demo]]''' | '''[[Tutorial - tiny-ecs demo]]''' | ||
{{GIDEROS IMPORTANT LINKS}} | {{GIDEROS IMPORTANT LINKS}} |
Latest revision as of 03:30, 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
Next?
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