Hi! I have an issue that has been bugging me for ages, and finally decided to ask.
So I want to create a shaking screen effect. ShakeScreenBackground is just what I want, except it creates an ugly black border on top of the screen. I have some extra space at the top of my room (it's a very high scrolling room), so I want that part to be revealed, instead of the black, empty area.
I've undersood that it's a constraint of the engine, and that I should animate the viewport instead. I tried, but didn't have much luck. I tested it with something like this:
Screen.Viewport.Y +=5;
It too created the black bar on top of the screen, eventhough my room should still continue there.
So what would be the best way to achieve the shaking screen effect? I'm using the Smoothscroll module, but I tried disabling it and got still the same results. Would the new camera system help?
Quote from: rongel on Mon 27/07/2020 11:24:38I have some extra space at the top of my room (it's a very high scrolling room), so I want that part to be revealed, instead of the black, empty area.
In that case you should move Camera (Game.Camera), not Viewport. Viewport defines where on screen the room is shown, Camera defines which part of the room is shown.
PS. Before 3.5.0 the "viewport" was actually "camera", so SetViewportX actually meant "set camera's x" in modern terms. When reading old threads or tutorials on this topic you have to replace "viewport" with "camera" :).
Thanks CW!
Yes, using Game.Camera seems to work. I had to disable the Smoothscroll first, using SmoothScroll_ScrollingOff();. But I think I can turn it on again after the effect.
Now I just have to figure out a good way to animate the camera to create the shaky effect. Any tips? :-D
Ok, I think I can manually animate the camerashake in room_RepExec(). It just needs testing to see what values work. So only thing that is missing compared to ShakeScreenBackground is that I have to make the effect blocking. That's because the camera manipulation won't work when smoothscroll is on.
But I think I can live with this!
Quote from: rongel on Mon 27/07/2020 13:02:29
Ok, I think I can manually animate the camerashake in room_RepExec(). It just needs testing to see what values work. So only thing that is missing compared to ShakeScreenBackground is that I have to make the effect blocking. That's because the camera manipulation won't work when smoothscroll is on.
To make it blocking, don't put it in room_RepExec. Instead move camera in a loop and call Wait(1) to force game redraw:
void BlockingShakeScreen( int shake_power, int shake_time, .. other parameters ..)
{
int counter;
while (counter < shake_time)
{
// ... change camera coords here
Wait(1);
counter++;
}
}
PS. fixed example, forgot to increment counter.
QuoteTo make it blocking, don't put it in room_RepExec. Instead move camera in a loop and call Wait(1) to force game redraw:
This seems to work nicely! I can make few different shake speeds / types and repeat them as long as I want. Much better than manually adding every single movement.
Thanks again!
You can read the positions from an array or calculate using something like a sin function
Quote from: eri0o on Mon 27/07/2020 14:01:35
You can read the positions from an array or calculate using something like a sin function
I'm afraid that might be too much for my coding skills...
I had some trouble deciding how to do the speed of the shakes. Something like this works fine for fast shakes, where I just change the camera's placement:
Game.Camera.Y += shake_power;
Wait(1);
Game.Camera.Y -= shake_power;
Wait(1);
But if I want to make a slower shake that has several inbetween frames, the above method wont work. And I don't think we can animate the camera directly? I figured out an ugly way to do it, but it could use improvement.
Quote from: rongel on Mon 27/07/2020 14:54:02
But if I want to make a slower shake that has several inbetween frames, the above method wont work. And I don't think we can animate the camera directly? I figured out an ugly way to do it, but it could use improvement.
What do you mean by "animating directly"?
You can move camera in smaller increments too, simply by breaking big move into steps. Example:
int normal_y = Game.Camera.Y;
int shake_y = normal_y - shake_power;
while (Game.Camera.Y > shake_y)
{
Game.Camera.Y = Game.Camera.Y - 1;
Wait(1);
}
while (Game.Camera.Y < normal_y)
{
Game.Camera.Y = Game.Camera.Y + 1;
Wait(1);
}
Increment amounts and Wait argument may be made dependent on some "speed" parameter.
Also, I believe latest Tween module has camera functions, letting you move camera smoothly in certain style.
QuoteWhat do you mean by "animating directly"?
I mean that there are no commands that would move the camera, like
Game.Camera.Move(122, 150, eBlock);QuoteYou can move camera in smaller increments too, simply by breaking big move into steps. Example:
Yes, I have something vaguely similar, but this seems much sophisticated!
Quote from: rongel on Mon 27/07/2020 15:41:34
I mean that there are no commands that would move the camera, like Game.Camera.Move(122, 150, eBlock);
The above example practically does same thing, and you may write blocking function yourself as extender:
import void MoveBlocking(this Camera*, int x, int y, int pixels_per_tick);
void MoveBlocking(this Camera*, int x, int y, int pixels_per_tick)
{
while (this.X != x || this.Y != y)
{
int distx = this.X - x;
int disty = this.Y - y;
if (distx < 0) distx = -distx;
if (disty < 0) disty = -disty;
if (distx <= pixels_per_tick)
this.X = x; // snap if too close
else if (this.X < x)
this.X += pixels_per_tick;
else if (this.X > x)
this.X -= pixels_per_tick;
if (disty <= pixels_per_tick)
this.Y = y; // snap if too close
else if (this.Y < y)
this.Y += pixels_per_tick;
else if (this.Y > y)
this.Y -= pixels_per_tick;
Wait(1);
}
}
The above is a crude example, and it's mostly useful for straight movements. Also for non-blocking movement you would have to write a somewhat more complicated system that updates movement in rep-exec.
I believe that Tween module (https://www.adventuregamestudio.co.uk/forums/index.php?topic=57315.0) already has these though.
QuoteI believe that Tween module already has these though.
Yes, I'm using Tween module as well, and I'm very happy with it. This current room that I'm working on is a bit special. I'm using Smooth Scrolling & Parallax so that I have nice smooth camera movements, and the parallax effect as well. But yes, it looks like that I could disable the smooth scroll feature and use Tween module to control the camera directly (currently there is a dummy character as a camera). I think the parallax effect still works, eventhough smooth scroll is disabled.