GameMaker Script to detect distance to object only working with one object.

C

Chris Livermore

Guest
hi guys and girls,

I am having some issues with a script I have made, Basically I want a space ship to drive up to a planet object and when its inside the diameter of the planet object get smaller (as if to land on the planet) I have got this working correctly

if distance_to_point(argument0.x,argument0.y) <=argument0.sprite_width {
argument1.image_xscale = distance_to_point(argument0.x,argument0.y) /argument0.sprite_width;
argument1.image_yscale = distance_to_point(argument0.x,argument0.y) /argument0.sprite_width;
}


if distance_to_point (argument0.x,argument0.y) <= 50 {
room_goto(argument2);
}

the problem is when I put this in my craft movement script it only detects the first planet I placed and all the others do not trigger.

I am calling it from a simple movement script as below:

if distance_to_object(obj_planet) <= obj_planet.sprite_width{
scr_enter_planet(obj_planet, obj_craft, room0);
}


any ideas? is it something to do with the fact I am comparing to obj_planet? should this be refering to all instances?

any help would be greatly appreciated!
 

NightFrost

Member
Well, distance_to_object will do the heavy lifting for you and picks the nearest instance, but when you refer to obj_planet directly in your script, GM will pick the first instance it can find, usually the first that was created. Since you need to know which the nearest instance is, you should use instance_nearest to figure out its ID.

Note that distance_to_object and distance_to_point give different results. Former calculates the empty space between collision boxes, while the latter calculates distance from edge of collision box to given point, which in this case would be the center of the planet.
 
C

Chris Livermore

Guest
thanks Night frost, for those stumbling into this here is my full solution.

New Script "nearest"
-----------------------------------------------------------------------------------------------------------------------------------
/// @description Nearest(xx, yy, obj, nth)
/// @function Nearest
/// @param xx
/// @param yy
/// @param obj
/// @param nth
/// Returns the nearest obj specified i.e
/// (playerX, playerY, OBJECT TO GET NEAREST, what nearest to get i.e 1 = first nearest).


var xx = argument0;
var yy = argument1;
var object = argument2;
var nth = argument3;

if (nth>0){
nth --;
var dsGrid = ds_grid_create (2,1);
var dsGridY = 0;
//goes through all instances of object and fills them in dsGrid
with (object){
ds_grid_add(dsGrid,0, dsGridY,id);
var dist = distance_to_point(xx,yy);
ds_grid_add(dsGrid,1,dsGridY,dist);
dsGridY ++;
ds_grid_resize(dsGrid,2,dsGridY+1);
}

//sorts the grid into order of distance
ds_grid_resize(dsGrid,2,dsGridY);
ds_grid_sort(dsGrid,1,true);
return ds_grid_get(dsGrid,0,nth);
}
----------------------------------------------------------------------------------------------------------------------------------------
credit to Talent Lost - GameMaker Tutorials on youtube for the above code and tutorial.

then simply call nearest (playerX, playerY, planetObject, nth(this can range from 0-Max number of spawned planets)

you can call this to a var for readability like so:


--------------------------------------------------------------------------------------------------------------------------------------------
var Nplanet = Nearest(x,y,obj_planet,1);

if distance_to_object(Nplanet) <= Nplanet.sprite_width{
scr_enter_planet(Nplanet, obj_craft, room0);
}

-----------------------------------------------------------------------------------------------------------------------------------------
 
Top