OK, not sure that this is a proper place to post but I have been really fleshing out the Squashy game into something bigger for my first try into Pico8/Lua. I've got it all the way I want it but I can't get it to flip game modes back to the main splash screen as the "game over" screen.
A couple of things... how do i get that to work? (should I post the game or the code?) If the game, how do I post it?
(crazy noob questions, sorry! :) )
No worries, I am on the same path as you are: making squashy into a more finished game. When I started I had next to no knowledge of coding, but now I have enough that I think I can help.
The way I have done it is by introducing a variable responsible for game state and change it when the game changes from intro, to gameplay. Then, in my _update and _draw I have an IF function that changes what is displayed depending on the value of my variable. Like this:
function _init() gamestate=0 end function _update() if gamestate==0 then intro_update() elseif gamestate==1 then play_update() elseif gamestate==1.5 then end_update() end end function _draw() if gamestate==0 then intro_draw() elseif gamestate==1 then play_draw() elseif gamestate==1.5 then end_draw() end end |
Now, you just need to make new _draw and _update functions for intro,play and end and put whatever logic you need into each of those. Basically, imagine you are making 3 programs in 1. Your intro program, play program and game over program. Then you switch between them. Intro to Play when button is pressed. Play to End when you have 0 lives and End to Intro when a button is pressed on game over screen.
If you are stuck on a problem, one thing I found really helpful is looking up code of other carts. Find a game that has solved the problem you are facing and lookup its code. Doing this has helped me understand programming a lot!
OK, super kudos to you for setting my head straight with the code part. I was working towards what your explanation but that was exactly what I needed! Only drawback is that it's doing the exact same thing I was getting before. my ball centers back to x64 y64, makes a terrible noise and doesn't change modes or display anything different. I wonder if it's the way I have the loseball coding?
function loseball() if bally>128 then if lives>0 then --next life sfx(3) bally=24 lives-=1 else --game over ballydir=0 ballxdir=0 bally=64 ballx=64 sfx(4) end end end |
I was just thinking something simple with just saying mode=2 (mine are set as 0, 1, 2 for intro, game and game over) but that doesn't work and I can't even do a print("game over", 20,20,7) for it to just chuck the text on the screen to test it. It doesn't trip an error or a line where it doesn't like the code. Just ends the game. No more, no less.
One of the biggest things I want to avoid is to rebuild the whole thing. While this has been (and always will be) an amazing learning experience, I'm not in the market go that route. :/
OK, now that I've been looking at loseball(), it doesn't seem to be the problem child since it's pretty much the same code as the original version.
One thing I've been doing to manage the scenes/views/modes of my games is assigning the update/draw portions to a common variable and then using that inside the main loops. I think I saw this in one of the Picozines and changed it a bit to make more sense to me.
What it gets you is not having to update the if/then conditions for various state values. Instead you just call the init() function for the mode you want. I've found it's easier to manage and also doesn't require me to know that state value 1 is the title screen, for example, and then I can call them from any other location.
First, I create some container variables:
cart={} cart.update=function() end cart.draw=function() end |
And then call them in my main loops:
function _update() cart.update() end function _draw() cls() cart.draw() end |
Then for each view/mode, I create an init, update and draw function and assign that to the cart:
-- this shows the title screen and waits for button press title={} title._init=function() cart.update=title._update cart.draw=title._draw end title._update=function() if btnp(4) then game._init() end end title._draw=function() print("my game",0,0,10) end -- this is the actual game (kinda) -- you'll call all the things that make up the game here, keeping them together game={} game._init=function() player._init() level._init() cart.update=game._update cart.draw=game._draw end game._update=function() player._update() level._update() end game._draw=function() player._draw() level._draw() end |
The in your system init you call whatever you want
function _init() title._init() end |
This might feel a little verbose, and maybe it is, but it's been easy for me to understand and follow where I've put game functions. It also lets me easily call modes from any other mode without having to do much. When I need to start a new level, just call game._init() and it takes care of everything.
This has also saved my butt when I think, "I don't need all this extra stuff" and I just put things directly into the system update/draw functions...which inevitably need to change and grow bigger and bigger, at which point I wish I had put them into a separate functions.
@morningtoast that's pretty good approach. I will try something along those lines for my next game.
@chosanjuan It is going to be a bit tricky to figure out without seeing your code.
If the ball just hags in place it means that your moveball() function is not upddating for some reason. The moveball() should be stored inside your PLAY gamestate, which I believe you have stored under value 1.
If it is, I think the culprit might be your variables for the lives, ball etc. When you restart your game, your variables should be restarted as well. You can do this by warping the variables for ball,paddle, lives and whatever else you might have inside _init() function. Then, when you restart the game (go from gameover to intro for example) call _init() once again, so the values will be the same as when you started the game.
You should check visit Pico-8 Slack and IRC. In my experience, they are both great places to ask for programming help. Not to mention much faster!
@morningtoast That will take a little time to break my head from the "traditional" way of how I learned how to do this in the first place. Just looking over your suggestion, it seems like an innovative approach! AS Level27geek said, on my next game...
@Level27Geek Yeah, I can post it if you want to take a look through it. Your suspicions are probably spot on with where it's causing the issue, I'm just having problems trying to split it out so it doesn't just keep on doing the same thing or going into a dead loop playing the final lostball noise. Wish there was a cart reset function to bring it back to the first init. That would be cheap and fix my problem without doing too much. Unfortunately, it's also really lazy programming and more of a bandaid rather than learning how to fix the actual issue.
As an aside...
This isn't markedly different, really, but you might like this format for, e.g., your 'game' setup:
game= { _init=function() player._init() level._init() cart.update=game._update cart.draw=game._draw end, _update=function() player._update() level._update() end, _draw=function() player._draw() level._draw() end } |
Makes it feel a bit more like a struct/class, that's all. It saves three tokens, but eh, that's not much. Mostly it's just personal taste for how you like to write/read/maintain code. Just thought I'd mention it as an option.
@Felice - Cool, thanks for the tip. Definitely better way to keep things together. I wanna say I tried to do that once and I got an error so I just did it with straight dot notation...I probably forget a comma or something. Anyway...thanks!
@chosanjuan: You can restart your cart all together by using run() in your code.
You can put something like this when you lose your last ball:
function reset() if btnp(4) or btnp(5) then run() end end |
@Level27Geek I knew that command was there but didn't think that it was the way to use it! Mind blown! I'll toss it in there and see if I like the results. I just don't want to get into being lazy. Regardless, this is a great fix for the time being. THANKS!
[Please log in to post a comment]