Earthquake effect leaving trails of itself?

Started by meese72, Sun 17/07/2011 23:48:05

Previous topic - Next topic

meese72

I made an earthquake effect by using TweenShakeScreen, however was thinking of maybe adding where you see the whole screen leaving ghosts trails of itself during the shaking, like in cartoons, then fading out ???

I can try to do it myself, but its hard because I think I need to do dynamic drawing again (ugh, i loooove using that!!). I know, iknow I need to learn it still  :-[

Help for a damsel in distress ::)

BlueAngel

Hi, just thinking - maybe you can use the The AGS Tween Module and fade in copies of the background pictures (make the pictures objects perhaps)?

Dualnames

Hey, meese72, is it possible for you to illustrate the actual effect? Perhaps some footage from youtube?
Worked on Strangeland, Primordia, Hob's Barrow, The Cat Lady, Mage's Initiation, Until I Have You, Downfall, Hunie Pop, and every game in the Wadjet Eye Games catalogue (porting)

meese72


omg ill try to find something to show then i guess! lemme try to explain a bit better

ok Im not too good at this so bear with me! ok, imagine that for each screenshake thing, i guess it grabs the screen where the current shake frame is, and on the next shake, you can still see the last previous screen grabn slowly fade out, but over the current shake frame, half transparent or so. So everything is shaking, with each shake kinda leaving ghosts of itself fading away, see what I mean?? omg its kind of hard to explain, lol!!!

<Cringe> I hope thats clearer!??

meese72

Should I try to do a mock animation to explain better? I really would appreciate the help guys  :-*

Ryan Timothy B

Why not just get a free screen capture program and upload the video (high quality) for us to see, rather than a mock animation which may look nothing like the problem you're having.

meese72

oh hi! Well its not really a problem I have now, its more a new effect id like to create! Imagine an earthquake that moves the whole screen (like I can achieve now with shakescreen), but aded to that it grabs various screen frames, fades them out so it looks like its ghosting while shaking.

Watch this clip (of my johnny, who, omg, is soooo cute btw, hihi) at 6 seconds when he gets hit over the head with the bottle
http://www.youtube.com/watch?v=TGs6BS-q1E4

thats what I mean by ghosting the frames! now if only I  can do that to follow the shake of the screen  ??? 

meese72

I'm afraid it's not possible, right?  :'(

RetroJay

#8
Quote from: meese72 on Sat 23/07/2011 00:13:01
I'm afraid it's not possible, right?  :'(

Hi meese72.

I know exactly the effect you are after but I think your example vid doesn't show it that well.
What you are looking for is an effect like 'Tom and Jerry' when Tom gets hit over the head by Jerry. Am I right?
This effect used to happen, especialy, when Tom had his head hit with two cymbals.

I think maybe the effect you want IS possible... maybe.
However I don't know how to do it.

Sorry.
Jay

EDIT:
Just been thinking about this. Why not make a few extra full screen 'frames' and make an animation out of them?
When you need the effect animate it (eblock, true,once forward) until animation has finished.
In your 'paint' program take a copy of your main image and 'paste' it over your main image and off-set it slightly with less opacity and so on.
Use these as your animation.

Just a thought. :-\
You could get a fairly good effect that way... I think.

EDIT:
Maybe even. Make copys of your room frames and lower the opacity and off-set them slightly and put them in 'Animating backgrounds' of your room.
These are all thoughts, though, and none of them may work... Give it a try though. :)

EDIT AGAIN:
You have, REALY, got me thinking about this.
I am, almost, certain that someone created a 'drunk module' although I may be wrong. :-\
If they did then this might be helpfull... Or not.

Only trying to help.
Jay.

OneDollar

#9
Do you mean something like this?

The best way would be to do it with drawing functions. Basically what you want to do is store the previous few frames (3 in my example) then draw them on top of the current frame at various levels of transparency (older frames being more transparent).

The problem with doing that while using the ShakeScreen is that its a blocking function. You could probably set something up in repeatedly_execute_always() to store and draw the previous frames, but you'd need some way of avoiding capturing the current frame's blur (turn off your overlay before taking the screenshot?) otherwise you'd get infinite ghosting. I played around with that idea for a bit, but I couldn't get it working so I just wrote a custom screen shaking function that had ghosting built in. I also cheated a bit - during a screen shake the screen is a static image, so I just kept drawing the same image, but at different positions and different transparencies.

The code's not great, but it might give you some ideas.

Code: ags

