mrdaneeyul
Member
Hey everyone! So I've made several attempts at understanding the complex world of bitwise operations so I can get tile collisions all figured out, and this time I figured I'd just ask! I've read up on the new articles in the GMS2 manual, done lots of research prior, and looked through the demos in GMS and GMS2 that exhibit tile collision.
There's a demo in GMS2 called "YoYo Dungeon Lite" that uses this tile collision method, and I'd love to give this a shot. The only thing is, I don't understand what all the collision code is doing or how to replicate it for smaller tile sizes (16px instead of 32px).
Here's the tile collision code. I'll make comments on things I understand and don't understand.
I would be very grateful if someone could help explain what's going on in these bitwise operations, as well as where the numbers in the macros are coming from! In addition, how would I do this for 16px tiles, and how could I accommodate diagonal checks as well? Any clarity on this is appreciated.
There's a demo in GMS2 called "YoYo Dungeon Lite" that uses this tile collision method, and I'd love to give this a shot. The only thing is, I don't understand what all the collision code is doing or how to replicate it for smaller tile sizes (16px instead of 32px).
Here's the tile collision code. I'll make comments on things I understand and don't understand.
Code:
/// ProcessCollision(_inst, _collision, _dx,_dy, _left,_right, _top,_bottom)
#macro TILE_SIZE 32 // this is labeled "size of debug tilemap". I assume not needed since I don't have a debug tilemap
#macro TILE_SHIFT 5 // "1<<5 = 32" - I'm not sure what this means or where these numbers are coming from.
var _inst = argument0; //The id of the object. In this case, the player
var _dx = argument1; //The horizontal speed to add/subtract to the player's x
var _dy = argument2; //The vertical speed " " " y
var _right = argument3; //The player's bounding borders (distance from origin?)
var _left = argument4;
var _top = argument5;
var _bottom = argument6;
var COLLISION_DEBUG=false;
var DEBUG_TILE = 2;
with( _inst )
{
// Now move and do collision checks.
x += _dx;
y += _dy;
if( dir = DIR_RIGHT ){
//Here I get that we're checking the top right and top left corners to make sure it doesn't overlap a tile, but not sure how.
var tx = (x+_right)>>TILE_SHIFT; // What is ">>" and how does it check the right edge?
var ty1 = ((y+_bottom)>>TILE_SHIFT);
var ty2 = ((y-_top)>>TILE_SHIFT);
if( COLLISION_DEBUG ){
tilemap_set(DebugMap, DEBUG_TILE, tx,ty1);
tilemap_set(DebugMap, DEBUG_TILE, tx,ty2);
}
// collision data never has flips etc...
var tile1 = tilemap_get(WallMap, tx,ty1 )& tile_index_mask; //More bitwise--what is this doing?
var tile2 = tilemap_get(WallMap, tx,ty2 )& tile_index_mask;
if(( tile1!=0 ) || (tile2!=0)) { //Pretty sure this is checking whether tiles exist at top right & top left
x = (tx<<TILE_SHIFT)-TILE_SIZE+(TILE_SIZE-_right); //Uh...
}
}
if( dir = DIR_LEFT ){
var tx = (x-_left)>>TILE_SHIFT; // check right edge
var ty1 = ((y+_bottom)>>TILE_SHIFT);
var ty2 = ((y-_top)>>TILE_SHIFT);
if( COLLISION_DEBUG ){
tilemap_set(DebugMap, DEBUG_TILE, tx,ty1);
tilemap_set(DebugMap, DEBUG_TILE, tx,ty2);
}
// collision data never has flips etc...
var tile1 = tilemap_get(WallMap, tx,ty1 )& tile_index_mask;
var tile2 = tilemap_get(WallMap, tx,ty2 )& tile_index_mask;
if(( tile1!=0 ) || (tile2!=0)) {
x = (x&~(TILE_SIZE-1))+_left; //This looks completely different from the right collision
}
}
if( dir = DIR_DOWN ){
var tx1 = (x+(_right-4))>>TILE_SHIFT; // check right edge
var tx2 = (x-(_left-4))>>TILE_SHIFT; // check right edge
var ty = ((y+_bottom)>>TILE_SHIFT);
if( COLLISION_DEBUG ){
tilemap_set(DebugMap, DEBUG_TILE, tx1,ty);
tilemap_set(DebugMap, DEBUG_TILE, tx2,ty);
}
// collision data never has flips etc...
var tile1 = tilemap_get(WallMap, tx1,ty )& tile_index_mask;
var tile2 = tilemap_get(WallMap, tx2,ty )& tile_index_mask;
if(( tile1!=0 ) || (tile2!=0)) {
y = (ty<<TILE_SHIFT)-(_bottom+1);
}
}
if( dir = DIR_UP ){
var tx1 = (x+(_right-4))>>TILE_SHIFT; // check right edge
var tx2 = (x-(_left-4))>>TILE_SHIFT; // check right edge
var ty = ((y-_top)>>TILE_SHIFT);
if( COLLISION_DEBUG ){
tilemap_set(DebugMap, DEBUG_TILE, tx1,ty);
tilemap_set(DebugMap, DEBUG_TILE, tx2,ty);
}
// collision data never has flips etc...
var tile1 = tilemap_get(WallMap, tx1,ty )& tile_index_mask;
var tile2 = tilemap_get(WallMap, tx2,ty )& tile_index_mask;
if(( tile1!=0 ) || (tile2!=0)) {
y = (ty<<TILE_SHIFT)+TILE_SIZE+_top+1;
}
}
}