I'll start out by saying that this method for making a pause function is not the simplest there is, but is quite effective and has rewarding consequences. A modification of what I have here allows for "fixed frame-rate" games that can run in turbo mode effectively.
Note: This may require massive re-writing of your code. It may be that this is not practical for a current project, although you might keep it in mind for a future one.
The way I'm going to describe lies in the logical structure of your program. Although there may be many complicated sub-procedures, every game has three crucial actions:
when I receive [StartGame v] broadcast [Initialize v] and wait forever broadcast [Update v] and wait broadcast [Draw v] and wait endRemember that you can always add broadcasts in here, since every game is different. Remember as well that the "and wait" part is critical.
when I receive [StartGame v] // In central sprite broadcast [Initialize v] and wait forever broadcast [CheckPaused v] and wait if <(Paused?) = [false]> broadcast [Update v] and wait broadcast [Draw v] and wait end end when I receive [CheckPaused v] if <key [p v] pressed?> set [Paused? v] to [true] else set [Paused? v] to [false] end
Last edited by amcerbu (2012-05-10 20:56:32)
Offline
Put this in the beginning of all forever scripts and right before the scripts under all when I receive scripts:
if <(variable) = (1)> wait until <(variable) = (2)> endAnd for the pause button:
when [sprite] clicked next costume
when gf clicked forever if <(costume#) = (1)> set [variable v] to (1) end if <(costume#) = (2)> set [variable v] to (2) endYou can add show if the variable is 2 and hide if the variable is 1 to the pause menu script.
Last edited by shpeters (2012-05-10 20:55:26)
Offline
The easiest way to do it if you have all your sprites in loops is to have an if-else structure that depends on a variable (probably called pause):
forever if <(pause) = (1)> broadcast [menu v] //this would only be needed in one or none of the sprites else all other code endThen you simply have another script that cycles the variable pause. This can be done with this inside whatever event you want to trigger/untrigger a pause:
set [pause v] to (((pause) + (1)) mod (2))Hope that helped!
Offline
amcerbu wrote:
I'll start out by saying that this method for making a pause function is not the simplest there is, but is quite effective and has rewarding consequences. A modification of what I have here allows for "fixed frame-rate" games that can run in turbo mode effectively.
Note: This may require massive re-writing of your code. It may be that this is not practical for a current project, although you might keep it in mind for a future one.
The way I'm going to describe lies in the logical structure of your program. Although there may be many complicated sub-procedures, every game has three crucial actions:when I receive [StartGame v] broadcast [Initialize v] and wait forever broadcast [Update v] and wait broadcast [Draw v] and wait endRemember that you can always add broadcasts in here, since every game is different. Remember as well that the "and wait" part is critical.
This script is executed by some "central" control sprite, that tells the rest of the game what to do.
By installing "when I receive Initialize," "when I receive Update," and "when I receive Draw" hats in each of your sprites, you can control exactly what is happening at any time. This is much easier to deal with than many forever loops. This also defines a "frame": one repetition of the "forever" loop.
Initialize makes sure the starting values of each sprite are correct (i.e. they're in the right positions, etc.).
Update sends commands for sprites to change their internal variables, receive input from the keyboard, etc. In my games, I prefer not to directly use "set x to (0)" blocks in the update. Instead, you store the desired position value, appearance variable, or other characteristic, to be assigned later in...
Draw tells all the sprites to update their positions and appearances as necessary. During this broadcast, sprites will "go to x: (desiredX) y: (desiredY)". The important thing to notice is that this ensures that all sprites move at the same time.
Since the entire game is controlled by a single forever loop, all a pause function has to do is restrict execution of the loop.when I receive [StartGame v] // In central sprite broadcast [Initialize v] and wait forever broadcast [CheckPaused v] and wait if <(Paused?) = [false]> broadcast [Update v] and wait broadcast [Draw v] and wait end end when I receive [CheckPaused v] if <key [p v] pressed?> set [Paused? v] to [true] else set [Paused? v] to [false] end
I'm a bit lost with that big chunk of text. Could you simplify it?
Offline
Basically, instead of having a bunch of forever loops in each sprite, you have a bunch of "when I receive Update" hats (with no forever loop underneath). If you have one sprite controlling all the others, you can easily pause the game. Check out the scripts in Music Marathon to see this in action.
Offline
I'm remixing it to show you what I mean (I'll post it to my test account at some point today or tomorrow).
One thing, though: I'm gonna have to change the "glide" commands in the enemy sprites. I'll make sure the motion looks the same, but you can't stop a sprite in the middle of a glide without also stopping the script (which we don't want to do).
Also, because of the way you've set up your movement commands, it would be too much of a hassle to implement a draw method, so the control script I mentioned above will be slightly modified (it won't contain the "broadcast 'Draw' and wait" block).
Offline
Okay, I added a pause function, which currently works with every game element except the enemies. One of the big things I had to deal with was the "glide" functions, which you can't pause (it's one of the few blocks in Scratch that doesn't execute immediately, along with the "wait () seconds" block).
Anyway, the enemy appears after 60 seconds, the blue orb appears as well (you can collect it), you can shoot the projectile at the enemy, the enemy will take damage, the fuel tank appears after your fuel is less than 100, and the red orb will fire once every 5 seconds or so.
Air Raid Modified
Last edited by amcerbu (2012-05-13 02:04:10)
Offline