Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

Advanced search

1403757 Posts in 68282 Topics- by 61952 Members - Latest Member: noah223

December 03, 2022, 01:20:53 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityTownhallForum IssuesArchived subforums (read only)Tutorials[GM:S] Screenshake, Impact frames, Satisfying game feel
Pages: [1]
Author Topic: [GM:S] Screenshake, Impact frames, Satisfying game feel  (Read 4346 times)
Level 0

Always be the best dressed in the room.

View Profile WWW
« on: February 28, 2017, 09:06:35 PM »

In this tutorial, we will make a ball roll around a room with satisfying impacts and motion. We will cover some more more advanced features of GameMaker studio as we do so.

This tutorial is designed to use zero custom software or assets, but for your convenience all the files are available here

We will cover

1. Achieving a smoother framerate
2. A 'Rolling' animation that matches the direction of the ball
3. Impact frames
4. S C R E E N S H A K E

To Begin, create a new project and a room with the dimensions of 512x512

Satisfying element 1: A Decent Frame Rate
By default, gamemaker rooms run at 30 'steps' a second, in this settings menu the 'room_speed' can be adjusted to something smoother, like 60 for example

Now since we're going to be rolling a ball around in here, it'd be wise to border the room with a solid object the ball can bounce against. Create a new object called o_block and give it a boring, square sprite. Be sure to tick 'solid' in the object's properties.

You can untick 'visible' if you don't want to see these big ugly blocks later on when the screen is shaking around.

Return to the room window and place a border of these around the playable area.

Now that we have a room, it's time for a ball. Create a new object called 'o_ball'

In the sprite section of this window, click new, name it s_ball, and click 'edit sprite'

Create a new empty frame with this button

Double-click your new frame to begin editing it, and draw what looks to you like a ball

Satisfying Element 2: A 'Rolling' animation that matches the direction of the ball
Close the sprite editor when you've filled the frame with a ball, and copy-paste it four times, so that you have five identical frames

In the last four frames, we're going to create a dark stripe that passes over the ball. You can do this any way you like, all we're doing is adding something the eye can track as it moves around the ball. A place to start is with a crescent shape that matches the ball's curves, as shown here, but feel free to experiment!

Make sure your shape passes over the ball from left to right, as the ball's neutral state is rolling to the right

Before closing the sprite, enable 'precise collision checking'...

...and set the sprite's origin to 'center'

Doing this will make the ball sprite rotate around the center of the ball, not the top-left corner where the origin usually is.

Give the ball a 'Create' event and a 'Move free' action. For this action's details, enter 'direction:random(360)' and 'speed: 6'

This will set the ball rolling in a random direction when the game starts

The 'random()' function picks a random number from 0 to the number given between the brackets, since we provided '360' (the number of degrees in a circle) the ball will choose a direction from all possible directions that exist.

While we're here in the create event, set the variable 'image_speed' to 0.25

Since our game runs at 60 steps a second, our 5-frame sprite will animate very fast. This is a simple way to slow the speed of sprites down (in this case, 25% its normal speed)

We created an animated 'rolling' sprite, but we only drew it rolling in one direction. To account for all the other directions the ball can roll, add a step event and a 'transform sprite' action. Under 'Angle' enter 'direction'

When using simple move actions like 'move free', gamemaker will store a 'direction' variable between 0 and 359 that you can use to track where an object is heading. If the ball bounces or an event moves it, the direction will automatically be updated.

Now the sprite will rotate to match the direction it's headed!
To finish the ball , add a collision event with the block we created, and give it a 'bounce precisely' action.

There are many ways to code collisions and bounces in gamemaker, this one is the simplest and most compatible with the movement the ball is set up to use. 'Precisely' will calculate a realistic new trajectory for the ball, whereas 'not precisely' will add a margin of incorrectness to that calculation. (Useful for pong or breakout style games where a ball object could get stuck infinitely bouncing)

Place the ball object in your room and run it with F5. It should look like this:

It's alright, but it lacks punch. We're going to add screenshake, impact frames and a background.

Satisfying Element 3: Impact frames

When the ball makes a collision, it should flash white for a short time. This technique is used to great effect in lots of action games (especially those by vlambeer)

