Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Snake on Tue 23/06/2009 21:59:22

Title: Possible to ShakeScreen on only half the screen?
Post by: Snake on Tue 23/06/2009 21:59:22
Hello once again, everyone,

I'm curious to know if there's a way to shake the screen on only half of the screen. I got looking at the manual since "SetViewport" was what first came to mind, and it seems it only works for scrolling rooms. I'm not even sure if I'm in the right direction.

I suppose I could do it with an object and either animate it or move it up and down rapidly. But I guess before I look into other options I'd like to know if using ShakeScreen within a specified X,Y would even work to begin with...

NOTES: The resolution is 800x600. I'm going to want to shake the screen on the upper and lower half of the screen (at different times, of course).


Thanks in advance.
Title: Re: Possible to ShakeScreen on only half the screen?
Post by: GuyAwesome on Tue 23/06/2009 22:25:31
SetViewport(x,y), as you read, is for scrolling rooms - it sets the top corner of the screen to a specific position within the room rather than following the player as normal (e.g. to pan across a landscpae in a cutscene, or 'lock off' part of the screen for soem effect). So, not what you were looking for...

Short answer: No, I don't think it's possible to do ShakeScreen only within a set area - it's all or nothing.
Long answer: According to this thread (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=38029.0) (which is admittedly about ShakeScreen going wrong), it looks like ShakeScreen/Background essentially screengrabs the background and rawdraws it over itself, a few pixels off each time. Which means, you should be able to write your own function that just grabs PART of the screen, and then rawdraws that offset mimicking ShakeScreen (pretty much the same as using an Object, but without having to 'waste' an Object on it) - IF you really want to go that route. Depending on where and how often you want this effect, the Object movement/animation method might be easier.

EDIT:
Actually, it might be the Overlay functions, rather than the DrawingSurface ones you want. DS will be drawn UNDER characters, objects, etc, which can lead to some odd effects. Overlays are draw on top, closer to what ShakeScreen does. Here's a pretty basic example

function ShakeScreenPart(int x, int y, int width, int height, int amount) {
 DynamicSprite *Vesper;
 int Duration = 40, InitY = amount;
 mouse.Visible = false;
 Wait(1);
 Vesper = DynamicSprite.CreateFromScreenShot();
 mouse.Visible = true;
 Vesper.Crop(x-GetViewportX(), y-GetViewportY(), width, height);
 while (Duration > 0) {
   InitY = -InitY;
   Overlay* myOverlay = Overlay.CreateGraphical(x-GetViewportX(), y-GetViewportY()+InitY, Vesper.Graphic, true);
   Wait(1);
   myOverlay = Overlay.CreateGraphical(x-GetViewportX(), y-GetViewportY(), Vesper.Graphic, true);
   Wait(1);
   myOverlay.Remove();
   Duration -= 2;
 }
 Vesper.Delete();
}

function ShakeScreenTop(int amount) {
 ShakeScreenPart(GetViewportX(), GetViewportY(), System.ViewportWidth, System.ViewportHeight/2, amount);
}
function ShakeScreenBottom(int amount) {
 ShakeScreenPart(GetViewportX(), GetViewportY()+System.ViewportHeight/2, System.ViewportWidth, System.ViewportHeight/2, amount);
}


It has a few ... potential flaws: for example, it looks a little odd if a character is moving on or around the shaking part of the screen (e.g. their head stays in place and shakes, while their legs and torso move on); the DynamicSprite.CreateFromScreenShot() function also captures GUIs, so they'll be shaken as well; it's 'semi-blocking' - some things will run in the background (like character movement), but as mentioned the effect can be a little off; and I'm sure others will occur with use... Still I don't think it's too bad, for 20 minutes work.

Why did I call the DynamicSprite 'Vesper'? Ever read "Casino Royale"? Yes, I know. I'm very sorry...