trying to mkae collision smaller than the object.

ChrisC

Member
i was using if place_meeting(x,y,oParEnemy)

but it makes the collision on the edges of them and dont want them to collide so far away.

So i tried this. if point_in_rectangle(oParEnemy.x,oParEnemy.y,oParPlayer.x+4,oParPlayer.y+4,oParPlayer.x-4,oParPlayer.y-4)

but it doesnt seem to do anything. Im trying to have the collsion just be the center 8x8 pixels of the object. Could someone please help how I could do this?
 

woods

Member
collision just be the center 8x8 pixels of the object

i would make an invisible 8x8 object that follows the enemy and check collision with that instead
 

TheouAegis

Member
If that 8x8 area will not change, set the collision mask in the Sprite resource itself. If it can change, such as if you are moving hitboxes around and stuff, then create multiple sprites with nothing in them but the size of each of those collision masks that you want. Then in code you can change the mask_index to whichever size you need.

If you are going to be rotating things around, don't even bother with collision checks and just check if the distance between any two instances' centers of mass is less than 8 (or half of size1 + size2 if different sizes).
 
Last edited:

ChrisC

Member
collision just be the center 8x8 pixels of the object

i would make an invisible 8x8 object that follows the enemy and check collision with that instead
I tried to do this. I was able to make the 8x 8 object follow the playuer and enemy but i couldnt figure out how to control the actions of the enemy with collsion of the object.

You should probably learn about collision masks. It's in the Manual.
I changed the collision mask but it doesnt change anything. I couldnt find anywhere in the manual to make the place_meeting the mask instead of the object.
This would only work if there is one player and one enemy.
oh ok thanks.
If that 8x8 area will not change, set the collision mask in the Sprite resource itself. If it can change, such as if you are moving hitboxes around and stuff, then create multiple sprites with nothing in them but the size of each of those collision masks that you want. Then in code you can change the mask_index to whichever size you need.

If you are going to be rotating things around, don't even bother with collision checks and just check if the distance between any two instances' centers of mass is less than 8 (or half of size1 + size2 if different sizes).
I changed the masks but the sprite edges still cause the collision on place_meeing.
 

TheouAegis

Member
Make sure you don't have residual code leftover that you no longer need. You can also post screenshots of your Sprite properties in case you did something wrong there. Because your issue would have been resolved normally by anything that has been suggested here if all old offending code had been removed.
 

ChrisC

Member
Make sure you don't have residual code leftover that you no longer need. You can also post screenshots of your Sprite properties in case you did something wrong there. Because your issue would have been resolved normally by anything that has been suggested here if all old offending code had been removed.
I made a collision mask a small box on all of the player sprites and all the enemy sprites, the goal is that he wont grab the enemy until those collide.
1593659901170.png

GML:
if place_meeting(x,y,oParEnemy)
    and (state != JUMP and weapon = "") // If is colliding with an item
    and canGrab                                    // ..and Player is not grabbing anything...
        {           
            if (vx != 0 or vy != 0)
            {
                grabbedId = instance_place(x,y,oParEnemy)                    // ..get the Id of the opponent to grab...
                if grabbedId.grabbable                                        // ..and check if its grabbable. If it is...
                and abs(grabbedId.depth - depth) <= EnemyLayerSize
                and abs(grabbedId.y - y) <= EnemyLayerSize                    // Check if Player and Opponent are in the depth and Y range to receive hit
                and grabbedId.state = grabbedId.IDLE or grabbedId.state = grabbedId.RUN or grabbedId.state = grabbedId.WAIT or grabbedId.state = grabbedId.RETREAT    // Check that opponent is in an available state                    // Check that opponent is out of HIT state
                {
                    state = GRAB;                                            // ..GRAB it/him/her!
                    canGrab = false;                                        // Can't grab anything more while grabbing
                    vx = 0                                                // Can't move either
                    vy = 0
                    grabbedId.state = grabbedId.GRABBED;                    // Set the opponent state to GRABBED
                    grabbedId.grabbed = true;
                    grabbedId.grabberId = id;                    // Pass to the opponent which instance is grabbing him/her
                    grabbedId.x = x + sprite_width/2;            // And reposition it/him/her to adapt to the animation
                    oParEnemy.showInfo = false;                    // Hide any other enemys HealthBar
                    grabbedId.showInfo = true;                    // Show the grabbed opponent HealthBar
                }
                else
                {
                    state = IDLE;
            
                    
                }
            }
        }
 

TheouAegis

Member
and grabbedId.state = grabbedId.IDLE or grabbedId.state = grabbedId.RUN or grabbedId.state = grabbedId.WAIT or grabbedId.state = grabbedId.RETREAT // Check that opponent is in an available state
Put ( ) around this entire clause after the and. My guess is the order of operations with all of those ors is screwing that conditional up. However, your first place_meeting() I would have expected to prevent that from happening, but it's definitely worth fixing in my opinion.


if grabbedId.grabbable // ..and check if its grabbable. If it is...
and abs(grabbedId.depth - depth) <= EnemyLayerSize
and abs(grabbedId.y - y) <= EnemyLayerSize // Check if Player and Opponent are in the depth and Y range to receive hit
and (grabbedId.state = grabbedId.IDLE or grabbedId.state = grabbedId.RUN or grabbedId.state = grabbedId.WAIT or grabbedId.state = grabbedId.RETREAT ) // Check that opponent is in an available state // Check that opponent is out of HIT state
 

ChrisC

Member
Put ( ) around this entire clause after the and. My guess is the order of operations with all of those ors is screwing that conditional up. However, your first place_meeting() I would have expected to prevent that from happening, but it's definitely worth fixing in my opinion.


if grabbedId.grabbable // ..and check if its grabbable. If it is...
and abs(grabbedId.depth - depth) <= EnemyLayerSize
and abs(grabbedId.y - y) <= EnemyLayerSize // Check if Player and Opponent are in the depth and Y range to receive hit
and (grabbedId.state = grabbedId.IDLE or grabbedId.state = grabbedId.RUN or grabbedId.state = grabbedId.WAIT or grabbedId.state = grabbedId.RETREAT ) // Check that opponent is in an available state // Check that opponent is out of HIT state
You are a miracle worker. The ( ) on the ends of the states seemed to fix it.
 
Top