• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

When are the bbox values recalculated? Diagonal sprite detection

F

FuturityUK

Guest
Hi All,

When are the bbox values recalculated? I've got a diagonal sprite detection issues and it feels like the bbox values aren't being updated when I change the "y" variable. Is this true?

I've followed a number of tutorials about platform games. I'm an experience programmer in Java etc, so it shouldn't be a simple mistake, just a miss understanding of the GMS2 function behaviour.

My horizontal and vertical collision is working fine, but when I jump diagonally, slightly above the vertical detection point into a tile, the sprite goes into the tile a fair way before being pushed back.

To make sure the problem isn't due to the tile mask, its currently solid (no gaps at all). In fact filling in the mask has made no difference.

I add the movement to Y, test Y axis bbox collision, then change Y to align to the tileset grid. I then immediately afterwards the X axis by add the movement to X, test the X axis bbox collision, then change X to align to the tileset grid.

On the basis of the Y being change first, then the X being changed second, it should avoid any diagonal issues?

Any idea whats going on? Are the bbox values only being updated outside the object.step code?

Thanks for any help

Futurity
 

NightFrost

Member
As far as I know, bbox values should change as soon as you change instance position. Changing position means collision box moves with it, and bbox values reflect the edge positions of a collision box. It doesn't matter in which order you check X and Y deltas. Only when the movement would clip across a box corner it in some cases it would affect if there's a collision or not. Note that bbox values are rounded values (I assume this is because collision detection always works on rounded values, so these will then show you where GMS actually sees your collision box to be). If your movement speeds and positions are not always in full integers, mixing together your actual x/y values, bbox values and movement deltas can lead to 1-pixel rounding errors in collision detection.
 
Last edited:
F

FuturityUK

Guest
Hi Misty, Thanks you for suggesting the precise collision mask. I've just tried it and it seems to be slightly worse than with using a rectangle, which covers the entire sprite.
 
F

FuturityUK

Guest
Hi NightFrost,

Thanks for your detailed reply. Its very good to hear that the bbox values change as the sprite's X and Y variables are modified through the step event.

Thinking about the rounding, the movement from the sprite into the mask is far move than a single pixel. I suspect within 5 or 10 pixels into the mask and this might be corrected over a couple of frames so something very strange is going on.

Could it be the because the sprite size is 92 x 128 pixels and the tileset is 64x64.

Assuming sprite x,y = 0,0
bbox_top = 0
would bbox_bottom = 64 or 128?
bbox_left = 0
would bbox_right be = 64 or 92?

I'm feeling it should be
would bbox_bottom = 128
bbox_left = 0
would bbox_right be = 92

If this is the case, then I'm perhaps missing the collision testing at x = 0, y = 64 as in the middle on the sprite?

Thanks Again
 

Slyddar

Member
As you've suspected, the collision testing on the borders of a mask need to be spaced equal or less then the tileset size, otherwise you will 'slip' over a tile if only testing the corners.
 
F

FuturityUK

Guest
Fantastic, I seem to have a solution. As my sprite is larger than a tile, vertically only in my case, I have to test the tiles that fall withing the sprite.

In my case I was right about the bbox_bottom being 128 pixels below bbox_top and therefor the tile in the middle of the sprite was being ignored / untested.

So hoping it helps someone in the future, here's my solution. Basically test the tile using the halfway point between the bbox_top and bbox_bottom.

var tile_data_blob1 = tilemap_get_at_pixel(tile_map_id, bbox_left, bbox_top) & tile_index_mask;
var tile_data_blob2 = tilemap_get_at_pixel(tile_map_id, bbox_left, bbox_bottom) & tile_index_mask;
var tile_data_blob3 = tilemap_get_at_pixel(tile_map_id, bbox_left, bbox_top + ((bbox_bottom - bbox_top)/2) ) & tile_index_mask;

if (tile_data_blob1 != 0 || tile_data_blob2 != 0 || tile_data_blob3 != 0 )

Ideally there should be a loop testing each 64 pixel increment until bbox_bottom is reached, which I may do if I have time

Thanks again
 
F

FuturityUK

Guest
Thanks everyone. I've been fighting this problem for a few days. Very happy to have found an answer with all your help.
 
Top