GML [SOLVED] Collision detection not working

D

dicktracy

Guest
Hi!

I have a problem with collision checking. I have a grid based game on which every grid cell can contain only one object. I have a player and enemies. Enemies by now are not moving and the player can move only one cell at once, either horizontally or vertically. My problem here is with collision detection. I tried every possible collision checking method (position_empty, position_meeting, place_meeting etc.). Unfortunately nothing is working for me, and the collision is not detected, so the player can be placed in the enemy cell.
I tried with precise collision checking marked and unmarked for both of objects (object_enemy and object_hero), I also tried to make them solid and set same depth. I checked many times if the coordinates are correct and they are. Both built-in vars x and y for both objects are the same in the collision checking x and y(i.e. x = 562, y = 712 are exactly the same for both objects). I have no more ideas why is this not working.

part of the code that I am using:
Code:
plusx = place_meeting(hero_x + 57, hero_y, o_enemy);
//object hero moves one cell horizontally to the right from hero_x to hero_x + 57(distance to next cell - and exactly x position of the enemy_x, hero_y does not change here and is exactly the same as enemy_y). Collision is still not detected.
and then I use:

Code:
if (!plusx){
  hero_x = hero_x + 57; 
  }
to move a hero, but it always does not detect the collision. I tried also different variation and checking methods and always came to same result - no collision detection. What do I do wrong?
 

jo-thijs

Member
Hi and welcome to the GMC!

There's nothing wrong with the codes you're using, so the issue must lie somewhere else.
Perhaps there is some other code messing things up.
Perhaps there's something wrong with the values of hero_x and hero_y.
Perhaps you've made a mistake with the player or enemy collision masks.
Or perhaps, you've made a mistake in the parent hierarchy involving o_enemy.

Could you provide us with more information about your project?
 
D

dicktracy

Guest
Thank you for your answer. For hero and enemy collision masks I use default settings from sprites -> collision checking checked precise collision checking and in modify mask I use automatic bounding box, which marks whole 52x52 square. Both hero and enemy are the same size and have the same masks settings in sprite. Then in object I have same depth for both of them. Both enemy and hero does not have any parents. Masks are set to be the same as sprite. Enemies after creation are not moving and by now are fast placed on the board. It is like in tower defense games, you can choose your units and place them on the board. After they are placed, the game play out like chess game, but for now you can just move one cell at a time.

The whole code from this script:

Code:
hero = instance_number(o_hero);

 for(i=0; i < hero; i++){
 objId = instance_find(o_hero,i);

hero_x = objId.x;
hero_y = objId.y;

plusx = place_meeting(hero_x + 57, hero_y, o_enemy);
minusx = place_meeting(hero_x - 57, hero_y, o_enemy);
plusy = place_meeting(hero_x, hero_y + 57, o_enemy);
minusy = place_meeting(hero_x, hero_y + 57, o_enemy);

show_debug_message("plusx   "  + string(plusx)); //.. and all above values for testing

if (!plusx){
  hero_x = hero_x + 57;
  } else if ... //some other decision based on collision.
The plan here is that every time an alarm[0] (in o_game) counts down, it calls above presented script. Counter works excellent. Above script is activated and dependent on the result from collision, the hero should move(or not) in one direction(decided in if cases at the end of the script). However before it can come to if's show_debug returns always false, doesn't matter if there is enemy in neighboring cell or not - all 4 directions returns same Boolean. Later on I plan to exchange hero with enemies, that is why I use instance_number and for loop. It is just easier to test collision on one hero and later on just switch places of hero-enemy than making adequate changes for enemies code.

However, here is some show_debug message from one cycle:

plusx 0
minusx 0
plusy 0
minusy 0

hero_x 391
hero_y 199

enemyx_1 448 // 391 + 57 = 448 -> case of plusx, but plusx stil returns false?
enemyy_1 199

enemyx_2 448
enemyx_2 256
 

jo-thijs

Member
This code is executed by some controller object without a sprite and with its collision mask set to be the same as the sprite, isn't it?
Then it is normal that place_meeting is always false, because it uses the mask of the executing instance to check collision with.
However, if there's no mask, then there cannot be a collision.

Using position_meeting is probably better then, but you'll have to be carefull with the sizes of the bounding boxes and the sprite origin.

You could also just use a "with" structure to replace the for loop and instantly solve this issue:
Code:
with o_hero {
    plusx = place_meeting(x + 57, y, o_enemy);
    minusx = place_meeting(x - 57, y, o_enemy);
    plusy = place_meeting(x, y + 57, o_enemy);
    minusy = place_meeting(x, y + 57, o_enemy);
    
    show_debug_message("plusx   "  + string(plusx)); //.. and all above values for testing
    
    if (!plusx){
        x += 57;
    } else if ... //some other decision based on collision.
}
 
D

dicktracy

Guest
YOU are great!! It works like a charm with "with" solution :) I tested it also with multiple heroes generated and no problems with collision detection. Thanks again for your help. Now I can continue with the project :)
 
Top