function TrailShakeScreen(int Speed, int Amount, int Length, int Severity) {
  //Speed = frames to wait after updating.
  //Amount = pixels to move each Speed number of frames.
  //Length = time in frames the effect lasts for (plus start and end).
  //Severity: Screen will shake between + and - Severity pixels.
  
  Overlay* EffectsOverlay; //Overlay to display the effect on screen.
  DynamicSprite* EffectsSpriteScreenCopy; //Holds a copy of the original screen (before bluring).
  DynamicSprite* EffectsSpriteCombined; //Holds blurred screen.
  DrawingSurface* EffectsSurface; //Surface for creating the blurred screen.
  int Timer = 0; //Timer for counting when the effect should stop.
  int Positions[4]; //Array for holding positions of previous screen copies.
  
  //Take a copy of whatever's on the screen so we can draw it later
  EffectsSpriteScreenCopy = DynamicSprite.CreateFromScreenShot(640, 480);
  
  //Draw it offset on Combined sprite
  EffectsSpriteCombined = DynamicSprite.Create(640, 480, false);
  EffectsSurface = EffectsSpriteCombined.GetDrawingSurface();
  EffectsSurface.DrawImage(Amount, 0, EffectsSpriteScreenCopy.Graphic, 0);
  
  //Now draw a slightly transparent copy on top of that one at the original location
  EffectsSurface.DrawImage(0, 0, EffectsSpriteScreenCopy.Graphic, 25);
  
  //Release the surface to update the sprite
  EffectsSurface.Release();
  
  //Update the graphics of the overlay to reflect our drawing
  EffectsOverlay = Overlay.CreateGraphical(0, 0, EffectsSpriteCombined.Graphic, false);
  
  //Wait while the effect displays on the screen
  Wait(Speed);
  
  //Draw screen and transparent offsets, show and wait
  EffectsSurface = EffectsSpriteCombined.GetDrawingSurface();
  EffectsSurface.DrawImage(2*Amount, 0, EffectsSpriteScreenCopy.Graphic, 0);
  EffectsSurface.DrawImage(Amount, 0, EffectsSpriteScreenCopy.Graphic, 25);
  EffectsSurface.DrawImage(0, 0, EffectsSpriteScreenCopy.Graphic, 50);
  EffectsSurface.Release();
  EffectsOverlay = Overlay.CreateGraphical(0, 0, EffectsSpriteCombined.Graphic, false);
  Wait(Speed);
  
  //Set 'Positions' of the four screen copies
  Positions[0] = 0;
  Positions[1] = 0;
  Positions[2] = Amount;
  Positions[3] = 2*Amount;
  
  //We are now ready to loop with three 'ghost' screens
  while (Timer <= Length) {
    //If the screen has moved 'Severity' pixels to the left or right, reverse the motion
    if ((Positions[3] > Severity) || (Positions[3] < -Severity)) {
      Amount = -1*Amount;
    }
    //Update the positions of the screens
    Positions[0] = Positions[1];
    Positions[1] = Positions[2];
    Positions[2] = Positions[3];
    Positions[3] += Amount;
    //Draw screen and transparent offsets, show and wait
    EffectsSurface = EffectsSpriteCombined.GetDrawingSurface();
    EffectsSurface.DrawImage(Positions[3], 0, EffectsSpriteScreenCopy.Graphic, 0);
    EffectsSurface.DrawImage(Positions[2], 0, EffectsSpriteScreenCopy.Graphic, 25);
    EffectsSurface.DrawImage(Positions[1], 0, EffectsSpriteScreenCopy.Graphic, 50);
    EffectsSurface.DrawImage(Positions[0], 0, EffectsSpriteScreenCopy.Graphic, 75);
    EffectsSurface.Release();
    EffectsOverlay = Overlay.CreateGraphical(0, 0, EffectsSpriteCombined.Graphic, false);
    Wait(Speed);
    //increase timer
    Timer ++;
  }
  
  //Slow blurring back down
  while (Positions[3] != 0) {
    if (Positions[3] < 0) {
      //Need to go right to get to center. Make Amount positive.
      if (Amount < 0) Amount = -1*Amount;
    }else{
      //Need to go left to get to center. Make Amount negative.
      if (Amount > 0) Amount = -1*Amount;
    }
    //Update positions
    Positions[0] = Positions[1];
    Positions[1] = Positions[2];
    Positions[2] = Positions[3];
    Positions[3] += Amount;
    //Draw screen and transparent offsets, show and wait
    EffectsSurface = EffectsSpriteCombined.GetDrawingSurface();
    EffectsSurface.DrawImage(Positions[3], 0, EffectsSpriteScreenCopy.Graphic, 0);
    EffectsSurface.DrawImage(Positions[2], 0, EffectsSpriteScreenCopy.Graphic, 25);
    EffectsSurface.DrawImage(Positions[1], 0, EffectsSpriteScreenCopy.Graphic, 50);
    EffectsSurface.DrawImage(Positions[0], 0, EffectsSpriteScreenCopy.Graphic, 75);
    EffectsSurface.Release();
    EffectsOverlay = Overlay.CreateGraphical(0, 0, EffectsSpriteCombined.Graphic, false);
    Wait(Speed);
  }
  //Returned to center, fade out screen copies.
  EffectsSurface = EffectsSpriteCombined.GetDrawingSurface();
  EffectsSurface.DrawImage(Positions[3], 0, EffectsSpriteScreenCopy.Graphic, 0);
  EffectsSurface.DrawImage(Positions[2], 0, EffectsSpriteScreenCopy.Graphic, 50);
  EffectsSurface.DrawImage(Positions[1], 0, EffectsSpriteScreenCopy.Graphic, 75);
  EffectsSurface.Release();
  EffectsOverlay = Overlay.CreateGraphical(0, 0, EffectsSpriteCombined.Graphic, false);
  Wait(Speed);
  EffectsSurface = EffectsSpriteCombined.GetDrawingSurface();
  EffectsSurface.DrawImage(Positions[3], 0, EffectsSpriteScreenCopy.Graphic, 0);
  EffectsSurface.DrawImage(Positions[1], 0, EffectsSpriteScreenCopy.Graphic, 70);
  EffectsSurface.Release();
  EffectsOverlay = Overlay.CreateGraphical(0, 0, EffectsSpriteCombined.Graphic, false);
  Wait(Speed);
  
  //Dispose of sprites and overlay
  EffectsSurface.Release();
  EffectsOverlay.Remove();
  EffectsSpriteCombined.Delete();
  EffectsSpriteScreenCopy.Delete();
}

