Howdy folks! Today, we are going to talk about everyone’s favorite indie effect: screen shake! A classic that is sure to beef up your impacts, explosions, sudden realizations, gunshots, and more. Setting up screen shake is a pretty simple process, but as you will see, there are a lot of nuances you can tweak to dramatically impact the feeling of it. This blog assumes you are somewhat familiar with views in GameMaker. If you aren’t familiar with views, check out this previous blog post on views!
Before we can start shaking the camera around, it is a good idea to initialize some variables that will help us control screen shake, and fine tune it. The best way to handle this is to do so from a game controller type object. A game controller object is a persistent object that manages many parts of your game. Things like score, the camera, changing levels, controlling menus, and lots of other things can be controlled from your game controller object. If your project does not have a game controller, now would be a good time to add one! Then, let's initialize some variables.
Game controller create event
shake = false;
shakeDur = 5;
shakeForce = 1;
These three variables will let us easily manage the ferocity of our screen shake, and its duration. The first variable is used to turn the screen shake effect on and off. The second, shakeDur, is the duration the effect lasts. Finally, shakeForce, is how dramatic the shake effect is. Now we need to put these to use.
Game controller step event
if(shake){
shakeDur --;
view_xview += choose(-shakeForce,shakeForce);
view_yview += choose(-shakeForce,shakeForce);
if(shakeDur <= 0){
shake = false;
shakeDur = 5;
}
}else{
view_xview = approach(view_xview,0,0.3);
view_yview = approach(view_yview,0,0.3);
}
Alright, real quick before I explain this, I want to point out this approach script at the bottom. If you don’t have the approach script (which is featured heavily in my previous blog entries) here it is. Create a new script, name it approach, and throw this code in there.
Approach script
/// approach(start, end, shift);
if(argument0 < argument1){
return min(argument0 + argument2, argument1);
}else{
return max(argument0 - argument2, argument1);
}
Quick shout out to Matt Thorson (Towerfall, Celeste) for this handy script that I have been using for years. This script takes a value, and shifts it towards another value by a set amount each frame. In the instance above, we are using it to reset our camera position back to zero, which is the default camera position. Now, back to the screen shake.
This is a pretty simple bit of code. First, we check to see if shake is true, and if it is, start counting down our shakeDur variable. Once shakeDur reaches zero, shake is set to false, and shakeDur is reset to its maximum value of five. While shakeDur counts down, we move the view around by adding shakeForce to it randomly. If you are unfamiliar with choose, it is pretty self explanatory. It simply chooses one of the arguments provided. In this case, it is choosing either shakeForce or negative shakeForce, so either one or negative one. This means our camera is moving around one pixel up, down, left, or right randomly every frame for five frames. Once shakeDur reaches zero and shake is no longer true, the view is reset back to zero by using the approach script.
That's basically it! Or, at least, it's basically the basics of screen shake. If you run the game and you have set a button press or some action to set shake to true, you should get a fairly small screen shake. Here is an example from a little game I have been working on lately.
Can Kicker Xtreme (working title)
Now you have the basics in place. If you haven’t already, take some time to mess with the shakeDur and shakeForce variables we created. See what happens if you increase/decrease those variables in the create event of your game controller object. Here are a couple of examples.
In the first animation, we have a shakeDur of 60 and a shakeForce of one. In the second animation, a shakeDur of five and a shakeForce of three.
You can also get a lot of mileage out of messing with the view_angle when shaking the screen. The setup for this is exactly like view_xview and view_yview above. It's fairly subtle in the animation below, but you can see how it adds just a little bit extra oomph to the shake.
That about wraps it up for screen shake. This just barely scratching the surface of how this can be applied and tweaked, but it should set you on the right track.
I’d also like to offer some general advice for using screen shake.
I see a lot of folks using it for… well… everything in their games all the time. With screen shake, often less is more. Use it to accentuate certain actions to give them more weight and impact. Don’t use it for every single gunshot. Use it for that big powerful gun that you have limited ammo for!
Thank you for taking the time to read over this, and I’ll catch you next time. As always, you can reach me on Twitter or visit my website for more gamedev stuff.
Nathan Ranney is the founder of punk house game dev shop, RatCasket. He’s best known for the creation and development of Kerfuffle, an online indie fighting game.