Legacy GM Check collision with all objects but self?

P

paulog

Guest
Hello! I'm making a simple game in GM1.4 and I want to check if an object is colliding with any other object but not with itself.

This is the code I'm using:

GML:
if position_meeting(x,y,all)
{
global.free = 1
}

if !position_meeting(x,y,all)
{
global.free = 0
}
Tha variable global.free is always 1 even if the only object present is this one, so I'm assuming it's colliding with itself, but really I don't know.
I'd be very grateful if someone could help me out in this.
Thanks in advance
 
You need to grab the instance ID of the colliding instance and compare that to the instance calling the collision. Something like this might work (off the top of my head, haven't tested it):
Code:
var _inst = instance_position(x,y,all);
if (instance_exists(_inst)) {
   if (_inst.id != id) {
      global.free = true;
   }
}
else {
   global.free = false;
}
However, if there is more than one instance running this code, then you're going to run into problems. Personally, I would use a controller object for this type of thing (if you are not already doing that). Also, if you are comparing a boolean value, make sure you use else rather than another if statement, it's more logically consistent (there either is a collision or else there is not, no need for two ifs).
 

Roleybob

Member
That will only store 1 instance id in the var _inst so could still only check against the calling instance's id even if there are collisions with other
instances.

You could use instance_position_list() instead, then check whether there are any values in the resulting ds_list which are not the id of the calling instance

EDIT: this is weird - I'm getting the opposite problem. Using:

Code:
check_space = 0;
if position_meeting(x, y, all)
    check_space = 1;
the value of check_space is always 0. Works fine if I check against specific objects instead of all
 
Last edited:
That will only store 1 instance id in the var _inst so could still only check against the calling instance's id even if there are collisions with other
instances.

You could use instance_position_list() instead, then check whether there are any values in the resulting ds_list which are not the id of the calling instance
Good call, unfortunately, I don't believe GMS1.4 has the list variants of the positional collision functions. One way to get around that is to move the calling instance:
Code:
var xx = x;
x += 10000;
var _inst = instance_position(xx,y,all);
x = xx;
if (instance_exists(_inst)) {
      global.free = true;
}
else {
   global.free = false;
}
EDIT: Removed the ID check as it's unnecessary now.
 
Last edited:

Sabnock

Member
You could make a parent object that all objects / instances are children to and then use instance_place() to get the collision Id.
 
Last edited:

Roleybob

Member
You could make a parent object that all objects / instances are children to and then use instance_place() to get the collision Id.
That would still check against itself. Though you could have a single object which is not a child of the parent object and any instance which wants to check for collisions moves itself away from the collision area, creates an instance of that object to check for collisions, resolves any collisions, destroys the instance, then moves the original instance back. Though you would need more than 1 of these special objects if you are checking for different boundinx box sizes
 
Last edited:

Sabnock

Member
That would still check against itself. Though you could have a single object which is not a child of the parent object and any instance which wants to check for collisions moves itself away from the collision area, creates an instance of that object to check for collisions, resolves any collisions, destroys the instance, then moves the original instance back. Though you would need more than 1 of these special objects if you are checking for different boundinx box sizes
You could just check the collision I'd is not equal to self.

Quite an expensive way of doing things though.
 

Roleybob

Member
If all objects used in the game are children of an object which you do the check against, that should not work any differently than just using all.

Just realised that RefresherTowel's last post includes a way to do it by moving the calling instance as per my previous post, but without the need for creating an extra instance to do the check
 

TheouAegis

Member
Why is he using position_meeting? The post says

check if an object is colliding with any other object
He should be using place_meeting, the only one (other than instance_place) that actually checks for collisions between instances, and checking self would never have been an issue because you can't.

Or if for some odd reason he reeeeally wants position_meeting:
Code:
global.free = 0;
with all if id!=other.id && position_meeting(other.x,other.y,id) {
    global.free = 1;
    break
}
 
Last edited:

FrostyCat

Redemption Seeker
Place vs. Position
The most important difference is whether the function name contains place or position Functions starting with place always put the current instance that is executing the code at the specified position and checks if its sprite (or mask if assigned) collides with another object.

On the other hand, functions named position checks the exact point, regardless of the instance that is executing the code.

placevsposition.png


Here are some consequences:
  • place_*() functions don't work at all if the instance executing the code has no sprite or mask.
  • place_*() functions never detect collision with itself, whereas position functions can be used with self.
 

Roleybob

Member
I don't understand why check_space always holds 0 after this code:

GML:
check_space = 0;
if position_meeting(x, y, all)
    check_space = 1;
If I change all to the object's name, or to self then check_space holds 1 after the code as it should.

In fact, all is not registering any instances at all - the calling instance can be completely within any instances bounding box, including both origins being at exactly the same coordinates and check_space still holds 0 after the code.

I don't need this for anything, just trying to understand why it is - I guess all just doesn't work with position_meeting() in GMS2.
 
Top