GML Opinion on my line tile collision function

Discussion in 'Programming' started by zampa, Jun 10, 2019.

  1. zampa

    zampa Member

    Joined:
    Jul 9, 2017
    Posts:
    92
    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
     
  2. YellowAfterlife

    YellowAfterlife ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    2,351
  3. stinger

    stinger Member

    Joined:
    Aug 7, 2016
    Posts:
    10
  4. zampa

    zampa Member

    Joined:
    Jul 9, 2017
    Posts:
    92
    In my first attempt at this I tried to work with the angular coefficient but I do not know how I did get it to work, maybe because gm2 sets the origin of the cartesian plane in the top left, maybe that ****ed with me
     
  5. zampa

    zampa Member

    Joined:
    Jul 9, 2017
    Posts:
    92
    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
     
  6. zampa

    zampa Member

    Joined:
    Jul 9, 2017
    Posts:
    92
  7. Ido-f

    Ido-f Member

    Joined:
    Feb 19, 2018
    Posts:
    111

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice