ZFGC

Resources => Coding => Topic started by: Scooternew on April 28, 2006, 12:16:45 am

Title: [Example / Listing] Freezing the Game for a Menu
Post by: Scooternew on April 28, 2006, 12:16:45 am
Again, not quite a tutorial, but just another perspective and helpful method of something.

When creating Zelda games, it is useful to create a menu....obviously. When the menu is created, though, nothing should move. Nothing should do anything when the menu is open. Realize, though, that deactivating all instances will also disable drawing their sprite. So, here is what you do in the creation of the menu object:

Code: [Select]
s = surface_create(view_wview,view_hview);
surface_set_target(s);
draw_clear_alpha(c_black,0);
screen_redraw();
draw_set_blend_mode_ext(bm_inv_dest_alpha,bm_one);
draw_set_color(c_black);
draw_rectangle(view_xview,view_yview,view_xview+view_wview,view_yview+view_hview,0);
draw_set_blend_mode(bm_normal);
surface_reset_target();
instance_deactivate_all(1);
Now, let me explain what this does. First of all, it creates a surface on whic the screen will be drawn. All graphics on the screen are captured onto this surface. Then, all instances are deactivated, all of their drawing stops, but the menu object is still activated. In the draw event, all you must do is draw the surface onto the screen, redrawing all of the previous graphics that aren't drawn when deactivated. Even so, there is a slight problem. Surfaces have a weird error in which rather than combining alpha values on top of each other (.3 + .4 = .7), only the last alpha value is drawn (.3 + .4 = .4). To remedy this, first, the whole surface is cleared (draw_clear_alpha), and then after the sccreen is captured, a special blend mode is set. A black rectangle is drawn, but since the blend mode forces black to become transparent, it resets the alpha to 1 without actually adding or drawing anyhting else to the screen! This fixes any alpha problems there might be in a simple, quick line of code.

When you are ready to exit the menu, make sure to free the surface from memory (surface_free(s)), reactivate everything (instance_activate_all()), and destroy the menu instance.

I like this apporach because I don't have to deal with technicalities of going to another room or manually stopping ecah and every object's speed, image_speed, sound, etc. to give the impression of the game being paused. This method actually pauses the game AND fixes transparency values, also in the quickest possible way.

Thank you, and goodnight. Crap, I overcomplicate things.
Title: Re: Freezing the Game for a Menu
Post by: AoDC on April 28, 2006, 12:32:16 am
Very interesting. That would save 100's of lines of code tosome Zelda engines I have seen. Great job, Scooter ^_^
Title: Re: Freezing the Game for a Menu
Post by: Scooternew on April 28, 2006, 12:45:09 am
Hehe thanks. Seems most simple to me, as it takes care of everything when the menu is open.
Title: Re: Freezing the Game for a Menu
Post by: FarFromHomeFish on April 28, 2006, 04:59:57 am
Excellent example! Your way of getting around the alpha problems is ingenous. Moving to another room when you pause your game is an ugly heck; you've shown everyone that there is another way. =)
Title: Re: Freezing the Game for a Menu
Post by: Scooternew on April 28, 2006, 10:10:47 pm
I'm glad. I hate moving to another room.

And the alpha blending annoyed the hell out of me.
Title: Re: Freezing the Game for a Menu
Post by: Lightz on April 28, 2006, 11:25:34 pm
Wow very insightfull way of looking at it.
Title: Re: Freezing the Game for a Menu
Post by: Cassyblanca on May 01, 2006, 02:49:06 pm
Or a far simpler way to do this (and one that would work across all languages) is to have a global variable (lets just use a boolean value bMenuMode), and in that variable store whether the menu is on (bMenuMode = true) or off (bMenuMode = false). In the A.I. (whether it's just moving up and down or more advanced), you first check if bMenumode is true or false. If it's true, then dont perform AI systems.

Example:
Code: [Select]
(enemy AI)
if bMenuMode is true
    do nothing
if bMenuMode is false
    perform AI (move up & down, etc.)

Then you can perform menu controls (switching items, etc) without worrying about affecting the game, and you can easily change whether things are done <.<
Title: Re: Freezing the Game for a Menu
Post by: Dayjo on May 01, 2006, 03:31:40 pm
True Min, but that'd require doing that for every object...
Title: Re: Freezing the Game for a Menu
Post by: Cassyblanca on May 01, 2006, 03:49:04 pm
Yeah, but it's more easily understood by users if your project is open-sourced <.<
Title: Re: Freezing the Game for a Menu
Post by: mit on May 01, 2006, 07:53:15 pm
Actually, Scooternew's is better than each object having a variable whether to calculate things. You could repeat the code using parents, but, because GM calculates things like speed by itself, they'd keep going, so you'd have to have several more lines of code remembering what these variables were, and setting them to zero, and afterwards setting them back - essentially deactivating the instance. Other than using surfaces, you could take a screenshot and redraw it, but that wouldn't be as good. Or you could freeze the current step, and have a little loop checking keyboard_lastkey as some have done, but that makes things like animation over-complicated. All in all, Scooternew's method is best.
Title: Re: Freezing the Game for a Menu
Post by: aab on May 01, 2006, 09:05:50 pm
It seems more similar to what a non-gm game would do.
In OOT its obvious that they take a screen render and redraw it as it is filtered into a quantized bit depth as the menu blends in.
Back on the Snes and Nes there would be limitations on this kindof thing: much less memory and especially limited image size.
They might sometimes have rendered everything withought updating logic (as in a game, logic and rendering would be very seperate: a common construction in a game is to eg have an Update() and a Render(), thus allowing seperate use for each, for either tweening, render-frame skipping or filling the back behind a menu; Using this method would allow for animations to continue on the objects behind the menu, but were talking GM here so ill just stop now.). But copying the screen buffer > having a value as to wether to update logic or not. The condition to check logic would be run through all the time of the game, and used frequently, which makes it instantly less practical.
Title: Re: Freezing the Game for a Menu
Post by: Scooternew on May 01, 2006, 09:30:02 pm
Interesting info, aab.

Wow - this got a lot replies. The concept is simple, but most people wouldn't know how to do it. THe most annoying this was the surface alpha bug, where only the last transparency drawn is kept, rather than combining alpha. It screwed me up because when I pause the menu when the background has rain, a black rectangle is drawn to give the impression of darkness, and the alpha bug screwed it all up.

With this method, you don't have to keep track of everything, which seems most practical and simple to me.
Title: Re: Freezing the Game for a Menu
Post by: Master J on May 11, 2006, 12:14:27 pm
More Efficient:

Code: [Select]
surface = surface_create(view_wview[0], view_hview[0]);
surface_set_target(surface);
draw_clear_alpha(0, 0);
screen_redraw();
surface_reset_target();
instance_deactivate_all(1);

Be more specific about the views in the room.
Title: Re: Freezing the Game for a Menu
Post by: Scooternew on May 11, 2006, 08:39:34 pm
This isn't more efficient. Doing code that doesn't do what mine does anyway doesn't really mean much.

Either way, this topic is old, so I'll lock it.

Contact Us | Legal | Advertise Here
2013 © ZFGC, All Rights Reserved