Grayscale Pause Module

Started by Gal Shemesh, Tue 19/09/2023 16:09:01

Previous topic - Next topic

Gal Shemesh

About
This module basically pauses the game upon call, takes a screenshot, and then draws that screenshot onto the screen as an overlay, with a nice touch of fade animation.

You enter the grayscale pause using the grayscale.FadeIn() function. Then you can show other elements on screen such as GUIs or close-up graphics for the player to interact with. When you're done, you exit from it using the grayscale.FadeOut() function, which fades back to full color and unpause the game.

This is the first module that I've created in AGS and I'm happily sharing it so everyone could enjoy and use it.

This module couldn't be done without the help of @Nahuel and @Crimson Wizard who assisted and directed me in the right way to making it work - thanks guys! I've credited you both in the module.

The idea behind making this module was to reproduce the same effect that exists in an old adventure game that I'm currently re-producing with captions, called "The Riddle of Master Lu" - in that game, when you opened GUIs during gameplay or examined inventory items which showed a close-up graphic of them, the entire screen went grayscale so the player won't be distracted by the surrounding but only by the specific GUI or close-up  graphic that was opened.

Attached an example how this module looks like in my reproduction game:


You may download the module from my personal dropbox.

Module was updated with the MIT license agreement as suggested in the forum guidelines. It is free for non-commercial AND commercial use - only request is to please credit authors if used.

Enjoy! :)


Changelog
=========
Version: 1.2.0
Released: 20th Septembre 2023
Notes: Added Original User GUI Hidden and Visible again during FadeIn/Out

Version: 1.1.0
Released: 20th Septembre 2023
Notes: Added TweenModule compatibility & Licence to header. by Nahuel

Version: 1.0.1
Released: 19th Septembre 2023
Notes: Added license. by Gal Shemesh.

Version: 1.0.0
Released: 19h Septembre 2023
Notes: Initial release. by Gal Shemesh

RootBound

Hey @Gal Shemesh just wanted to let you know I'm using this module in the game I'm currently working on. Thanks for making it. :)
They/them. Here are some of my games:

Gal Shemesh

Quote from: RootBound on Sat 21/09/2024 19:42:00Hey @Gal Shemesh just wanted to let you know I'm using this module in the game I'm currently working on. Thanks for making it. :)
I'm very glad you find it useful. I really like how it turned out, and not only because it's mine. It sure adds a lot to the game. Enjoy! :)

RootBound

#3
@Gal Shemesh Mostly the module works great, but I may have found two possible bugs.

1. You have
Code: ags
if ( userGUI ) userGUI.Visible = false;
within the FadeIn function and
Code: ags
if ( userGUI ) userGUI.Visible = true;
within the FadeOut function.

For me, this produced the opposite of the intended effect, removing GUI during fade in and making it visible after fade out. I swapped the two lines of code, and this fixed the problem.

2. Another issue I had was that my game involves hundreds of overlays, and the grayscale screenshot was appearing behind some of them. While this can produce very cool effects like having most of the screen be grayscale while some objects remain in color, that's not really the intended behavior of the module. Events that are in any of the game's repeatedly_execute_always functions will also continue to play when the game is paused, and if this involves overlays, this too can happen on top of the screenshot.

I fixed this by giving my pausegame GUI a very high ZOrder (1000), and then I added this statement to your module:
Code: ags
if( userGUI ){
      screenOverlay.ZOrder = userGUI.ZOrder-1;
    }
This fixed the problem for me by making the grayscale screenshot appear on top of all the overlays (which have ZOrder under 1000), but below the pausegameGUI. Unfortunately, this  would not fix the issue if the user does not pass a GUI when calling the function, or if the user does not put a high enough ZOrder on their GUI.


On a more positive note, I also made, for my game, some changes and additions to the module, if you're interested.

First, I changed the location of
Code: ags
if ( userGUI ) userGUI.Visible = true;
to before the screenshot is taken, which includes the GUI in the screenshot.

Then I changed the location of
Code: ags
if ( userGUI ) userGUI.Visible = false;
to BEFORE the fadeout, which means that the GUI fades out along with the grayscale screenshot, which I thought was a nice effect. Sadly, I don't think it's possible to have the GUI fade in along with grayscale screenshot without putting in separate fade-in code for the GUI itself (which is possible, but more complicated than fading it out with the screenshot).

I also added a speed parameter to both the fade in and fadeout functions:
Code: ags
static function grayscale::FadeIn(GUI* userGUI, int FadeSpeed)

and then used that parameter in the fading wait delay within each function:
Code: ags
    Wait(FadeSpeed); 
So now the user can set the speed of the fade, with 0 being an instant switch to grayscale and higher numbers increasing the slowness of the fade.

IMPORTANT CAVEAT: I don't know if this will work if you use the tween module (I am not using it).

EDIT:
Another caveat on adding the FadeSpeed parameter: because the screenshot fades its transparency in increments of 5% each update, passing a wait number above 6 or so for the speed makes the transition look a bit choppy. But I kept the transition speed at 5% each update because it allows for faster fading, whereas fading by 1% percent each update would be slow even at Wait(1).

I hope this is useful :)
They/them. Here are some of my games:

Gal Shemesh

It seems like you made good modifications to the module to suit your project. One can make a great module and yet it still might not work out of the box for every game and would require some modifications. But that's also the beauty of it, as anyone could take its initial state and tune it to their liking.

And thanks for all the info you provided! I'm sure anyone who visits here may make good use of it.

glurex

Something particularly interesting about the new version 3.6.2 is that it's no longer necessary to hide the mouse before saving the DynamicSprite-type screenshot of the screen. With the new render layer option, you can take a screenshot of the room without the cursor being captured:

Code: ags
screenToGrayscale = DynamicSprite.CreateFromScreenShot(0, 0, eRenderLayerRoom);

In my opinion, this looks much more elegant and benefits this module.

SMF spam blocked by CleanTalk