Jump to content


Photo

Collision mask scaling


Best Answer Strawbry_Jam, 28 March 2016 - 08:20 AM

 
Then try this:

var col;
for(i = 0; i < instance_count - 1; i++){
    for(k = i + 1; k < instance_count; k++){
       col = false;
//checks if the 2 objects are close enough to each other
//center() is a script I wrote that returns the x and y values of the center of the sprite. usage: center(object, 0 for x and 1 for y)
        if(abs(center(instance_id[i], 0) - center(instance_id[k], 0)) < 2 * max(instance_id[i].sprite_width, instance_id[k].sprite_width) && abs(center(instance_id[i], 1) - center(instance_id[k], 1)) < 2 * max(instance_id[i].sprite_height, instance_id[k].sprite_height)){
            with(instance_id[i]){
                if(place_meeting(x, y, instance_id[k])){
                   col = true;
                 }
             }
            if(col){
//collision is a script I wrote that enacts collisions
                    collision(instance_id[i], instance_id[k]);
            }
        }
    }
}
 
I got an error that reads

 
 
 
___________________________________________
############################################################################################
FATAL ERROR in
action number 1
of  Step Event0
for object PhysEn:
 
Variable obj_AABB.k(100022, -2147483648) not set before reading it.
 at gml_Object_PhysEn_StepNormalEvent_1 (line 28) -                 if(place_meeting(x, y, instance_id[k])){
############################################################################################
 

Add
var i, k;
to the top. Go to the full post


  • Please log in to reply
11 replies to this topic

#1 ContraMuffin

ContraMuffin

    GMC Member

  • New Member
  • 6 posts
  • Version:GM:Studio

Posted 26 March 2016 - 08:50 AM

I've searched the Internet for a long time now and I couldn't find a solution.

I'm creating a physics engine (I need the physics to be customizable for the game I'm making so I can't use Game Maker's in-built physics). To test it out, I made a circle object and a square object. It's been working perfectly, but then I tried scaling the objects. I found out that the collision masks don't scale along with the objects. I use the room editor to place and scale objects, and all sprites are "precise collision checking" selected, "separate collision masks" not selected, origin at (0,0), and nothing else changed. I used 

show_debug_message(image_xscale);
show_debug_message(image_yscale);

 to check for image_xscale and image_yscale and they were indeed scaled properly. I asked on Reddit and the response said that he tried to scale objects in his room editor and collision mask scaled for him. I'm using 

for(i = 0; i < instance_count - 1; i++){
    for(k = i + 1; k < instance_count; k++){
//checks if the 2 objects are close enough to each other
//center() is a script I wrote that returns the x and y values of the center of the sprite. usage: center(object, 0 for x and 1 for y)
        if(abs(center(instance_id[i], 0) - center(instance_id[k], 0)) < 2 * max(instance_id[i].sprite_width, instance_id[k].sprite_width) && abs(center(instance_id[i], 1) - center(instance_id[k], 1)) < 2 * max(instance_id[i].sprite_height, instance_id[k].sprite_height)){ 
            if(place_meeting(instance_id[i].x, instance_id[i].y, instance_id[k])){
//collision is a script I wrote that enacts collisions
                collision(instance_id[i], instance_id[k]);
            }
        }
    }
}

 to check for collisions. I have no idea why the collision mask is scaling. Any idea is appreciated.

Thanks in advance.


Edited by ContraMuffin, 26 March 2016 - 08:51 AM.

  • 0

#2 Insanebrio

Insanebrio

    GMC Member

  • GMC Member
  • 471 posts
  • Version:GM:Studio

Posted 26 March 2016 - 09:56 AM

I didnt understood well, but the collision mask and the sprite both scales with the image xscale yscale vars, if you dont need that you should make your own scale vars and use draw_sprite_ext

Edited by Insanebrio, 26 March 2016 - 10:01 AM.

  • 0

#3 ContraMuffin

ContraMuffin

    GMC Member

  • New Member
  • 6 posts
  • Version:GM:Studio

Posted 26 March 2016 - 06:39 PM

I didnt understood well, but the collision mask and the sprite both scales with the image xscale yscale vars, if you dont need that you should make your own scale vars and use draw_sprite_ext

My issue is that the mask isn't scaling with the sprite, even when I use image_xscale/yscale.


  • 0

#4 Strawbry_Jam

Strawbry_Jam

    Likes Toast

  • GMC Member
  • 345 posts
  • Version:Unknown

Posted 26 March 2016 - 07:12 PM

