Jibble

Author Topic: Need help with DynamicSprite / Overlay  (Read 238 times)

Need help with DynamicSprite / Overlay
« on: 18 Oct 2021, 22:50 »
I've been working on a new rain module which will suit my aesthetic a bit better than some of the other ones out there.

After looking at a lot of pixel art, I find the most realistic ones don't animate the raindrops, but just randomly place them, but simulate refraction of the light and slightly desaturate and lighten from the background.

I think I'm on the right track, but there isn't a lot of detailed information about DynamicSprite and drawing surfaces (If I'm incorrect, please direct me to the relevant part of the tutorial!)

My code is posted below, I think that I need to create an overlay and draw a bunch of raindrops onto it, then reset it for the next rain. should be pretty lightweight if it works!

Thanks in advance to anybody who can help me with this!


Code: Adventure Game Studio
  1.  
  2. function makeItRain(){
  3.  
  4.   //  set/reset overlay, using a sprite which is the same as the screensize, transparent colour
  5.   //  overlay  = sprite 1234, etc...
  6.  
  7.   int howMuchRain = 10;             //to make 10 raindrops at a time
  8.   int rainDropLength = 20;          //each drop is 1 pixel wide, 20 pixels long
  9.  
  10.   for (int i = 0; i < howMuchRain; i++)
  11.   {  
  12.     int coordX = Random(359);
  13.     int coordY = Random(170);       //find random places for the raindrops
  14.    
  15.   DynamicSprite* raindrop1 = DynamicSprite.CreateFromBackground(GetBackgroundFrame(),
  16.                                                                 coordX, coordY, 1, rainDropLength);
  17.                                                                 //makes a raindrop from the background image
  18.                                                                 //would be better if it was from a screenshot,
  19.                                                                 //so includes objects, characters
  20.   raindrop1.Tint(1, 1, 1, 20, 100); //slightly lighten and desaturate each drop
  21.  
  22.   DrawingSurface *surface = myOverlay;  //draw on the overlay
  23.  
  24.   surface.DrawImage(coordX, coordY-1, raindrop1.Graphic);       //place the raindrop 1 pixel higher than it's source
  25.                                                                 //creating a light refraction effect
  26.   surface.Release();
  27.   raindrop1.Delete();  
  28.   }
  29. }
  30.  
  31. [/code/
« Last Edit: 19 Oct 2021, 02:22 by timid_dolphin »

Re: Need help with DynamicSprite / Overlay
« Reply #1 on: 21 Oct 2021, 08:43 »
Okay, after going through a lot of old forum posts and rereading the manual a thousand times, I think I'm starting to get my head around these things.

For now I'm testing this in a global late_repeatedly_execute_always()

It's beginning to look kind of ok. I really want the for loop to render x amount of raindrops, and it seems to only do one at a time each time this function is called.
But if I remove the for loop, the 'rain' stops when the player exits the first room.
Any ideas why it's behaving this way?

(DynamicSprite raindrop1 and Overlay surface are defined as in global variables.)

Code: Adventure Game Studio
  1. int howMuchRain = 10;             //to make 10 raindrops at a time
  2. int rainDropLength = 50;          //each drop is 1 pixel wide, 50 pixels long
  3.  
  4. function makeItRain()
  5. {
  6.   if(!IsGamePaused())
  7.   {
  8.     if(rainDrop1 != null)
  9.     {
  10.     //  rainSurface.Remove();
  11.     }
  12.  
  13.      for (int i = 0; i < howMuchRain; i++)
  14.     {  
  15.       int coordX =  Game.Camera.X + 1 + Random(Game.Camera.Width - 2);
  16.       int coordY =  Game.Camera.Y + 1 + Random(Game.Camera.Height - rainDropLength - 2);
  17.      
  18.       rainDrop1 = DynamicSprite.CreateFromBackground(GetBackgroundFrame(), coordX, coordY, 1, rainDropLength);
  19.       rainDrop1.Tint(1, 1, 1, 30, 100);
  20.       rainSurface = Overlay.CreateGraphical(coordX - Game.Camera.X, coordY - 1 - Game.Camera.Y,  rainDrop1.Graphic, true);
  21.       //raindrop1.Delete();
  22.     }
  23.   }
  24. }
  25.  
  26.  
« Last Edit: 22 Oct 2021, 21:43 by timid_dolphin »

Re: Need help with DynamicSprite / Overlay
« Reply #2 on: 23 Oct 2021, 05:57 »
This feels weird replying to myself to help myself, perhaps reason to spend a little longer reading the manual before posting in this forum. I'll do it anyway, because this could be helpful to other beginners who want to get into the cool weird parts of the AGS engine!

so I create a DynamicSprite from a fully transparent screen sized sprite (slot 1234),

make a DrawingSurface from the DynamicSprite,

then the for-loop creates raindrops from the background image and draws them onto the DrawingSurface one pixel up from the source.

then I create a graphical Overlay from the background sprite which has been drawn on.

There's a timer there which slows them down a bit so they're not flickering every game loop but closer to a film frame rate.

It looks about as good as I would expect at this basic level. More could be done to make it more generalised and adaptable for different purposes.

It also needs another layer of 'splash' effects as rain drops hit the ground, which could be a variation on the same algorythm but with single pixels randomly appearing within a  few defined rectangles representing flat surfaces.

The effect could be more improved with customised animations of slower drips coming off the edges of surfaces etc.

I'm certain it will look cool when it's done!

Code: Adventure Game Studio
  1. //rainDrop1 and rainOverlay are defined as global variables
  2.  
  3. int howMuchRain = 10;             //to make 10 raindrops at a time
  4. int rainDropLength = 20;          //each drop is 1 pixel wide, 20 pixels long
  5.  
  6. DynamicSprite *rainBackground;
  7. DrawingSurface *rainDrawingSurface;
  8.  
  9. function makeItRain()
  10. {
  11.   if(!IsGamePaused())
  12.   {
  13.     if(rainDrawingSurface != null)
  14.     {
  15.       rainDrawingSurface.Clear();
  16.     } else {
  17.       rainBackground = DynamicSprite.CreateFromExistingSprite(1234);
  18.       rainDrawingSurface = rainBackground.GetDrawingSurface();
  19.     }
  20.       if(Game.DoOnceOnly("initRain")){
  21.       SetTimerWithSeconds(13, 0.1);
  22.     }
  23.     if(IsTimerExpired(13))
  24.     {
  25.       for (int i = 0; i < howMuchRain; i++)
  26.       {
  27.         int coordX =  Game.Camera.X + 1 + Random(Game.Camera.Width - 2);
  28.         int coordY =  Game.Camera.Y + 1 + Random(Game.Camera.Height - rainDropLength - 2);        
  29.         rainDrop1 = DynamicSprite.CreateFromBackground(GetBackgroundFrame(), coordX, coordY, 1, rainDropLength);        
  30.         rainDrop1.Tint(1, 1, 1, 30, 100);
  31.         rainDrawingSurface.DrawImage(coordX, coordY-1, rainDrop1.Graphic);
  32.       }
  33.       rainOverlay = Overlay.CreateGraphical(0, 0, rainBackground.Graphic, true);
  34.      
  35.       SetTimerWithSeconds(13, 0.15);
  36.     }  
  37.   }
  38. }
  39.  
  40. function late_repeatedly_execute_always()
  41. {
  42.   makeItRain();
  43. }
  44.  
  45.  
  46.  

Cassiebsg

  • Cavefish
  • Fleeing the Cylon tyrrany...
    • Cassiebsg worked on one or more games that won an AGS Award!
    •  
    • Cassiebsg worked on one or more games that was nominated for an AGS Award!
Re: Need help with DynamicSprite / Overlay
« Reply #3 on: 23 Oct 2021, 22:06 »
Just wanted to say to keep posting.  (nod)
My experience with dynamic sprites is rather limited, so I can't help, but I always enjoy reading and learning. :)
There are those who believe that life here began out there...

Re: Need help with DynamicSprite / Overlay
« Reply #4 on: 24 Oct 2021, 23:17 »
Thanks!

I may not even use this as a rain machine, but it's been cool to learn about all this stuff, there's so much potential for other weird special effects, like you could use parts of this function to make the whole room drip with blood and melt away or something, or VHS glitch effects?