The Mechanical Heart: Good Vibrations

posted in Binary Cats
Published December 01, 2014
Advertisement

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:

HRozism.gif


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


[size=2]Artifacting is caused by recording device



[size=2]

So I decided to revisit the drawing board. I decided on adding a slight bias of which direction the recoil.






DRUStcM.gif


[size=2]

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


[size=2]

[size=2][size=2]Artifacting is caused by recording device



[size=2]

Unfortunately the recoding device skipped about half of the screen shake frames, so it isn't immediately obvious that the screen shake isn't accumulative in the direction of the recoil. It is a lot more noticeable in game, and if I can reproduce the results in .gif form I will update this blog.



[size=2]

Here is an image illustrating the recoil, each and every different frame is coloured.






[size=2]

m5iBNH9.png




[size=2]

Timing and shake amount



[size=2]

These will vary for your game, but for The Mechanical Heart I played around with the values a lot, I found that for firing a weapon, the total amount of time the screen should shake for is about 0.2 seconds. Although, if you wanted to create a feeling of a more powerful weapon and greater recoil I would suggest going up to ~0.5 seconds.



[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]

Until next time,


[size=2]

Dsm

10 likes 3 comments

Comments

riuthamus

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

December 01, 2014 08:38 PM
dsm1891

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.
December 01, 2014 09:06 PM
TheChubu

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.

December 06, 2014 02:45 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement