Jump to content


Photo

place_meeting not working when being called through a with statement?

gm:studio

Best Answer flyingsaucerinvasion, 28 March 2016 - 11:42 PM

Okay, so the reason the amulet is not created in the control_obj code, is because scr_enemy_player_collision_player_wins runs before the control_obj's step event.

 

Either put all the code pertaining to collisions between the player and that enemy into a single place...

 

Or change enemy_obj's step event into a step end event.

 

I think it would be far better to put the collision code in one place.

Go to the full post


  • Please log in to reply
11 replies to this topic

#1 DerpsDev

DerpsDev

    GMC Member

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

Posted 27 March 2016 - 08:44 AM

Basically I have two objects (enemy_obj and player_obj) that are colliding and the collision detection is working fine when checked from those objects. BUT I am using a third object with no sprite I put in the room that is not part of the collision at all, for room/object instance checking. I want to check and see if it is a specific instance of enemy_obj (named enemy1) and I am running basically identical code for the collision. The if statements handling the collision are not returning true in this case. I am using a with statement from this control object to access the variables of the other two (player_obj & enemy_obj). If I take out the collision code, the rest of it works fine. Anyone know how I can fix this??? Any help will be much appreciated thanks!!

I have an enemy_obj, a player_obj  a control_obj  and an amulet_obj which is supposed to be dropped when this particular instance of the enemy dies.

 

code from the enemy object`s step event:

 

​    //collision with player
      if (place_meeting(x,y,player_obj) )
    {
        if(player_obj.y<y)
        {
            scr_enemy_player_collision_player_wins();  
        }
        else
        { 
            scr_enemy_player_collision_enemy_wins();
        }
    }

//***************************************************************

the script scr_enemy_player_collision_player_wins():

 

   

    with(player_obj)
    {
  
        vsp = -jump_speed;
    }
 
    instance_destroy();  // I even took this line out to see if this was making it so that there was no more object to reference by the control_obj and still no dice.

 

//******************************************************************

the code being called from the control_obj step event

   
with(enemy1)

   if (place_meeting(x,y,player_obj))
    {
        if(player_obj.y<y)
        {
            instance_create(player_obj.x,player_obj.y,amulet_obj);
        }
       
    
    }
  
}


Edited by DerpsDev, 28 March 2016 - 02:46 AM.

  • 0

#2 johnboy

johnboy

    GMC Member

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

Posted 27 March 2016 - 10:26 PM

I'm not too sure if the fact your object doesn't have a sprite will affect place_meeting - I think it would.....What you could do is use the x/y coordinates instead.

 

Define a "space" for your invisible object like this:

inv_obj.x-20;

inv_obj.x+20;(obviously the value of 20 here would be whatever half the width is if you have a central origin point)

inv_obj.y-20;

inv_obj.y+20;(obviously the value of 20 here would be whatever half the height is if you have a central origin point)

 

which you'd use like this to check against an object with a sprite: (you could use the sprites bounding box here)

(create event)

x_hit=false;
y_hit=false;

(step event)

if bbox_left > inv_obj.x-20 && bbox_left < inv_obj.x+20 || bbox_right > inv_obj.x-20 && bbox_right < inv_obj.x+20
{x_hit=true; }    //one of its sides is inbetween the horizontal "space" the invisible object is occupying
else
{x_hit=false;}

if bbox_bottom > inv_obj.y-20 && bbox_bottom < inv_obj.y+20 || bbox_top > inv_obj.x-20 && bbox_top < inv_obj.x+20
{y_hit=true; }   //either its top or bottom is inbetween the vertical "space" the invisible object is occupying
else
{y_hit=false;}

if x_hit && y_hit
{is in collision}

Hopefully I've typed that correctly, but you should be able to get the basic premise - it uses very straightforward comparisons, and is (a) less intensive than collision checks, and (b) as I said I don't think collision checks will work because you have no sprite (but I could be wrong about that, as I haven't checked in GMS to be sure) 


Edited by johnboy, 27 March 2016 - 10:27 PM.

  • 0

#3 flyingsaucerinvasion

flyingsaucerinvasion

    GMC Member

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

Posted 27 March 2016 - 10:31 PM

what is "enemy1"?  As long as whatever that is has a collision mask, and so does the palyer_obj, then place_meeting should work.  However you never tell us what enemy1 is, so maybe its definition is the problem.


  • 0

#4 DerpsDev

DerpsDev

    GMC Member

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

Posted 28 March 2016 - 02:45 AM

 @ flyingsaucerinvasion enemy1 is what I renamed the specific instance of enemy_obj. So that I could easily reference it through the code. I stated that in the opening paragraph but there was alot there. And the code recognizes the instance, but not the collision.


@johnboy Thanks. It looks like the code you wrote would check if an object was colliding with the invisible object. That's good to know how I`d do that, but I actually just want to use that object to check the collision between the player and the enemy. And the invisible control object wouldn't be a part of the collision at all, its just that I wanted to run these specific checks from a third party object if that makes sense.


