Hello! I’ve been wondering this for awhile how I can make multiple screens, for example, Lets say I want a world where you can step on a button, and by pressing the button your screen changes to the main menu.
Any suggestions?
Here’s a menu example.
displayMode(FULLSCREEN)
supportedOrientations(PORTRAIT) -- set for portrait mode
function setup()
func=menu
end
function draw()
func()
end
function menu()
background(0,0,200)
w=WIDTH/2 -- set width value
eh=HEIGHT-400 -- set height of different options
nh=HEIGHT-600 -- eh easy, nh normal, hh hard
hh=HEIGHT-800
fontSize(48) -- set font size
fill(255,0,0) -- set font color
menuTitle1="Main Menu" -- main title
menuTitle2="Select Option"
text(menuTitle1,w,HEIGHT-100) -- display titles
text(menuTitle2,w,HEIGHT-200)
fill(0,255,0) -- set easy values
t1="Easy"
text(t1,w,eh)
w1,h1=textSize(t1) -- width and height of easy text
t2="Normal" -- set normal values
text(t2,w,nh)
w2,h2=textSize(t2) -- width and height of normal text
t3="Hard" -- set hard values
text(t3,w,hh)
w3,h3=textSize(t3) -- width and height of hard text
end
function easy()
background(40,40,50)
text("EASY screen",WIDTH/2,HEIGHT/2)
text("tap screen for menu",WIDTH/2,HEIGHT/2-200)
end
function normal()
background(40,40,50)
text("NORMAL screen",WIDTH/2,HEIGHT/2)
text("tap screen for menu",WIDTH/2,HEIGHT/2-200)
end
function hard()
background(40,40,50)
text("HARD screen",WIDTH/2,HEIGHT/2)
text("tap screen for menu",WIDTH/2,HEIGHT/2-200)
end
function touched(t)
if t.state==BEGAN then
if func ~= menu then
func=menu
return
end
if func==menu then
if t.x>w-w1/2 and t.x<w+w1/2 and t.y>eh-h1/2 and t.y<eh+h1/2 then
func=easy
end
if t.x>w-w2/2 and t.x<w+w2/2 and t.y>nh-h2/2 and t.y<nh+h2/2 then
func=normal
end
if t.x>w-w3/2 and t.x<w+w3/2 and t.y>hh-h3/2 and t.y<hh+h3/2 then
func=hard
end
end
end
end
Here’s some code I wrote a while ago that does this: http://coolcodea.wordpress.com/2013/05/04/47-game-template/
But those just look like menus, Are they just that are multiple screens?
@Prynok The code I show above is an example of how to display different screens based on what button you tap. Since I don’t know exactly what you want to do with the different screens, I can only show screens that don’t really do anything. Since the screens don’t do anything, I just return back to the menu when you tap the screen. You would do whatever you want in the different screens and where you return to would depend on your code.
… but if you mean multiple screens like PIP, then you might wanna look at setContext() …
-delete-
I’ve got some code in my game (StackIt) that does menus, multiple screens, and transitions, but it’s heavily integrated with the rest of my code.
-delete-
- Double post *
@Prynok - perhaps what’s confusing you is that in Codea there are no “screens”. There is one screen that is redrawing itself 60 times a second.
So if you want to show a menu, you draw a menu. If you want to play the game, you draw the game. That is why the examples you have been given have a variable that tells Codea what it should be drawing, ie whether it is a menu, the game etc.
So your draw code will look something like
function draw()
if state=="Menu" then
--code to draw menu
elseif state=="Playing" then
--code to draw game
end
This is also a great place to use classes. You don’t want to draw the entire game in your main tab’s draw() function. Instead, you should have, at the very least, a Game object and a Menu object. Each one of those has a draw() function. In the Menu object, you’ll have code that draws the active menu items. In the Game object, you’ll have a table of things that get drawn. (Actually, you should have at least 2 tables: one for the background and one for dynamic objects and actors.)
So, building on Ignatz’s example, your main draw routine would look like:
function draw()
if menu.active then
menu:draw()
elseif game.active then
game:draw()
else
titleScreen:draw()
end
end
yeah, the difference between : and . can be important. Every time I see that error trying to index nil, I know right what to go look for…
Oh that makes sense, thanks!
What I do is create a variable called “scene” and make an if statement in the draw function that’s “if scene == 1 then…(What to do for this scene)… elseif scene == 2 then…(What to do for this scene)…end” etc. I think that’s the simplest way. Now when you want to change your screen you just do “scene = (The scene #)”.
Classes are really good here instead of if() in draw simply because it’s easier to forward the execution to another “thing” to do - but it’s confusing to debug issues. I typically put together a main that consists of this:
--
-- main.lua
--
-- 0_GameTemplate
function setup()
SetDisplayMode() --your own function
--GAME STATE DRIVER -- CAN ABSTRACT IN THE FUTURE
-- define consts - these drive the game state
--Note that I could have abstracted these
--into the GameFunctions file, but I want
--to "see" the states.
GAMESTATE_TITLE = 1
GAMESTATE_PLAYING = 2
-- put any screen states you want in here.
GAMESTATE_SCREEN1 = 3
GAMESTATE_SCREEN2 = 4
GAMESTATE_ENDED = 5
--these are the screens (classes) that are called when
--the game performs it's heartbeat
--there should be one of these for each of the items above.
GAMESTATES = { ScreenTitle, ScreenGame, nil, nil, ScreenEnd }
--note I don't have a SCREEN1 or SCREEN2, so
--I assigned nil for now, These are Codea classes!
--start at the default Title / Menu screen
--note that this will occur fast, so if you are defer loading,
--you'll have to
--be aware that all assets might not be loaded
--before the Title screen renders.
GAMESTATE = GAMESTATE_TITLE
--END OF GAMESTATE DRIVER
GameSetup() --sets up game parameters.
--Not the same as the game state driver. Your custom variable setup
end
-- This function gets called once every frame
--this is the game's heartbeat.
function draw()
background(0, 0, 0, 255) --clear background
--state machine
GAMESTATES[GAMESTATE]:draw() --draw whatever the "Screen" should be
end
--any touches we get, forward on to the screen / class that needs them.
--note that this assumes that the default touch() is working!
function touched(touch)
--state machine - forward the touch!
GAMESTATES[GAMESTATE]:touched(touch)
end
GAMESTATES are the “screens”, basically, classes in Codea that handle their own draw() and touched(). Whenever you want to change the state of the game, change the value of the GAMESTATE variable to any of the constants, and the game will immediately jump / draw / touch in that state.
The biggest challenge with this is knowing how to safely switch states - clearing variables and making sure that you don’t jump into the middle of a game when you just finished doing high scores, for example. Careful variable use should help you avoid that.
I don’t know if this is the right place to go, but instead of having multiple screens in which the transitions quickly snap to the screen you wish to go to, couldn’t you also have a scene which the screen displays partially while you are in one section, and when you swipe or select a button the screen (slowly) shifts to reveal the other half of the scene.
I’m trying to refer to the screen in a game called Tiny Wings. I’m currently trying to code the effect using Codea.