Ok, so bin tweaking around with Codea for a few months now, and one of the reasons I love it is because it is powered by Lua. I’ve had quite some exposure to the language before.
The first thing I noticed was the way content was rendered. You see, this is the first time I have to use a self-executing draw() function. I was OK with it for small things, but I am really starting how to wonder HOW you efficiently “flow events”.
You see, in the Lua I used, it wasn’t the same. (In fact, it was GMod Lua) and it was not 60fps draw().
So how would you make something like this:
Text saying “Welcome” appears … THEN AFTER 3 seconds
text with instructions appears
THEN if a button is pressed then a functions gets called
you see, the thing I am concerned about here is not HOW to DO them, but how to FLOW them… Count frames? Makes some kind of sleep functions? HOW?
For timing, you could use ElapsedTime, the number of seconds since the program started, eg
--in setup
state=1 --use this to decide what to draw
timer=ElapsedTime+2 --time of next change
--in draw
if ElapsedTime>timer then
state=2 --use this to decide what to draw
timer=ElapsedTime+3 --set timer for next change
end
I would use a simple finite state machine, with classes for each state. As the states are “singletons” (ie there can only be one instance of a given state at a time), strictly speaking they don’t have to be classes (they can just be tables holding related functions). But if you have lots of events that are quite similar (ie various screens like level select, options screens etc, where you’re just waiting for user to press a button), you can use class inheritance to avoid repeating code.
--# Main
function setup()
scene = Splash()
end
function draw()
scene:draw()
end
function touched(touch)
scene:touched(touch)
end
--# Splash
Splash = class()
function Splash:init()
--set up your splash screen, title of the game, "Start" button etc
end
function Splash:draw()
--draw the splash screen
end
function Splash:touched(touch)
--check whether Start button has been pressed
-- if so, scene = Game()
end
--# Game
Game = class()
function Game:init()
--set up the game
end
function Game:draw()
-- update the game
--check for GameOver event, if so scene = GameOver()
--draw the game
end
function Game:touched(touch)
--game touch events
end
--# GameOver
GameOver = class()
function GameOver:init()
--set up your gameover screen, hiscores, "restart", "quit" button etc
end
function GameOver:draw()
--draw the GameOver screen
end
function GameOver:touched(touch)
--check whether restart button has been pressed
-- if so, scene = Game()
--check whether quit button pressed
--if so scene = Splash()
end
Codea is a little more ‘low-level’ than, say, Corona SDK. If you want to use events to control your game objects and the ‘flow’, you must invent your own system. (Or just search the forum - some people did this already.)
This is true, there are a lot of event managers on the forum, ranging from very simple to super complex, and also lots of finite state machines/managers.
@_quenix Here’s a simple example of controlling the flow of code. This is an example of a menu calling 3 different screens based on which button is pressed.
displayMode(FULLSCREEN)
supportedOrientations(PORTRAIT) -- set for portrait mode
function setup()
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
func=menu -- set func to run the menu function
end
function draw()
func() -- call the function that func is set to
end
function menu()
background(0,0,200)
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() -- easy screen
background(40,40,50)
text("EASY screen",w,HEIGHT/2)
text("tap screen for menu",w,HEIGHT/2-200)
end
function normal() -- normal screen
background(40,40,50)
text("NORMAL screen",w,HEIGHT/2)
text("tap screen for menu",w,HEIGHT/2-200)
end
function hard() -- hard screen
background(40,40,50)
text("HARD screen",w,HEIGHT/2)
text("tap screen for menu",w,HEIGHT/2-200)
end
function touched(t)
if t.state==BEGAN then
if func ~= menu then -- one of the other screens is showing
func=menu
else
-- easy button
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 -- set func to run easy function
end
-- normal button
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 -- set func to run normal function
end
-- hard button
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 -- set func to run hard function
end
end
end
end
_quenix If you want to see the code that executes what you requested at the start of the discussion, here’s an example.
displayMode(FULLSCREEN)
function setup()
rectMode(CENTER)
t=ElapsedTime -- starting time
end
function draw()
if button_was_pressed then
pressed() -- run this code when the button is pressed.
elseif ElapsedTime-t<3 then -- show this for 3 seconds
fontSize(60)
background(255, 185, 0, 255)
fill(0, 46, 255, 255)
text("Welcome",WIDTH/2,HEIGHT/2)
else
instructions() -- show this until a button is pressed
end
end
function pressed() -- button pressed code
background(0, 255, 251, 255)
fontSize(30)
fill(255, 0, 64, 255)
text("Executing the button pressed function.",WIDTH/2,HEIGHT/2)
text("Tap the screen to restart.",WIDTH/2,HEIGHT/2-100)
end
function touched(t)
if t.state==BEGAN then
if button_was_pressed then
restart()
end
if t.x>WIDTH/2-50 and t.x<WIDTH/2+50 and
t.y>175 and t.y<225 then
button_was_pressed=true
end
end
end
function instructions() -- show instructions
background(0, 202, 255, 255)
fill(255, 0, 135, 255)
str=[[
All of your
instructions
go
here.
]]
fontSize(40)
text(str,WIDTH/2,HEIGHT/2)
fontSize(20)
fill(235, 255, 0, 255)
rect(WIDTH/2,200,100,50)
fill(0)
text("Start",WIDTH/2,200)
end