• entries
9
18
• views
17167

# The Mechanical Heart: Good Vibrations

2072 views

The Mechanical Heart

Development Blog

One of the biggest problems with creating 2D games is adding weight to the players actions, if you are not careful the controls can feel 'floaty' or light. Good animations can really help combat having your main character float around the screen, but another good way, which I will discuss today, is screen shake. Screen shake allows the player to really feel different actions, such as taking damage or recoil of a gun. These effects can reach their full potential when paired with vibration on a controller.

Goal
Create a algorithm that adds weight to the controls by the means of violently moving the camera. The camera movement should be random, but always return to the original position the camera was in.

Step 1 - Screen Shake
The First stage of making your screen shake 'feel' good is the camera being positioned along a path and returning to the same point as it left off. At first I thought it would be a good idea to add a 'shake frequency' variable so I could tell the camera only to X amount of times per second, however after implementing this, and playing around with the values, I decided to remove it. In my opinion you should try and move the camera as much as you can per second I.E. ever frame. Ok, so lets concentrate on a simple screen shake:CameraUpdate(){If the screen should be shakingincCameraPositionrandom amount(from 1 to MAX_AMOUNT) - HALF_MAX AMOUNT) in x directionincCameraPosition (random amount(from 1 to MAX_AMOUNT) - HALF_MAX AMOUNT) in the y direction}
This will simply move the camera around the origin. However there is a reason we dont rely on bogo sort to sort a list, the method above technically will return to origin if we leave it for long enough, the likely hood of that happening is slim. Instead if we add each movement to a list (vector in this case), then when the screenshake is half way through its time we go back through the list and move in the opposite direction.std::vector direction;CameraUpdate(){If the shake time < maxShakeTime/2{direction.pushback( XMFLOAT3(random amount(from 1 to MAX_AMOUNT) - HALF_MAX AMOUNT),random amount(from 1 to MAX_AMOUNT) - HALF_MAX AMOUNT) , 0))incCameraPosition(direction.back()) //move the camera by the amount we have just made} else if ( direction.size > 0 ){incCameraPosition(-direction[0]); // move in the opposite directiondirection.erase(direction.begin());//remove that direction from the vector}}
I first experimented with starting from the end of the list (the last shake of the camera) and working my way backwards to the start. However it turns out humans are good at pattern recognition and it didn't give the random feel I wanted. So starting at the front, moving in the opposite direction then deleting and carrying on to the next one, works best.

Step 2 - Polish

I found that most 2D games stop with the code above, but I wanted to add another layer of polish to the screen shake. I wanted to add a directional bias to the screen shake. This will enhance the feeling of recoil, or taking damage. For example, if the player fires a gun to the right, the screen should shake to the left and vice versa.

My first thought of doing this was that the recoil direction should be accumulative, that is the screen shake should only move in the direction of the recoil. However, I did want the other axis component to stay the same (for recoil to the left/right, the screen would still shake up and down).direction.push_back(XMFLOAT3(((rand()%maxRumble)+1)-ancor+rumbledir.x,((rand()%maxRumble)+1)-ancor+rumbledir.y,0));// Where ancor is half of maxRumble+1// And rumbledir is the direction the screen shake should shake i.e.:// -1//-1 0 -1// -1
This did not have the feel I wanted for the recoil as you can see below:

[size=2]Graphics are not representative of final graphics in game

[size=2]Artifacting is caused by recording device

[size=2]

[size=2]

[size=2]

[size=2]

[size=2]

[size=2]

[size=2]

[size=2]

[size=2]

## The amount to move the camera each frame is subjective for your game, for The Mechanical Heart, who's graphics are currently 64px x 64px tiles, I found moving the camera from -5 to +5 pixels per frame.

Conclusion
I am really happy with the screen shake, it really adds weight to what would have been 'floaty' or light input. I am happy with the result, so it is unlikely I will revisit this, but if I do I will most assuredly make a blog post about it.
You may have noticed I was increasing the camera position in 3 axis (x,y and z) but I always kept the Z axis at 0 - therefore not increasing it at all. The reason I kept it there was for a place holder, I may decide to move the camera on the Z axis (zooming in and out) when shaking the screen. I think this would give a nice effect, but I haven't had time to play with it.

[size=2]

[size=2]

## Dsm

Your art is not an accurate portrayal of my work. I am offended.

Your art is not an accurate portrayal of my work. I am offended.

I am sorry, next week I will give an art update, just for you.

Artifacting is caused by recording device

Yeah, sure, keep telling yourself that :P

Nice update man, I agree on the "going the extra mile" here. A nice camera shake effect goes a long way to make the player "feel" the attack. Much like headbobbing can make or destroy the feeling of running in FPS games.

## Create an account

Register a new account