Bitwise, and value_exists functions

DeScruff

Member
Hey,
So after years of using Game Maker, I only recently found out that GM does have binary functions!
This could significantly clean up and shorten my code. Specially my "Can you walk on this tile" code.
As a quick example instead of:
Code:
var tmpTile
tmpTile = ds_grid_get(grid_Tile, x/16+1, y/16)
if tmpTile == 1 || tmpTile == 3 || tmpTile == 5 || tmpTile == 7 || tmpTile == 9 || tmpTile == 11 || tmpTile == 13 || tmpTile == 15 { // All the tiles the player cant walk on
   CanWalk = false;
} else { CanWalk = true; }
I can have:
Code:
var tmpTile
tmpTile = ds_grid_get(grid_Tile, x/16+1, y/16)
if tmpTile & 1{ // The binary numbers for 1,3,5,7,9,11,13,15 all contain xxx1
   CanWalk = false;
} else { CanWalk = true; }
Much shorter, and cleaner!

But Im wondering, is it possible use Bitwise operations for things like ds_grid_value_exists?
It be much cleaner then running a small loop to check each individual grid square in an area.
If not you guys have any ideas?
 

Hyomoto

Member
As far as I know, no. Because ds_grid_value_exists is looking for a value, not a mask. So basically you say:
Code:
if ds_grid_value_exists(  grid, 0, 0, 1, 1, TILE_SOLID ) == true { //do }
It will only return true if one of those is equal to TILE_SOLID. The only way to perform a masking operation would be to get the value then & it out with the mask:
Code:
if grid[# _x, _y ] & TILE_SOLID > 0 { // do }
Now, you could hypothetically use ds_grid_get_sum if your grid is only a list of solid tiles, and then if the return is > 0 there is a solid tile there, but off the top of my head I can't think of another way to search a region. I will say that at some point you have to do the work, the built-in functions are sometimes faster, but functionally identical to, code you could write yourself. So even in my example there, it's the same as using a for loop to add the values of that region without the benefit of being able to do a masking operation. Hopefully that helps!
 

jo-thijs

Member
I can have:
Code:
var tmpTile
tmpTile = ds_grid_get(grid_Tile, x/16+1, y/16)
if tmpTile & 1{ // The binary numbers for 1,3,5,7,9,11,13,15 all contain xxx1
CanWalk = false;
} else { CanWalk = true; }
Much shorter, and cleaner!
You can further horten it to:
Code:
var tmpTile = ds_grid_get(grid_Tile, x/16+1, y/16);
CanWalk = tmpTile & 1 == 0; // The binary numbers for 1,3,5,7,9,11,13,15 all contain xxx1
For readability and modifiability's sake, I would create a new script "scr_tile_is_walkable" to contain th logic of this expression:
Code:
tmpTile & 1 == 0
Just because it sounds like something you'd use at multiple locations in your project
and adding new tiles in the future may break this logic.

But Im wondering, is it possible use Bitwise operations for things like ds_grid_value_exists?
It be much cleaner then running a small loop to check each individual grid square in an area.
If not you guys have any ideas?
Hyomoto has already replied to this by now.
It's not possible in general by only using ds_grid_value_exists.
However, nothing is keeping you from creating a script for this yourself.
 

DeScruff

Member
As far as I know, no. Because ds_grid_value_exists is looking for a value, not a mask. So basically you say:
Code:
if ds_grid_value_exists(  grid, 0, 0, 1, 1, TILE_SOLID ) == true { //do }
It will only return true if one of those is equal to TILE_SOLID. The only way to perform a masking operation would be to get the value then & it out with the mask:
Code:
if grid[# _x, _y ] & TILE_SOLID > 0 { // do }
Now, you could hypothetically use ds_grid_get_sum if your grid is only a list of solid tiles, and then if the return is > 0 there is a solid tile there, but off the top of my head I can't think of another way to search a region. I will say that at some point you have to do the work, the built-in functions are sometimes faster, but functionally identical to, code you could write yourself. So even in my example there, it's the same as using a for loop to add the values of that region without the benefit of being able to do a masking operation. Hopefully that helps!
Hmm yeah, I guess, I'll probably just have a smple loop that goes something like
Code:
var tmpValue, tmpPass
tmpPass = true;
for (tmpValue = 1; tmpValue <= 15; tmpValue += 2;) {
    if ds_grid_value_exists(  grid,x1,y1,x2,y2,tmpValue) == true {
          tmpPass = false;
          tmpValue = 16;
    }
}
if tmpPass == true { //Do whatever }
or something. Its better then what I had before which was checking every tile individually >_<

You can further horten it to:
Code:
var tmpTile = ds_grid_get(grid_Tile, x/16+1, y/16);
CanWalk = tmpTile & 1 == 0; // The binary numbers for 1,3,5,7,9,11,13,15 all contain xxx1
For readability and modifiability's sake, I would create a new script "scr_tile_is_walkable" to contain th logic of this expression:
Code:
tmpTile & 1 == 0
Just because it sounds like something you'd use at multiple locations in your project
and adding new tiles in the future may break this logic..
Oh yeah, my examples were just that. Simplistic examples. Right now my code is in a script called "Scr_ColDtct" and just returns true or false, since its being used by the Player and NPCs
If I copy/pasted my actual code It would make no sense out of context due to weird variable names (Well... Possibly weird out of context at least) and be something like 60 lines. (Gotta make sure the Charcters aren't walking off the map, or trying to get the value of something outside the ds_grid's boundaries and all that stuff)
 
Last edited:
Top