motion_towards
///////////////////////////////////////////////////////////////
// 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;
}
// 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;
}
[Please Login]
Projects: 8
Contributor: Mark Overmars
comments powered by Disqus

Related: motion_towards,