@flyingsaucerinvasion sorry. I just realized I wrote object1 instead of enemy1 in the paragraph... XD sorry.. It was late when I wrote that.


  • 0

#5 flyingsaucerinvasion

flyingsaucerinvasion

    GMC Member

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

Posted 28 March 2016 - 03:24 AM

Hmm... well the only other things that I can see that might be going wrong are... maybe the objects aren't where they appear to be (because drawn in wrong place), or player.y is never less than the enemy's y, or player_obj isn't what you think it is.

 

When you say enemy1 is an instance of enemy_obj, I assume you mean it is either a variable held in the controller object, or a name given to an instance in the room editor.  But in either case, it will only refer to a single instance of enemy_obj.  No others instances of enemy_obj in the room will be involved with the "with" statement in the controller object.


Edited by flyingsaucerinvasion, 28 March 2016 - 03:34 AM.

  • 0

#6 DerpsDev

DerpsDev

    GMC Member

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

Posted 28 March 2016 - 03:45 AM

Ya I renamed the instance in the room editor. It is definitely only supposed to reference that one instance. And it recognizes it as long as I'm not using the collision code. It`s weird because it`s the exact same code that is in the enemy_obj to check for collisions and that code executes fine. I changed it so that instead of just rerunning the collision code, it checks for a flag that I set in the enemy_obj code. This works, as long as I don't call instance_destroy so that it has nothing to reference. So now I`m trying to use another with statement in the enemy_obj code changing a flag in the control_obj and run the code off of that, but that is giving me problems too.. XD I feel like I'm missing something about how the with statement works...


Edited by DerpsDev, 28 March 2016 - 03:46 AM.

  • 0

#7 flyingsaucerinvasion

flyingsaucerinvasion

    GMC Member

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

Posted 28 March 2016 - 03:57 AM

I think you are indeed using the with statement correctly.  I don't know what could be going wrong.  Maybe there's something wrong with amulet_obj. 


  • 0

#8 DerpsDev

DerpsDev

    GMC Member

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

Posted 28 March 2016 - 04:06 AM

I got it to do what I wanted by just using a flag variable in the enemy_obj, and checking that variable from the control object  and setting its x = -1 and y = -1; Then making it check in the step: if(x == -1 && y == -1 ) {instance_destroy};

 

It works but I really wanted to handle specific instance collisions from the control object because I can see it getting cluttered in the enemy_obj scripts.


Thanks for your help flyingsauserinvasion. I`m just really confused as to why it wasn't working the original way.


  • 0

#9 flyingsaucerinvasion

flyingsaucerinvasion

    GMC Member

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

Posted 28 March 2016 - 04:14 AM

Hey, if you want help figuring it out, send me a PM of your project download, and I'll look at it and try to figure out why it wasn't working from the control object. I'd like to know what the problem was for my own curiosity.


  • 0

#10 DerpsDev

DerpsDev

    GMC Member

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

Posted 28 March 2016 - 09:24 PM

Okay sure thanks man!


  • 0

#11 flyingsaucerinvasion

flyingsaucerinvasion

    GMC Member

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

Posted 28 March 2016 - 11:42 PM   Best Answer

Okay, so the reason the amulet is not created in the control_obj code, is because scr_enemy_player_collision_player_wins runs before the control_obj's step event.

 

Either put all the code pertaining to collisions between the player and that enemy into a single place...

 

Or change enemy_obj's step event into a step end event.

 

I think it would be far better to put the collision code in one place.


Edited by flyingsaucerinvasion, 28 March 2016 - 11:42 PM.

  • 0

#12 DerpsDev

DerpsDev

    GMC Member

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

Posted 29 March 2016 - 02:40 AM

Okay thanks! I figured that the order it was being executed had something to do with it. I wasn't familiar with step end. Ya I agree, maybe I'm just making it more complicated by splitting it up. Thanks for your help!
  • 0





Also tagged with one or more of these keywords: gm:studio