GML With/distance_to_object/place_meeting

J

Joe Banko

Guest
I have an object, hitbox and another object, o_enemy_parent. I want to detect a collision between the 2 object using the following code:

with(o_enemy_parent) {
var dto = distance_to_object(other);
if dto < 100 {
var pm = place_meeting(x, y, other)
if pm {
...
...

I register a collision and setting breakpoints at "if dto" and "if pm". for dto I get a value of ~31 but I get a value of false for pm. Why am I not getting a true for pm? The x, y values of o_enemy_parent (.Self) are 644, 415 and the x, y of other are 777, 415. It would seem that to get a true for pm I would have to add 100 to x and y in place_meeting but that doesn't work either. I'm totally baffled by this code which I used in another tutorial application and it worked fine there. I'm seriously missing something but not sure what it is.

TIA,

joeb
 

FrostyCat

Redemption Seeker
distance_to_object() starts counting from the edge of the collision box, not the origin. This is clearly stated in the Manual:
The Manual's entry on distance_to_object() said:
This function calculates the distance from the edge of the bounding box of the calling instance to the nearest edge of the nearest instance of the object specified.
From this definition, it's obvious that a distance_to_object() result of 31 means there is no collision, as do any other positive value.
 
J

Joe Banko

Guest
Still learning but as I said this worked in the tutorial class I took plus for a beginner I get confused what I'm talking about when a weapon collision object calls an enemy object to see if the enemy has collided with the weapon collision box.
And yes I hit the manual as much as I can before posting. Thanks for the reply, it IS much appreciated.

joeb
 
J

Joe Banko

Guest
//player stab hitbox
////cycle thru all enemies and see if they were hit
with(o_enemy_parent) {
var dto = distance_to_object(other);
if dto < 60 {
var pm = place_meeting(x, y, other)
if pm {
if !hurt {
hurt = true;

This code is virtually identical from Castle Raider, an excellent tutorial course on platformers, the only difference being the dto and the pm vars so I could see the values returned by the functions. That code works perfectly. Currently dto = 11 in the image, the pink area around the sword is the player_stab_hitbox object and the collision mask of the skeleton is the ENTIRE skeleton object. So why am I seeing positive 11? As you can see in the graphic my stab hitbox object is well within the collision mask of the skeleton yet pm NEVER returns true! I have all the collision masks set up and just am TOTALLY frustrated why pm never goes tru in my code. I have been back and forth between the files and the manual at least a dozen times over the past 2 days and have started from scratch 3 times on the sprite and code. I am out of options where to look and am hoping anyone might have some insight. Please help!

Thanks,

joeb
 

Attachments

FrostyCat

Redemption Seeker
If that's what the tutorial says, then it is not an excellent tutorial course. Having the player loop through and proxy behaviours for enemies is an example of dependency inversion, which is a no-no in software architecture. A lot of tutorials written by authors whose pedigree is in design rather than programming teach habits that actual programmers like me cringe at.

What should have happened instead is the enemies checking for collisions against the player in their own step events, like this:
Code:
if (place_meeting(x, y, obj_player)) {
  if (!hurt) {
    hurt = true;
And unless there is something that should happen when the enemy is close to the player, the distance_to_object() part can be skipped completely. If their intention is to save computational time by not considering instances far away, the only time when that argument holds is if precise collisions are involved. With box-shaped collision masks on both sides (which is the default if you left the mask as-is on the sprites), the distance_to_object() call is easily more expensive than the collision check that it's trying to spare.
 

Slyddar

Member
And unless there is something that should happen when the enemy is close to the player, the distance_to_object() part can be skipped completely. If their intention is to save computational time by not considering instances far away, the only time when that argument holds is if precise collisions are involved. With box-shaped collision masks on both sides (which is the default if you left the mask as-is on the sprites), the distance_to_object() call is easily more expensive than the collision check that it's trying to spare.
In my testing, the advantage a place_meeting check has over a distance_to_object check is around 1500 microseconds over 60000 iterations. So if you have 1000 enemies to check, it will be around 15 microseconds per 1000000 microseconds. I wouldn't call that easily more expensive.

In answer to the op, draw the mask of the enemy. Maybe it's not where you think it is.
 
Last edited:
J

Joe Banko

Guest
All I wanted was some ideas on how to address my issues, not start a thread war based on my opinion which remains that the course was excellent in overall presentation and game concepts. Based on my 35 years in the engineering arena, programming in multiple languages, assembler and hardwired switches to bit slice boards I say that I picked up quite a bit of game theory and finite state machine concepts. Which is why I took the course. At this point in time I could give a rat's patootie about performance. I need an operational prototype that I can work with and eventually look at performance when I know what I need to speed up. That's when I ask the how to make it faster questions.
Sheesh.....

Thanks TheSly, good idea, which is what I was looking for!

best
joeb
 
Top