In order for the ball to flash white, it should have a color to begin with! In the create event, add a 'execute a piece of code' action. Inside it enter:


the 'make_color_rgb(0,0,0)' function takes three numbers, one for a red value, one for green and one for blue, each with a minimum of 0 and max of 255. Since we want the ball to be mostly red, we've entered '150' in the red category. If you want to get more specific, you can use any online color picker to get RGB values.

Now that the ball is red by default, we need to make it flash white on impact. Under the collision with o_block action, add this code:


All values are at their maximum of 255, which will produce white, whereas (0,0,0) would produce black

Under this, we're going to set an alarm that we can use to return the ball to its default color.

alarm[0] = 4

Using code, we set the alarm to run for 4 steps. Since our game runs at 60 steps per second, this flash will only be visible for a short time. Be sure to experiment with longer alarm times to perfect the feel of your bounces.

Add an Alarm 0 event and inside it add the same image_blend code we used in the create event.

When the alarm is triggered, it will set the ball's color from white to red.

Satisfying Element 4: Screenshake

To setup screenshake, our room needs a view enabled and a background (Because your eyes won't detect the shake if nothing in the room is moving)

Create a background image for your room. You can draw whatever you like, but I'm going to create a simple grid pattern.

Apply it to your room in the backgrounds tab, and then select the 'views' tab and configure the room as follows:

Enable the use of views: Tells gamemaker to use the views you have setup instead of rendering the whole room

view0: The view we're going to use (you can have multiple)

visible when room starts: tells gamemaker to enable this view when the room is initialized, it can later be disabled

view in room: The dimensions and position of the view. we have set W and H to 512, so that the view contains everything in the room

port on screen: The shape the view will be rendered on your computer screen. entering a higher width and height than that of the view will scale the view up to the specified size.

We need to enable a view like this so that we can shake it around using code.
Open the object window for the ball and, inside the 'create' event, set the variable 'shake' to 0

Now, under the collision event with o_block, set the shake variable to 1

finally, under alarm0, set the variable to 0

The 'shake' variable will now switch to 1 when the ball hits a wall, and switch itself back to 0 when the alarm's time is up.

Now that the pieces are in place, we can begin coding the screenshake. In the 'step' event, add a piece of code:

if shake = 1{                    //if screenshake is enabled
view_xview[0]=random_range(-4,4) //sets the view to a random x position
view_yview[0]=random_range(-4,4) //set's the view to a random y position

What's happening here?
The step event runs every step (60 times a second) and, if the variable 'shake' is equal to 1, this code will set the view's position to a random spot between -4 and 4. You can increase how violent the shaking is by adjusting these numbers, and you can increase the duration of the shaking by setting alarm0 to a longer time.

If you run the game now, you'll notice that the screen will shake, but it will 'stick' to its last assigned random position

We need to add some code that will move the view to its natural position when a shake isn't occurring. Under the previous chunk of code, add the following:

if shake = 0{

if view_xview[0] < 0 { view_xview[0]++ }
if view_xview[0] > 0 { view_xview[0]-- }
if view_yview[0] < 0 { view_yview[0]++ }
if view_yview[0] > 0 { view_yview[0]-- }


What's happening HERE?
every step, if shake is disabled, this code will check if the x value of the view is below or above 0. If it's more than zero, it will reduce the x value and if it's less than zero, it will increase the x value. (and do the same for y).

The screenshake should now correct itself, and you should be feeling the impacts of your rolling ball (I've added a white flash on every bounce here for a little extra satisfaction)

What next?

'Game feel', 'Juice', 'Crunch' or whatever you may call it, is a comically unfocused and poorly defined concept and because of that, you're free to build your own definition from what's out there. Here are some videos from devs about methods they've found to add personality to games.

: Martin Jonasson & Petri Purho

Jan Willem Nijman

« Last Edit: March 25, 2017, 07:35:57 PM by Jrap » Logged

Level 1

View Profile WWW
« Reply #1 on: April 21, 2017, 01:34:26 AM »

A must read, and the videos at the end, must watch. Very usefull advices that game programmer should never forget! Thanks Jrap.

Pages: [1]
Jump to:  

Theme orange-lt created by panic