Log In  

Hi, everyone. I made a very simplistic scene manager for you all to use, its somewhat compressed as well. here's an example:

Cart #scenemanager_sample-0 | 2019-02-03 | Code ▽ | Embed ▽ | No License

Basically, this scene manager allows you to create init, update and draw for each scene (as well as anything else you want to cook up, of course).

HOW TO USE
to make a new scene, use the command 'nscn' inside of your init function. for example: nscn({init=function() end, update=function() end, draw=function() end})

to grab the current scene thats running so you can modify it or its variables, you can simply create a local variable called 'self'.

local this=scn['self']()

(or local this=scn.self())

to switch to a scene, you'll need to comment the ID of that scene so you don't lose track. I recommend you have a function that launches at the init() of your game that creates all of your scenes for you.

command to load a scene: scn_mng.go(id) where id is the scene number you want to run.

Finally, you need to put the 2 commands inside draw() and update(). in update(), put scn_mng.update() and in draw put scn_mng.draw()

code snippit:

--scene manager
--shooting★
scn = {self=function() return scn[scn_mng.r] end} scn_mng = { go=function(s) scn_mng.r = s scn[s].init() end, draw=function() scn[scn_mng.r].draw() end, update=function() scn[scn_mng.r].update() end } function nscn(d) local a={ init=d.init or function() end, update=d.update or function() end, draw=d.draw or function() end } add(scn, a) end

code example (used in cart above)

--sample

function create_scenes()
    --scene 1
    nscn({
        init=function()
            --create a local var called
            --this and set it to self
            --scene
            local this=scn['self']()

            --create particles
            this.particles = {}
            for i=0,16 do
                local a={rnd(127),rnd(127),rnd(2)}
                add(this.particles, a)
            end

            --create a timer to switch
            --to scene 2 with
            this.timer=0
        end,

        update=function()
            --create a local var called
            --this and set it to self
            --scene
            local this=scn['self']()

            this.timer+=1

            if this.timer==120 then
                this.timer=0
                --switch to scene 2
                scn_mng.go(2)
            end
        end,

        draw=function()
         --create a local var called
            --this and set it to self
            --scene
            local this=scn['self']()

            --draw particles
            for i=1,#this.particles do
                pset(this.particles[i][1],
                     this.particles[i][2],
                     7)
            this.particles[i][1]+=this.particles[i][3]
            this.particles[i][2]+=this.particles[i][3]
            end
        end
    })

    --scene 2
    nscn({
        init=function()
            --create a local var called
            --this and set it to self
            --scene
            local this=scn['self']()

            this.timer=0
        end,

        update=function()
            --create a local var called
            --this and set it to self
            --scene
            local this=scn['self']()

            this.timer+=1

            if this.timer==120 then
                this.timer=0
                --switch back to scene 1
                scn_mng.go(1)
            end
        end,

        draw=function()
            cls(1)
        end
    })
end

function _init()
    --create scenes
    create_scenes()
    scn_mng.go(1)
end

function _update()
    scn_mng.update()
end

function _draw()
    cls()
    scn_mng.draw()
    print('running scene '..scn_mng.r, 0, 0, 7)
end
P#61476 2019-02-03 02:34

1

So this is nice.

However, I saw you posting similar systems on Twitter and I wanted to bring up something you might not be considering. In the lower right corner Pico-8 will track how many 'Tokens' your code is using. The concept of a Token is a bit nebulous but basically every time you type an operator, a command, a function, a variable you spend at least a Token. When you hit 8192 Tokens, it's game over. You can't put any more code in your cart. In fact, your code won't even run until you can somehow go below that limit again. Note that this is not the same as the length of the code. Shorter variable names or compression won't save Tokens.

When doing bigger projects in Pico-8, being efficient with Tokens will be a very high priority. Every bigger project is bound to hit that limit. Your efficiency will translate directly into being able to implement more features.

OOP is a highly token-inefficient way of coding.

player_x = 1 -- is 3 Tokens

player.x = 1 -- is 4 Tokens

Every single time you access a property of an object it costs you an additional Token. So every time you use objects, you should ask yourself: "Does this absolutly HAVE to be an object? What am I actually GAINING from this being an object?".

Your sample code with the scene manager is 299 Tokens.

This is a whole racing game made in 387 Tokens
https://twitter.com/p01/status/1091498849049427969

And the code below is your sample rewritten. It has no scene maner and no OOP. But it still uses the same function pointer trick you applied and it's not that much harder to use. It's 163 Tokens.

I'm not bringing this up to dunk on your system. I'm sure it has its place. And maybe you already know all of this and you had your reasons. I wanted just to make sure you're not wasting your time developing systems that end up causing you more problems than they solve.

Cheers man, keep it up!

function init_1()
 _drw=draw_1
 _upd=update_1

 particles = {}
 for i=0,16 do
  local a={rnd(127),rnd(127),rnd(2)}
  add(particles, a)
 end
 timer=0
 scn_num=1

end

function update_1()
 timer+=1
 if timer==120 then
  timer=0
  init_2()
 end
end

function draw_1()
 cls()
 for i=1,#particles do
  pset(particles[i][1],particles[i][2],7)
  particles[i][1]+=particles[i][3]
  particles[i][2]+=particles[i][3]
 end
end

function init_2()
 _drw=draw_2
 _upd=update_2
 timer=0
 scn_num=2
end

function update_2()
 timer+=1

 if timer==120 then
  timer=0
  init_1()
 end
end

function draw_2()
 cls(1)
end

function _init()
 --create scenes
 init_1()
end

function _update()
 _upd()
end

function _draw()    
 _drw()
 print('running scene '..scn_num, 0, 0, 7)
end
P#61477 2019-02-03 03:30

Krystman,
Thank you for that info. All the more reason to love pico8 as its going to force me to optimize more! Loving the token system, and I'll start paying attention to it more <3

Cheers!

P#61485 2019-02-03 13:29
function scene(act, int, upd)
    if act == 'new' then
     return {int=int, upd=upd}
    end

    if act == 'go' then
     int.int()
     scn = int
    end
end

function upd_scn()
    if not scn then return end
    scn.upd()
end

Krystman
thanks for telling me about tokens! I made this update here that only uses 41 tokens. <3

sample:

function scenes()
    scene1=scene('new',
    --init
    function()
        scene1.f=0
    end, 
    --update/draw
    function()
        print(scene1.f)
        scene1.f+=1
    end)
end

function _init()
    scenes()
    scene('go', scene1)
end

function _draw()
    upd_scn()
end

----EDIT----
even more optimized now <3 same setup just different execution

function scene(a, b, c)
    if a == 'new' then
     return {b, c}
    end

    if a == 'go' then
     if c != true then b[1]() end
     scn=b
    end
end

function upd_scn()
    if not scn then return end
    scn[2]()
end

this one uses 44 tokens and looks cleaner.

compressed:

function scene(a, b, c) if a == 'new' then return {b, c} end if a == 'go' then if c != true then b[1]() end s=b end end function upd_scn() if not s then return end s[2]() end 
P#61493 2019-02-04 02:03 ( Edited 2019-02-04 02:16)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-04-16 15:56:36 | 0.015s | Q:18