Reap and tear without problems

Here is a short tutorial about bloody effect in HONK.

honk05.gif

First of all, this effect is based on this tutorial https://www.youtube.com/watch?v=nz8FUMHEyAU

However, I've made some slight changes to make it better for my game. I think, that my approach is still clunky and needs some upgrade in the future.

Step 0. Make movement system

I use my movement system in this effect, I highly recommend to read about it. Movement.

Step 1. Setup surface object

In my game I use special object which is called obj_drawer, this object does one job - sorting sprites and drawing them in the order I need. It takes a lot of time to explain this, now you should create an empty object which will control surface for these bloody effects.

Create event surfaceFloorEffects= surface_create(room_width, room_height);

Draw event if (surface_exists(surfaceFloorEffects)) { draw_surface_ext(surfaceFloorEffects, 0, 0, 1.0, 1.0, 0, c_white, 1.0); } else { surfaceFloorEffects = surface_create(room_width, room_height); }

Clear event surface_free(surfaceFloorEffects);

Step 2. Setup base object

In the project I use special base objects. They include some logic, which is shared by other objects, e.g. I have obj_sortable, which contain logic for sorting etc.

In this case this you need to create obj_floorEffect and place it on your level.

Destroy event ``` var surface = objdrawer.surfaceFloorEffects;

if (surfaceexists(surface)) { surfacesettarget(_surface);

draw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, direction, c_gray, image_alpha);

surface_reset_target();

} else { surface = surfacecreate(roomwidth, roomheight); } ```

Step 3. Setup splatter object

Create object vfx_splatter without any sprite.

Variable definitions

You need this variables to adjust child objects.

vfxemslplatter/emvd.png

Create event ``` velocityMax = 20;

// Visual paarameters imagespeed = 0; imageindex = irandomrange(0, imagenumber - 1); imagexscale = randomrange(0.05, 1); imageyscale = randomrange(0.05, 1); imagealpha = randomrange(0.25, 1);

// Movement parameters direction = randomrange(0, 359); imageangle = direction; velocityCurrent = randomrange(0.4, velocityMax); groundFriction = randomrange(0.1, 0.2); velocityX = 0; velocityY = 0;

// Smear parameters smearTime = 3; smearTimer = 0; **Step event** // Movement MoveObject();

velocityCurrent = CalculateDeceleratedVelocity(direction, velocityCurrent, groundFriction);

if (velocityCurrent <= 0) { instance_destroy() }

// Smearing smearTimer += global.TimeFactor;

var checkTimer = checktimer(smearTimer, smearTime);

if (_checkTimer) { smearTimer = 0;

instance_create_layer(x, y, layer, smearObject);

} ``` check_timer script

Be aware, I use timefactor, it means you need to arrange global.TimeFactor somewhere at the very start of the game. gml global.TimeFactor = 1;

``` /// @param timer /// @param time

var _timer = argument0; var _time = argument1;

return (floor(timer) >= _time && floor(timer - global.TimeFactor) != floor(_timer)); ```

Step 4. Setup smear object

Create object vfxsmear. It must not have any sprite as well as vfxsplatter.

Create event ``` imagespeed = 0; imageindex = irandomrange(0, imagenumber - 1); imagexscale = randomrange(0.05, 0.5); imageyscale = randomrange(0.05, 0.5); imageangle = irandomrange(0, 359); imagealpha = randomrange(0.25, 1);

instance_destroy(); ```

Step 5. Create sprites and child objects

Here is an example of blood sprite. sprembloodSplatters/emstrip6.png

Yep, it’s small.

After this, you need to create a new object for splatter and smear and make their parents vfxsplatter and vfxsmear relatively.

Do not forget to set up variable definitions.

Step 6. Make a spawn script

This script will definitely make adjustments of the effect easier.

``` /// @param x /// @param y /// @param splatterObject /// @param count /// @param velocityMax

var _x = argument0; var _y = argument1; var _object = argument2; var _count = argument3; var _velocity = argument4;

for (var i = 0; i < count; i++) { var _splatter = instancecreatelayer(x, _y, layer, _object);

with (_splatter)
{
    velocityMax = _velocity;
    velocityCurrent = random_range(0.4, velocityMax);
}

} ```

Step 7. Use script

Now you can place this script wherever you want, but be careful when you will use it in step events.

Step 8. ???

Step 9. PROFIT!

Now you can reap and tear in your game with ease!