GMS 2 Create new instance without collision

Discussion in 'Programming' started by Daniel Cáceres, Oct 1, 2019.

Tags:
  1. Daniel Cáceres

    Daniel Cáceres Member

    Joined:
    Oct 1, 2019
    Posts:
    5
    I'm trying to create a new instance object if there is not another instance that collides with at cursor coordinates. The thing is that the new instance is created if I click in an empty space, both if it collides or not.

    if (mouse_check_button_pressed(mb_left)) {
    if (instance_position(mouse_x, mouse_y, obj_myobject) == noone){
    instance_create_layer(mouse_x, mouse_y, "instances",obj_myobject);
    }
    }
    Thnak you
     
  2. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    2,037
    It's odd but for a different reason. As written your code should only work if there is no collision. You could should be:

    Code:
    
    if (mouse_check_button_pressed(mb_left)) {
        if (instance_position(mouse_x, mouse_y, obj_myobject) != noone) { //change here
            instance_create_layer(mouse_x, mouse_y, "instances", obj_myobject);
        }
    }
    
    
    Your code should not have created an instance if there was a collision. Perhaps your sprite's mask is off?
     
  3. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,908
    instance_position() checks for a point. If there's nothing at the mouse's position, then instance_position() is true.
    instance_place() compares bounding boxes. If there's nothing at the mouse's position but within the bounds of a bounding box placed at the mouse there is, then instance_place() is false.

    So you need to either make the object running this code invisible and give it the same sprite as obj_myobject, or you need to first create obj_myobject and have it check for the collision, then destroy itself if there is one.

    There are a couple other methods using such functions as collision_rectangle(), but you'd need to fetch the left, top, right, and bottom bounds of obj_myobject's sprite relative to obj_myobject's sprite's origin and add those values to mouse_x and mouse_y. The aforementioned methods are sloppier but easier to work with. lol
     
    ParodyKnaveBob likes this.
  4. Daniel Cáceres

    Daniel Cáceres Member

    Joined:
    Oct 1, 2019
    Posts:
    5
    Thanks,
    I made it work using collision_rectangle(...). Although I have to test it further as the instances I want to create when clicking are balls with a precise collision mask. And I want to prevent new ball instances from collisioning with existing ones. I guess a rectangle will not be enough.
    I didn't understand how is working instance_place(), it's always returning noone.
     
  5. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,908
    Because you didn't give the calling instance a sprite.
     
  6. Daniel Cáceres

    Daniel Cáceres Member

    Joined:
    Oct 1, 2019
    Posts:
    5
    obj_c1 is visible, marked as solid and has a Sprite 64*64. I have the following code in obj_c1 step event:

    if (mouse_check_button_pressed(mb_left)) {
    inst_1 = collision_rectangle(mouse_x - 1 , mouse_y - 1, mouse_x + 1 , mouse_y + 1, obj_c1, false, false);
    inst_2 = instance_position(mouse_x, mouse_y, obj_c1);
    inst_3 = instance_place (mouse_x, mouse_y, obj_c1);

    show_debug_message("inst_1 is "+string(inst_1 != noone));
    show_debug_message("inst_2 is "+string(inst_2 != noone));
    show_debug_message("inst_3 is "+string(inst_3 != noone));
    }

    Output when clicking inside the object is:
    inst_1 is 1
    inst_2 is 1
    inst_3 is 0

    Output when clicking outside the object is:
    inst_1 is 0
    inst_2 is 0
    inst_3 is 0

    So collision_rectangle() and instance_position() do what I expect, but inst_3 is always returning 0. Where is my error?
     
  7. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,908
    How many obj_c1 are in the room? so the objects is trying to avoid collisions with its own kind? The first two codes will return the calling instance if you clicked on the calling instance. The third code only works if you click on a separate instance of obj_c1.
     
  8. Daniel Cáceres

    Daniel Cáceres Member

    Joined:
    Oct 1, 2019
    Posts:
    5
    There is just one instance of obj_c1 in the room. What I'm trying to do is to create a new instance of obj_c1 at cursor's position only if it does not collide with an existing one (of the same kind). Well, my final aim is to dinamically create several instances of the same object at random positions and make sure that they do not collide with each other.

    I think instance_place() is designed to check collision between objects of diferent kind. For example :

    if (mouse_check_button_pressed(mb_left)) {
    if (instance_place(mouse_x,mouse_y, obj_c2) != noone) {
    show_debug_message ("it will collision");
    }else {
    instance_create_layer(mouse_x,mouse_y, "instances", obj_c1);
    }
    }
    This code in the step event of obj_c1 will create a new obj_c1 instance if it does not collide with an already existing instance of obj_c2. But my aim is to work with objects of the same kind and check for precise collisions (as they are balls) before creating them.

    Thank you for your effort.
     
  9. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,908
    No, it doesn't care what kind you are looking for. As I have said, your code is running from inside obj_c1, which you said there's only one of. An instance cannot collide with itself.

    This code should be in a separate object of which there will only ever be at most one in the room and that object should be assigned at the time that you're performing the checks the Sprite of the object which you are trying to spawn in.
     
  10. Daniel Cáceres

    Daniel Cáceres Member

    Joined:
    Oct 1, 2019
    Posts:
    5
    I don't understand very well your second paragraph, but I think the key is when you say that an instance cannot collide with itself. When I use instance_place() the calling instance object is moved to the new position (where I clicked) and checks if there's a collision with another instance at the new position. As there is no instance at the new position it returns noone. After the check is done, the instance is moved back to its original position.

    I solved he problem with the following code in a control object (without sprite):

    if (mouse_check_button_pressed(mb_left)) {
    if (instance_number(obj_c1) == 0 || collision_circle(mouse_x, mouse_y, obj_c1.sprite_xoffset, obj_c1, false, false) == noone) {
    instance_create_layer(mouse_x, mouse_y, "instances", obj_c1);​
    }​
    }
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice