• Hey! Guest! The 39th GMC Jam will take place between November 26th, 12:00 UTC and November 30th, 12:00 UTC. Why not join in! Click here to find out more!

GML Opinion on my line tile collision function

zampa

Member
So i wanted to create a function that checks for tiles using a line, i came up with this:
Code:
/// @function tile_line_collision(x1,y1,x2,y2,tilemap_id)
/// @description checks for collision with a tilemap using a line
/// @description it returns true if it finds some collision with assigned tilemap else returns false
/// @arg x1 first x position for the line
/// @arg y1 first y position for the line
/// @arg x2 second x position for the line
/// @arg y2 second y position for the line
/// @arg tilemap_id the tilemap id to check for

var x1 = round(argument[0]);
var y1 = round(argument[1]);
var x2 = round(argument[2]);
var y2 = round(argument[3]);
var tilemap_id = argument[4];
var tilemap_size = tilemap_get_tile_width(tilemap_id);
var found_tile = false;
var k = 0;
var reached = false;

var dir = point_direction(x1,y1,x2,y2);

var x_add = cos(degtorad(dir));
var y_add = -sin(degtorad(dir));


while(!reached){
    var x_check = x1 + k*x_add;
    var y_check = y1 + k*y_add;
    if((floor(x_check) mod tilemap_size) == 0 or (floor(y_check) mod tilemap_size) == 0 or k == 0){
        var x_tls = (x_check div tilemap_size) * tilemap_size + tilemap_size / 2;
        var y_tls = (y_check div tilemap_size) * tilemap_size + tilemap_size / 2;
        var ch = tilemap_get_at_pixel(tilemap_id,x_tls,y_tls);
        if(ch != 0){
            found_tile = true;
            break;   
        }
    }
    
    if(round(x_check) == x2 and round(y_check) == y2) reached = true;
    k++;
}

if(found_tile) return true;
else return false;
So my idea was to check for a tile collision only when the x or y value is equal to a multiple of the tile size , because when that is true we know that we have crossed a new cell in the grid and therefore there could be a new tile to check for. (it also works for k == 0 so to check the "starting cell" of the line)

It works but i wanted to know if you think this is a good way to do it and what you would change, one thing that i already thought off was not to increase K by 1 but to calculate how much it would take respectively x_check and y_check too turn into a multiple of the tile size, and then add that instead of 1
 

zampa

Member
I think you should look into line drawing algorithms, maybe Bresenham's
https://en.wikipedia.org/wiki/Line_drawing_algorithm
And another thing i run into while trying this is that if you wanna use the y = mx + q formula you have to code two very different scenario:
m = (y1 - y2)/(x1 - x2)
1) if m exists (x1 != x2)
2) if m does not exist (x1 == x2)

I found that the way i did it was more easy having one case that solves for more situations, but then i could be wrong
 
Top