Try taking out this check:
if(abs(center(instance_id[i], 0) - center(instance_id[k], 0)) < 2 * max(instance_id[i].sprite_width, instance_id[k].sprite_width) && abs(center(instance_id[i], 1) - center(instance_id[k], 1)) < 2 * max(instance_id[i].sprite_height, instance_id[k].sprite_height)){
That check should work ok if there isn't roration but what happens if one instance is rotated 90 degrees? You would have to swap the height and width of that instance. An easier way to deal with that would be using the bbox_* variables and a rectangle in rectangle check.
  • 0
Spoiler

#5 ContraMuffin

ContraMuffin

    GMC Member

  • New Member
  • 6 posts
  • Version:GM:Studio

Posted 26 March 2016 - 08:13 PM

Try taking out this check:

if(abs(center(instance_id[i], 0) - center(instance_id[k], 0)) < 2 * max(instance_id[i].sprite_width, instance_id[k].sprite_width) && abs(center(instance_id[i], 1) - center(instance_id[k], 1)) < 2 * max(instance_id[i].sprite_height, instance_id[k].sprite_height)){
That check should work ok if there isn't roration but what happens if one instance is rotated 90 degrees? You would have to swap the height and width of that instance. An easier way to deal with that would be using the bbox_* variables and a rectangle in rectangle check.

 

That'll be very helpful, I'll look into the bbox stuff.

Do you have any suggestions as to how that code should be written?

And is the collision masks not scaling a bug or a programming error? I'm sort of confused whether it's my fault or Game Maker's fault that the mask isn't scaling.


  • 0

#6 Strawbry_Jam

Strawbry_Jam

    Likes Toast

  • GMC Member
  • 345 posts
  • Version:Unknown

Posted 27 March 2016 - 02:05 AM

Try out the code without the check for if they are close enough. If it works without it, you know it's your code that wasn't working. If they are colliding, but your first check says they aren't close enough, then you never get to check if they are actually colliding. If without the check, if they still aren't triggering a collision, there might be an issue with Game Maker.
  • 0
Spoiler

#7 ContraMuffin

ContraMuffin

    GMC Member

  • New Member
  • 6 posts
  • Version:GM:Studio

Posted 27 March 2016 - 02:49 AM

Try out the code without the check for if they are close enough. If it works without it, you know it's your code that wasn't working. If they are colliding, but your first check says they aren't close enough, then you never get to check if they are actually colliding. If without the check, if they still aren't triggering a collision, there might be an issue with Game Maker.

I've put a bunch of show_debug_message()s all over the place. In particular (since I had a slight difficulty with setting up the collision checking) I put a bunch of them in collision checking (I removed them in my post because they didn't really do anything). The 2 objects do in fact trigger the "close enough" distance check, but the actual collision checking returns false (I've tested this extensively. To test, I have one square set to xscale and yscale of 2 and one square set to xscale and yscale of 1, and I arrange these 2 in different locations. The collision will only be triggered when the smaller square is intersecting the upper left hand section of the larger square [ie where the unscaled square would be]).

 

Seeing as how I'm probably not going to be able to scale the mask along with the sprite, is there any commands that would let me scale the mask manually? (Since I could just use image_xscale to get the scale factor)


Edited by ContraMuffin, 27 March 2016 - 02:52 AM.

  • 0

#8 Strawbry_Jam

Strawbry_Jam

    Likes Toast

  • GMC Member
  • 345 posts
  • Version:Unknown

Posted 27 March 2016 - 03:14 AM

Then try this:

var col;
for(i = 0; i < instance_count - 1; i++){
    for(k = i + 1; k < instance_count; k++){
       col = false;
//checks if the 2 objects are close enough to each other
//center() is a script I wrote that returns the x and y values of the center of the sprite. usage: center(object, 0 for x and 1 for y)
        if(abs(center(instance_id[i], 0) - center(instance_id[k], 0)) < 2 * max(instance_id[i].sprite_width, instance_id[k].sprite_width) && abs(center(instance_id[i], 1) - center(instance_id[k], 1)) < 2 * max(instance_id[i].sprite_height, instance_id[k].sprite_height)){
            with(instance_id[i]){
                if(place_meeting(x, y, instance_id[k])){
                   col = true;
                 }
             }
            if(col){
//collision is a script I wrote that enacts collisions
                    collision(instance_id[i], instance_id[k]);
            }
        }
    }
}

  • 0
Spoiler

#9 TheouAegis

TheouAegis

    GMC Member

  • GMC Member
  • 13885 posts
  • Version:GM:Studio

Posted 27 March 2016 - 07:09 AM

Post a screenshot of when the collision SHOULD be happening but the code is saying it isn't happening.


  • 0

"The problem with object-oriented languages is that they've got all this implicit environment that they carry around with them. You wanted a banana but what you've got is a gorilla holding the banana and the entire jungle." -Joe Armstrong

 

"It goes against the grain of modern education to teach children to program. What fun is there in making plans, acquiring discipline in organizing thoughts, devoting attention to detail and learning to be self-critical?" -Alan Perlis

 

"Do not think about where you want to be and how to get there; think about what you want to do and how to do it." -Theou Aegis


#10 ContraMuffin

ContraMuffin

    GMC Member

  • New Member
  • 6 posts
  • Version:GM:Studio

Posted 28 March 2016 - 05:15 AM

 

Then try this:

var col;
for(i = 0; i < instance_count - 1; i++){
    for(k = i + 1; k < instance_count; k++){
       col = false;
//checks if the 2 objects are close enough to each other
//center() is a script I wrote that returns the x and y values of the center of the sprite. usage: center(object, 0 for x and 1 for y)
        if(abs(center(instance_id[i], 0) - center(instance_id[k], 0)) < 2 * max(instance_id[i].sprite_width, instance_id[k].sprite_width) && abs(center(instance_id[i], 1) - center(instance_id[k], 1)) < 2 * max(instance_id[i].sprite_height, instance_id[k].sprite_height)){
            with(instance_id[i]){
                if(place_meeting(x, y, instance_id[k])){
                   col = true;
                 }
             }
            if(col){
//collision is a script I wrote that enacts collisions
                    collision(instance_id[i], instance_id[k]);
            }
        }
    }
}

 

I got an error that reads

 

 

 
___________________________________________
############################################################################################
FATAL ERROR in
action number 1
of  Step Event0
for object PhysEn:
 
Variable obj_AABB.k(100022, -2147483648) not set before reading it.
 at gml_Object_PhysEn_StepNormalEvent_1 (line 28) -                 if(place_meeting(x, y, instance_id[k])){
############################################################################################
 

 

 

 

 

Post a screenshot of when the collision SHOULD be happening but the code is saying it isn't happening.

 

I don't know how to post pictures


Edited by ContraMuffin, 28 March 2016 - 05:16 AM.

  • 0

#11 Strawbry_Jam

Strawbry_Jam

    Likes Toast

  • GMC Member
  • 345 posts
  • Version:Unknown

Posted 28 March 2016 - 08:20 AM   Best Answer

 
Then try this:

var col;
for(i = 0; i < instance_count - 1; i++){
    for(k = i + 1; k < instance_count; k++){
       col = false;
//checks if the 2 objects are close enough to each other
//center() is a script I wrote that returns the x and y values of the center of the sprite. usage: center(object, 0 for x and 1 for y)
        if(abs(center(instance_id[i], 0) - center(instance_id[k], 0)) < 2 * max(instance_id[i].sprite_width, instance_id[k].sprite_width) && abs(center(instance_id[i], 1) - center(instance_id[k], 1)) < 2 * max(instance_id[i].sprite_height, instance_id[k].sprite_height)){
            with(instance_id[i]){
                if(place_meeting(x, y, instance_id[k])){
                   col = true;
                 }
             }
            if(col){
//collision is a script I wrote that enacts collisions
                    collision(instance_id[i], instance_id[k]);
            }
        }
    }
}
 
I got an error that reads

 
 
 
___________________________________________
############################################################################################
FATAL ERROR in
action number 1
of  Step Event0
for object PhysEn:
 
Variable obj_AABB.k(100022, -2147483648) not set before reading it.
 at gml_Object_PhysEn_StepNormalEvent_1 (line 28) -                 if(place_meeting(x, y, instance_id[k])){
############################################################################################
 

Add
var i, k;
to the top.
  • 0
Spoiler

#12 ContraMuffin

ContraMuffin

    GMC Member

  • New Member
  • 6 posts
  • Version:GM:Studio

Posted 29 March 2016 - 05:12 AM

 

 

 
Then try this:

var col;
for(i = 0; i < instance_count - 1; i++){
    for(k = i + 1; k < instance_count; k++){
       col = false;
//checks if the 2 objects are close enough to each other
//center() is a script I wrote that returns the x and y values of the center of the sprite. usage: center(object, 0 for x and 1 for y)
        if(abs(center(instance_id[i], 0) - center(instance_id[k], 0)) < 2 * max(instance_id[i].sprite_width, instance_id[k].sprite_width) && abs(center(instance_id[i], 1) - center(instance_id[k], 1)) < 2 * max(instance_id[i].sprite_height, instance_id[k].sprite_height)){
            with(instance_id[i]){
                if(place_meeting(x, y, instance_id[k])){
                   col = true;
                 }
             }
            if(col){
//collision is a script I wrote that enacts collisions
                    collision(instance_id[i], instance_id[k]);
            }
        }
    }
}
 
I got an error that reads

 
 
 
___________________________________________
############################################################################################
FATAL ERROR in
action number 1
of  Step Event0
for object PhysEn:
 
Variable obj_AABB.k(100022, -2147483648) not set before reading it.
 at gml_Object_PhysEn_StepNormalEvent_1 (line 28) -                 if(place_meeting(x, y, instance_id[k])){
############################################################################################
 

Add
var i, k;
to the top.

 

 

Thanks, the code worked!


  • 0