GameMaker: Homing missiles

Homing missiles example for GameMaker

This is a post about implementing homing missiles in GameMaker.

A homing missile is a type of missile that can alter its direction mid-flight to hit a (generally) moving target.

This example shares much of the concept with "angular rotations explained".

First, you will need cycle and angle_rotate scripts from there,

/// cycle(value, min, max)
var result, delta;
delta = (argument2 - argument1);
result = (argument0 - argument1) mod delta;
if (result < 0) result += delta;
return result + argument1;
/// angle_rotate(angle, target, speed)
var diff;
// 180 is to be replaced by "pi" for radians
diff = cycle(argument1 - argument0, -180, 180);
// clamp rotations by speed:
if (diff < -argument2) return argument0 - argument2;
if (diff > argument2) return argument0 + argument2;
// if difference within speed, rotation's done:
return argument1;

The rest is trivial - you want to find the target' coordinates and have your missile rotate in that direction, like so (in Step event),

if (instance_exists(target)) {
    direction = angle_rotate(direction, point_direction(x, y, target.x, target.y), 3);
}

Where target is a variable holding the object to track (be that some obj_player or an instance ID), and 3 is rotation speed, in degrees per frame.

Add acceleration (speed = min(speed + accel, maxspeed)) and image_angle = direction, if needed.

And that's it. Here's a small live demo if you'd like:

The downloadable example (shown in GIF above) expands on this slightly, adding the ability to place/remove walls, and spotting simplistic visuals akin to one of my older games:

Download GMK

Usage instructions for the example:

  1. Add obj_launcher, obj_rocket, obj_shard to your source. obj_shard only needed for rocket explosions - if you're going to make your own, you can omit adding that and remove relevant code from "obj_rocket:collision with obj_wall" event).
  2. Change occurrences of obj_target in obj_rocket and obj_launcher to name if your desired target object (for most games this is probably your player object). If you have multiple target objects in room, you may need to add target determination code (such as instance_nearest(x, y, obj_player)) there.
  3. Tweak parameters (third parameter in angle_rotate calls and speed modifiers in obj_rocket) to suit your game mechanics.

Have fun!

Note: this post was originally published on Jun 4, 2013. It was updated on Mar 19, 2017, adding a live demo and important bits of the source code to the post.

Related posts:

7 thoughts on “GameMaker: Homing missiles

  1. It seems that you have a simple mistake in your demo .gmk file. When a rocket collides with a block, it tries to create “obj_gib”, but in your object resource list, there is no “obj_gib”. Instead there is an object called “obj_shard”, and switching the code from trying to create an instance of “obj_gib” to “obj_shard” resulted in the error being fixed.

    Otherwise, good example! I believe some may find it useful.

    • Thanks, I’ve fixed that.
      Was a post-publication edit because term “gib” doesn’t quite apply to fragments of mechanical objects. Didn’t pay attention to whether I saved last change or not.

  2. I savor, lead to I discovered exactly what I was taking a look for.

    You’ve ended my 4 day long hunt! God Bless you man. Have a nice day.
    Bye

    • Why 4 days mate? Do you not know gm? Perhaps you should look into the functions instead of CPing code. Copying people’s example is gonna do you know good if you don’t know what you are doing. Hopefully you tried to at least make a homing missle.

      Anyways, I’m only saying this because it held my younger self back quite a bit in the beginnings of my gamemaker experience.

  3. Is there a way to make this go around walls and such, instead of being destroyed on contact with them?

    • Your safest bet would probably be to use mp_potential_step, which (via mp_potential_settings) similarly rotates the object while following, but will attempt to avoid obstacles.

Leave a Reply

Your email address will not be published. Required fields are marked *