mzxio [Lexaloffle Blog Feed]https://www.lexaloffle.com/bbs/?uid=11987 Simple Scene Manager <p> <table><tr><td> <a href="/bbs/?pid=36143#p"> <img src="/bbs/thumbs/pico36138.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=36143#p"> Simple Scene Manager</a><br><br> by <a href="/bbs/?uid=11987"> mzxio</a> <br><br><br> <a href="/bbs/?pid=36143#p"> [Click to Play]</a> </td></tr></table> </p> <p>Something to help create more complex games in Pico-8 rather than just simple one-off demos. All this code is free to take, use, change, adapt, or whatever. Have fun.</p> <p>Press Z to cycle through scenes and X to reset back to the default scene.</p> <p>Scene 0 shows a clock running, scene 1 still shows the clock but doesn't update it, scene 2 rolls a random number every few ticks, and scene 3 just looks pretty. The whole demo weighs in at only 161 lines of code.</p> <p><strong>ABOUT</strong></p> <p>This cart contains a simple set of functions used to swap out scenes composed of layers made up of calculations and drawing instructions. For this release there's some basic demo data so you can reverse-engineer the thinking and maybe adapt it to your own projects. I tried to mirror Pico-8's default update/draw style of functionality so you hopefully don't have to change the way you think about writing your games too much. </p> <p>I made this tool for myself but I wanted to share it because it might help you, if you're like me and struggle with manifesting complex projects. I'm not very experienced as a programmer but I've spent a lot of time using drawing tools like Photoshop. Art tools often use layers to organize complex compositions. So I decided to adapt that way of thinking into Pico-8. I find this helps me keep everything straight in my head as I work. Instead of building monolithic behaviors inside the default _update and _draw functions, this scene manager allows me to create scenes built up of whatever components those scenes should have.</p> <p>This has the added benefit of making it easier to jump back into projects after not looking at them for a while, because you don't have to completely rediscover your old thought processes in order to start playing around with new ideas. That has saved me a lot of time! I found my code became much more readable and easier to manage after making the switch to using this scene manager. A modified version of this very cart became the core of my <a href="https://www.lexaloffle.com/bbs/?tid=28612">Pocket Full of Sand</a> demo.</p> <p><strong>REFERENCE</strong></p> <p>The simple scene manager is very easy to integrate into Pico-8's core functions:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> function _update() -- listen for buttons input() -- update active scene scene.updates() end function _draw() -- draw active scene scene.drawing() end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Here's how it works:</p> <p><table style="width:640px" cellspacing=0 cellpadding=10><tr><td bgcolor=#ffeedd><span style="color: #101010;"><br /> <strong>scene</strong><br /> Top level table used to keep all the scene functions tidy and out of the way.</p> <p><strong>scene.active</strong><br /> Number representing the index of the current scene to run. </p> <p><strong>scene.update</strong><br /> <strong>scene.draw</strong><br /> Tables that hold their respective steps for each scene.<br /> <br></span></td></tr></table></p> <p>Scenes are made of two functions, assigned to the same index in their respective table. So you end up with something that should look very familiar: </p> <p><table style="width:640px" cellspacing=0 cellpadding=10><tr><td bgcolor=#ffeedd><span style="color: #101010;"><br /> <strong>scene.update[0,1,...]()</strong> + your code<br /> <strong>scene.draw[0,1,...]()</strong> + your code<br /> <br></span></td></tr></table></p> <p>Note:<br /> My first programming language was JavaScript. That means I think in arrays that start at 0, so that's how I made the scene manager. If you prefer the Pico-8 / Lua style that starts table indices at 1, you should be able to easily make that change.</p> <p>Included functions for the scene manager:</p> <p><table style="width:640px" cellspacing=0 cellpadding=10><tr><td bgcolor=#ffeedd><span style="color: #101010;"><br /> <strong>scene.cycle</strong><br /> Increments active scene by by one until it reaches the end of the draw table, then it starts over.</p> <p><strong>scene.reset</strong><br /> Sets active scene back to zero.</p> <p><strong>scene.updates</strong><br /> <strong>scene.drawing</strong><br /> Fires the update or draw function for the active scene, if one is present.<br /> <br></span></td></tr></table></p> <p>Note:<br /> The 'cycle' function only looks at the length of the scene.draw table. This means update steps are optional, but draw steps are required. This is personal preference again, and not set in stone.</p> <p>Now only one critical piece is missing:</p> <p><table style="width:640px" cellspacing=0 cellpadding=10><tr><td bgcolor=#ffeedd><span style="color: #101010;"><br /> <strong>input</strong><br /> Function that runs every update and checks if buttons are down, then sends instructions over to the scene manager to make changes. In the demo, Z (btn 4) fires scene.cycle and X (btn 5) fires scene.reset.<br /> <br></span></td></tr></table></p> <p>Optional extras to bring everything together:</p> <p><table style="width:640px" cellspacing=0 cellpadding=10><tr><td bgcolor=#ffeedd><span style="color: #101010;"><br /> <strong>calc</strong><br /> Table containing functions that hold game logic, behaviors, special sauce, or any step to take before drawing. I give calc functions unique names and add them to my scene.update layers. That way the layers themselves are kept very simple so my most gnarly complex code can live by itself. </p> <p><strong>layer</strong><br /> Table containing functions that get all your drawing instructions, or steps to take after updates. Same idea as the calc functions, I throw all my draw instructions into layer functions so any awkward pixel magic is easier to keep straight.<br /> <br></span></td></tr></table></p> <p>Note:<br /> This part is entirely optional and just an idea to keep code organized. If the description is confusing, it might make more sense in the way the demo code is structured. In my <a href="https://www.lexaloffle.com/bbs/?tid=28612">Pocket Full of Sand</a> demo I ended up changing the name of 'layer' because it's a confusing value to use for just the draw steps. I didn't go back and change it for this release, but you might want to. </p> <p>As an example of how everything comes together, here's some of the code from the demo.</p> <p>First the functions for scene 0 are declared:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> scene.update[0] = function() calc.clock() end scene.draw[0] = function() cls() rectfill(0,0,128,128,12) layer.clock() end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>Then the special sauce for updates and drawings live in their own functions:</p> <div> <div style="max-width:800px; overflow:auto; margin-bottom:12px"> <table style="width:100%" cellspacing=0 cellpadding=0> <tr><td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> <td background=/gfx/code_bg0.png> <div style="font-family : courier; color: #000000; display:absolute; padding-left:10px; padding-top:4px; padding-bottom:4px; "> <pre> -- current time nowish = 0 -- set time to local pico time calc.clock = function() nowish = time() end -- print nowish time at top left layer.clock = function() print('time: '..nowish, 0, 0) end </pre></div></td> <td background=/gfx/code_bg1.png width=16><div style="width:16px;display:block"></div></td> </tr></table></div></div> <p>This example doesn't do much, but I'm sure you can think of ways to extend it for your own ideas!</p> <p><strong>CONCLUSION</strong></p> <p>I tried to keep everything straightforward and well ordered so the code can be easy to grok. I haven't been programming for long so I'm sure there are better ways to do this, but I couldn't find any existing solutions for Pico-8 that fit my needs. In the short time since I wrote this code it's already advanced my Pico-8 skills enormously. Maybe it can do the same for you.</p> <p>Again, this code is totally free to do with as you please. Best of luck.</p> https://www.lexaloffle.com/bbs/?tid=28639 https://www.lexaloffle.com/bbs/?tid=28639 Fri, 20 Jan 2017 15:30:02 UTC Pocket Full of Sand <p> <table><tr><td> <a href="/bbs/?pid=35962#p"> <img src="/bbs/thumbs/pico35961.png" style="height:256px"></a> </td><td width=10></td><td valign=top> <a href="/bbs/?pid=35962#p"> Pocket Full of Sand 1</a><br><br> by <a href="/bbs/?uid=11987"> mzxio</a> <br><br><br> <a href="/bbs/?pid=35962#p"> [Click to Play]</a> </td></tr></table> </p> <p>A little day-night time simulation with environment that I've been working on.</p> https://www.lexaloffle.com/bbs/?tid=28612 https://www.lexaloffle.com/bbs/?tid=28612 Tue, 17 Jan 2017 22:08:03 UTC