Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Screen fade in/out technique

  1. #1

    Screen fade in/out technique

    I'd like to implement a screen fade out > screen fade in feature between screens in my game.

    What would you recommend as the fastest/easiest technique?

  2. #2

    Screen fade in/out technique

    Well, with 8 bit colour modes this was very easy. In pseudocode:
    [pascal]
    for i:=0 to 255 do
    begin
    wait_for_vertical_retrace;
    for j:=0 to 255 do
    with palette[i] do
    begin
    if red>0 then
    dec(red);
    if green>0 then
    dec(green);
    if red>0 then
    dec(blue);
    end;
    write_new_palette_to_vga;
    end;
    [/pascal]

    With higher colour modes, you can also decrease the colours, but then you need to do this on the full framebuffer instead of just the palette. In many situations, it will require a 2d accelerator to do it fast enough in high colour modes.

    So check if 8 bit colour is enough for your needs, and then see what to do.

  3. #3

    Screen fade in/out technique

    There are two ways, but the second is the most efficient.

    1. You could, based on a specific event/flag, etc, fade all items out on the screen simultaneously. While this might lead to a neat unorthodox fade-out effect, lots of alpha rendering takes a large amount of video power; it may not work on most systems.

    2. The best way is to draw a rectangle over the whole screen for your fade out; you can pick any color you like to make another effect (red pain flashes, white lighting glare, etc) but you must always vary the opacity. And easy way to do so is to use a float value for your fade in/out, 0 is hide and 1 is show, and multiply it by 255 -- for good programming practice wrap that in a "round()" conversion to make certain there wouldn't be an overflow or type assignment bug.

    In my recent Asphyre project I do it this way as a "hit effect" that makes the screen invert a little (except using the actual byte value). OnRender:[pascal] if damagedoverlay > 0 then
    AsphyreCanvas1.Rectangle(0,0,ClientWidth,ClientHei ght,cAlpha1(damagedoverlay),cAlpha1(damagedoverlay ),fxSub);
    [/pascal]OnProcess (be warned the alpha I set it to is an even number with no variance, I just reduce it by 2 for a rapid fadeout):[pascal] if damagedoverlay > 0 then
    damagedoverlay := damagedoverlay - 2;[/pascal]
    I honestly have no clue how to do it in (un)DelphiX. So that's how I do it in my own stuff in a similar fashion, although I declared the project done before I could have implemented any transition effects.

    Does that help any?

  4. #4
    Legendary Member cairnswm's Avatar
    Join Date
    Nov 2002
    Location
    Randburg, South Africa
    Posts
    1,537

    Screen fade in/out technique

    In openGL you can set the default drawing color. By moving this color from white to black you get a fade out effect.

    I dont know if this is possible in DelphiX.

    Drawing an alpha blended rectangle over the screen with an increasing alpha value will give you the best effect - but I havn't used it yet.
    William Cairns
    My Games: http://www.cairnsgames.co.za (Currently very inactive)
    MyOnline Games: http://TheGameDeveloper.co.za (Currently very inactive)

  5. #5

    Screen fade in/out technique

    It depends on how you´ve written your game.

    I've used the rectangle approach in Village Defense.
    However, it wasn't as easy as I had thought and I do recommend giving it some serious thoughts before implementing it in your game.

    In VD I used states to go from, for example, the menu to the optionsscreen. You've seen it probably before, but it basically looks something like this:

    [pascal]
    procedure TMyGame.mainLoop;
    begin
    (...)
    case gameState of
    gsMenu : drawMenu();
    gsOptions : drawOptions();
    gsrunGame : runGame();
    end;
    end;

    [/pascal]

    In this instance, when the user clicks the menuItem to go to the optionscreen I simply change gameState to gsOptions. Thats all there is to it.

    Btw, I must point out that the menu is not an object! Its nothing more than a simple procedure with a few function calls to draw the images and a few others to check mouse activity.

    Anyway, it becomes a whole different matter when I add fade effect. How are you going to implement that? Again with gamestates? I did,... but I wont be doing it again, that´s for sure!

    Imagine the user clicking on options:
    gamestate switches to gsFadeOutMenu :arrow: screen fades out :arrow: gamestate switches to gsFadeInOptions :arrow: screen fades in :arrow: gamestate switches to gsOptions.

    Thats a real nightmare to write and it gets worse with each additional section in the game. Especially if you want cross sections, where you can for example go from the game as well as the menu to the options screen or from the menu as well as from the game to highscorelist.

    I dont say its impossible, because I was able to get it to work. Be it with a few dirty tricks.

    I'm still not entirely sure what is a good solution. I believe a more OO approach might work, but I still need to work out the details on that, I'm afraid.

  6. #6

    Screen fade in/out technique

    I always split my functionality in an update and a render procedure.

    So in my gameengine.update I do things like this:

    Code:
      if UI.FadeDir = 1 then
      begin
        UI.FadeAlpha := min($FF, UI.FadeAlpha + 15*time_);
        if UI.FadeAlpha = $FF then
        begin
          // PERFORM THE REASON FOR FADEOUT HERE (eg change gamestate)
          UI.FadeDir := 2;
        end;
      end;
    
      if UI.FadeDir = 2 then
      begin
        UI.FadeAlpha := max($0, UI.FadeAlpha - 15*time_);
        if UI.FadeAlpha = $0 then
          UI.FadeDir := 0;
      end;
    Then in my UI.render I do this:

    Code:
      if &#40;FadeAlpha <> 0&#41; then
      begin
        DanJetX.Zbuffer &#58;= false;
        DanJetX.Primitives2D.Rectangle&#40;0,0,DanJetX.width,DanJetX.height,trunc&#40;FadeAlpha&#41; shl 24&#41;;
        DanJetX.Zbuffer &#58;= true;
      end;
    The point is, I don't need seperate gamestates for fading out or in. I just set UI.FadeDir to 1 and the show begins.



    PS: UI is my UserInterface class... and since this is always rendered after all other things, I perform the rectangle there, embedded in the User Interface. This way I can also set a flag if the whole screen should be faded or only game content and the UI remains...
    I think DelphiX has a rectangle function, so this is a really easy task to do.
    <a href="http://www.greatgamesexperiment.com/game/Valgard/?utm_source=gge&amp;utm_medium=badge_game"><img border="0" alt="GGE" title="GGE" src="http://static.greatgamesexperiment.com/badge/game/valgard/gge400x56.png"></a>

  7. #7

    Screen fade in/out technique

    I use a "gamestate" system like Traveler and therefore after everything has been rendered surely I only need to change the "darkness" of the screen immediately before the .doflip

    So how do I darken the surface quickly by a percentage amount?

  8. #8

    Screen fade in/out technique

    Did you not read my response, or must I quote myself?
    2. The best way is to draw a rectangle over the whole screen for your fade out; you can pick any color you like to make another effect (red pain flashes, white lighting glare, etc) but you must always vary the opacity. And easy way to do so is to use a float value for your fade in/out, 0 is hide and 1 is show, and multiply it by 255 -- for good programming practice wrap that in a "round()" conversion to make certain there wouldn't be an overflow or type assignment bug.
    Although I forgot you could just use a call to Min and be done with it.[pascal]Alpha := Min(Round(255*Percent,255)); // Percent is 0.0-1.0[/pascal]

  9. #9

    Screen fade in/out technique

    Quote Originally Posted by Robert Kosek
    Did you not read my response, or must I quote myself
    No, sorry I did read your reply, but I was sort of looking for something equivalent in DelphiX.

  10. #10

    Screen fade in/out technique

    Quote Originally Posted by Robert Kosek
    [pascal]Alpha := Min(Round(255*Percent,255)); // Percent is 0.0-1.0[/pascal]
    Yep, you print a big rectangle using drawalpha with delphix and for alpha value use the code above
    Will: &quot;Before you learn how to cook a fish you must first learn how to catch a fish.&quot; coolest

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •