motion_towards

Downloadmotion_towards(speed,x,y)   Place in Step Event to move the calling instance towards a point, navigating around solid obstacles.
///////////////////////////////////////////////////////////////
// script name: motion_towards
//     creator: Mark Overmars
//        date: Feb 25, 2002
//
// description: This script moves the the instance for which it is called
//              a bit in the direction of the given position. It (tries to)
//              navigate it way around solid obstacles. It correctly sets the
//              direction of the instance.
//
//   arguments: argument0: speed
//              argument1: x-position of point to move towards
//              argument2: y-position of point to move towards
//
//return value: indicates whether successfully a step was made
//
//     remarks: Place in the step event of the object. Don't give the object
//              a speed.
////////////////////////////////////////////////////////////////
{
    // Test whether we are on the goal
    if (x == argument1 && y == argument2) return true;
    // Close enough if it matches the mask value
    //  if (abs(argument1 - x) < 20 && abs(argument2 - y) < 16) return true;

    if (distance_to_point(argument1,argument2) < argument0) return true;


    checkspot = instance_place(argument1, argument2, all)
    if (checkspot != noone) // Something is in the position, we may not be able to get there
    {
        if (checkspot.solid) // Definitely blocked
        {
            if (abs(argument1 - x) < checkspot.sprite_width && abs(argument2 - y) < checkspot.sprite_height) return true;
        }
    }

    // Test whether we are close to the goal, if so, move there immediately
    if (point_distance(x,y,argument1,argument2) <= argument0)
    {
        if place_free(argument1,argument2)
        {
            direction = point_direction(x,y,argument1,argument2);
            x = argument1;
            y = argument2;
        }
        return true;
    }
    // Compute the potential useful direction to try in order of usefullness.
    // The directions we test must lie not too far away from the current
    // direction and are preferably directed as much as possible towards the goal
    __goaldir = point_direction(x,y,argument1,argument2); // directions towards goal
    __trynumb = 0;
    __maxrot = 30;    // maximal amount to rotate in a step. Can be changed
    __stepsize = 10;  // size of the steps to take. Can be changed
    for (i = 0; i<180; i += __stepsize)
    {
        // try a counterclockwise direction
        __dir = (__goaldir-i+360) mod 360;   // to get it in the range 0-360
        __dif = (direction-__dir+360) mod 360;
        if (__dif <= __maxrot || __dif >= 360-__maxrot) // add to the array of tries
        { __try[__trynumb] = __dir;  __trynumb += 1;}
        // try a clockwise direction
        __dir = (__goaldir+i+360) mod 360;   // to get it in the range 0-360
        __dif = (direction-__dir+360) mod 360;
        if (__dif <= __maxrot || __dif >= 360-__maxrot) // add to the array of tries
        { __try[__trynumb] = __dir;  __trynumb += 1;}
    }
    // Now we try the directions in the array __try
    // For each direction we look a bit ahead to see whether it will lead to
    // a collision. If not, we take that direction for the motion
    // Note that we temporaily set the speed to argument0 such that we can
    // use hspeed and vspeed to determine the new position
    __ahead = 4;   // number of steps we look ahead for collisions(can be changed)
    speed = argument0;
    for (i = 0; i < __trynumb; i += 1)
    {
        // try moving a bit in the direction
        direction = __try[i];
        if (place_free(x + __ahead*hspeed,y + __ahead*vspeed) && place_free(x+hspeed,y+vspeed))
        {
            x = x + hspeed;
            y = y + vspeed;
            speed = 0;
            return true;
        }
    }
    speed = 0;
    // If we did not succeed a local minima was reached and the instance gets stuck
    return false;
}

Click if you've used this script[Please Login]
Projects: 8

 Contributor: Mark Overmars


comments powered by Disqus