We would love you to play this but your browser doesn't support HTML5 canvas.
Just use a different browser and you can happily play this game.

Persistent Unlimited Memory Efficient Blood in GameMaker (HTML5 Compatible)

So that title might not make much sense so let’s break down what I am trying to do.

Using this technique you can add infinite amounts of collateral blood splashes to your game without impacting memory at all.

The example at the top of the page shows how I am spawning a massive number (30 every second) of blood objects into the game world however there are actually only a relatively small number of objects performing at any one time.

You can interact with the demo at the top, by moving your mouse around you can aim where they are being shot, I am also spawning 3 smaller blood objects every time one lands as well as trickles that move down the walls and create more blood if they get to the bottom of the wall.

How does it work?

The basic principle behind it is as soon as one of the blood splatters is stationary I draw it onto a big image that is always overlaid over the top of the game. This way I can delete the blood object and it still looks like it is on the screen. In this guide I’m going to show you how to do this quite easily in GameMaker.

I have used this same technique to do wall damage in GameMaker which you might also find useful as I talk more in-depth on how the systems work. Whereas I hope this one will be an easier tutorial.

Here is an example of what this overlay with all the blood on ends up looking like:

Persistent Unlimited Memory Efficient Blood in GameMaker (HTML5 Compatible)
The Code :

I’m going to start with the code and then break down how it works. For the purpose of keeping it simple I will remove how the gun and trickle work as I assume you will want to write that bespoke for your own game. Instead I will focus on the blood and how we draw it onto an image.

/// obj_surface – Create:
damagemask = surface_create(room_width, room_height)

/// obj_surface – Draw:
if (surface_exists(damagemask)) {
    draw_surface(damagemask,x,y)
}


/// obj_blood – step:

if (collision_point( x, y, obj_wall, false, false )) {

    if (surface_exists(obj_surface.damagemask)) {
        surface_set_target(obj_surface.damagemask)
        
        draw_self()
        
        surface_reset_target();
    }
    
    instance_destroy()
}
    

And that’s all the code.

In this I have two objects. The obj_blood which is each individual blob of blood flying around and obj_surface which is the object that holds the image with all the blood splats drawn on it.

I use a surface to save all this data in GameMaker, if you don’t know what a surface is I wrote guides on drop shadows or scratch cards that are easier to learn from, however they are basically an empty canvas you can draw onto in the same way you draw any sprite onto the screen and anything you draw there is saved, these surfaces can then themselves be drawn onto the screen with everything you have added onto them.

Let’s first look at obj_surface. All this does is store the surface we are using and draws it onto the screen. I called my surface damagemask but I’m sure you could use a more sensible name. We create the surface with damagemask = surface_create(room_width, room_height) in the create event and in the draw event we use draw_surface(damagemask,x,y) to draw it, I need to mention here that we need to check it exists before we draw it because surfaces are volatile in GameMaker, to do this I just use surface_exists(damagemask).

Now for the blood... I have removed all of the code for doing gravity and other things so we can focus on making the blood persistent. The first line is just checking for a collision, its likely you will want to put your own code here but this is all the code I need for mine.

And this is the magic for the whole method:

if (surface_exists(obj_surface.damagemask)) {
    surface_set_target(obj_surface.damagemask)

    draw_self()

    surface_reset_target();
}
    

surface_set_target() allows us to change where GameMaker draws to, so rather than drawing onto the screen we are telling it we want to draw directly onto our surface. This permanently changes the surface. Now I just draw the blood as it normally would and it appears on the surface. I just then use surface_reset_target(); to tell GameMaker to go back to drawing to the screen.

So that’s it!

Lots of triple A games use techniques similar to this to store persistent wall damage, I’m fairly sure I heard the developers of Killing Floor say they did something like this.

HTML5 and WebGL compatible :

I made sure all of the features in this technique were compatible with the GameMaker HTML5 module so if you wanted you could do something like I did above and export it to a browser. I’m pretty sure this will work without WebGL enabled however I always tick the box to make WebGL required so I don’t have to test and support two versions.

Credits :

Wall Image - GrumpyDiamond

About the Article:
Easy Difficulty
GameMaker
By David Strachan