function room_AfterFadeIn()
{
  Wait(40);
  TrailShakeScreen(1, 5, 100, 10);
  Wait(80);
  QuitGame(0);
}


Edit: Changed code to work with DX9 and 32-bit colour depth. Also this is for 640x480 res, so change the EffectsSpriteScreenCopy = DynamicSprite.CreateFromScreenShot(640, 480); and EffectsSpriteCombined = DynamicSprite.Create(640, 480, false); lines to reflect your game's resolution.

meese72

Ooh WOW yes yes YES! :o
gonna go try this coolness now, a big hug+kiss to you all for your generous help :-*

meese72

umm, it works FABULOUS with directdraw and 16 bit (yay!!  :)), but when i tried 32bit or direct3d it didnt do the effect one bit!

Mazoliin

Change the last parameter of
Code: ags
EffectsSpriteCombined = DynamicSprite.Create(640, 480, true);
to false. Alpha channels in dynamic sprites is a bit wierd.

This is how I think it works (anyone, please correct me if I'm wrong):
When we create a dynamic sprite with an alpha channel, it's alpha is set to 0. When something is drawn to the image, it will be drawn with an alpha at 0 (fully transparent) since AGS doesn't seem to take the images alpha channels into account, and just use the alpha of the image we're drawing on to.

OneDollar

Yes, it looks like Mazoliin is right. Removing the sprite's alpha channel seems to fix it, but I've gone ahead and removed the alpha channel from the overlay as well:
Code: ags

EffectsOverlay = Overlay.CreateGraphical(0, 0, EffectsSpriteCombined.Graphic, true);

becomes
Code: ags

EffectsOverlay = Overlay.CreateGraphical(0, 0, EffectsSpriteCombined.Graphic, false);

every time (6 times in my code) it occurs. Tested with all combinations of 16 and 32-bit, and DD5 and D3D 9.

Also worth noting that the code is for 640x480 res, so if your game is 320x240 you can change the
Code: ags

EffectsSpriteScreenCopy = DynamicSprite.CreateFromScreenShot(640, 480);

and
Code: ags

EffectsSpriteCombined = DynamicSprite.Create(640, 480, false);

lines to create 320x240 sprites instead.

It seems odd that AGS handles things differently at different colour depths and renderer, and using 16-bit D3D 9 with the original code gave some very odd results.

meese72

Thanks sooo much guys!

Itty-bitty problem tho, I cant seem to get my player to move when the screen is shaking (during the earthquake). Its like its paused or something. Is there a way to make it so that players can still play/move/get around while the earthquake is shaking?

R4L

It's because the function has wait commands I believe, which means gameplay is paused until the quake is over.

meese72

oh, ok! So is that possible to take off so we can still play while the earthquake is shaking?

Dualnames

One Dollar, that is simply fantastic!! Way to go there!!  :D
Worked on Strangeland, Primordia, Hob's Barrow, The Cat Lady, Mage's Initiation, Until I Have You, Downfall, Hunie Pop, and every game in the Wadjet Eye Games catalogue (porting)

meese72

I'll look how I can  try to make all this possible to be playable while the shaking is occuring. Im still stuck but i just might be able to get it, well see lol!

Thanks a bunch guys  :-*

meese72

omg i have nooooooo idea how to get it to do the earthquake shake while the game is playable...id post what I tried but it's embarrassing lol!  ???

Could someone be so kind as to show how it could be achieved? It would be sooooooo appreciated pretty please with a cherry on top! :)

SMF spam blocked by CleanTalk