Advertisement
RefresherTowel

GameMaker - Tile Raycast

Oct 30th, 2022
2,238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ///***** Cloned from badwrong: https://pastebin.com/52zTNYMJ ******
  2.  
  3. #macro TILE_SIZE 16
  4. #macro TILE_SIZE_M1 15
  5. #macro TILE_RANGE 50
  6. #macro NO_COLLISION -4
  7.  
  8. // _map is the tilemap id
  9.  
  10. function tile_raycast(_x, _y, _rx, _ry, _map)
  11. {  
  12.     // Casts a ray to test for tile collision and returns true or false if found
  13.    
  14.     _rx -= _x;
  15.     _ry -= _y;
  16.    
  17.     var _dot0 = _rx * _rx + _ry * _ry,
  18.         _dist = sqrt(_dot0) + 0.00001; // safe normalize
  19.  
  20.     _rx /= _dist;
  21.     _ry /= _dist;
  22.    
  23.     var _x_length = _ry/_rx,
  24.         _y_length = _rx/_ry,
  25.         _x_dist = sqrt(1 + _x_length * _x_length),
  26.         _y_dist = sqrt(1 + _y_length * _y_length),
  27.         _x_map  = _x div TILE_SIZE,
  28.         _y_map  = _y div TILE_SIZE,
  29.         _x_step = sign(_rx),
  30.         _y_step = sign(_ry);
  31.    
  32.     if (_rx < 0) _x_length = (_x - (_x &~ TILE_SIZE_M1)) / TILE_SIZE * _x_dist;
  33.     else  _x_length = ((_x &~ TILE_SIZE_M1) + TILE_SIZE - _x) / TILE_SIZE *_x_dist;
  34.    
  35.     if (_ry < 0) _y_length = (_y - (_y &~ TILE_SIZE_M1)) / TILE_SIZE * _y_dist;
  36.     else _y_length = ((_y &~ TILE_SIZE_M1) + TILE_SIZE - _y) / TILE_SIZE *_y_dist;
  37.        
  38.     for (var _d = 0; _d < TILE_RANGE; _d++)
  39.     {
  40.         if (_x_length < _y_length)
  41.         {
  42.             _x_map += _x_step;
  43.             if (tilemap_get(_map, _x_map, _y_map) & tile_index_mask == TILE_SOLID)
  44.             {
  45.                 _dist = _x_length * TILE_SIZE;
  46.                 _rx *= _dist;
  47.                 _ry *= _dist;
  48.                 if ((_rx * _rx + _ry * _ry) > _dot0) return false;
  49.                 else return true;
  50.             }
  51.             _x_length += _x_dist;  
  52.         }
  53.         else
  54.         {
  55.             _y_map += _y_step;
  56.             if (tilemap_get(_map, _x_map, _y_map) & tile_index_mask == TILE_SOLID)
  57.             {
  58.                 _dist = _y_length * TILE_SIZE;
  59.                 _rx *= _dist;
  60.                 _ry *= _dist;
  61.                 if ((_rx * _rx + _ry * _ry) > _dot0) return false;
  62.                 else return true;
  63.             }
  64.             _y_length += _y_dist;
  65.         }  
  66.     }
  67.     return false;
  68. }
  69.  
  70. function tile_raycast_point(_x, _y, _rx, _ry, _map)
  71. {  
  72.     // Casts a ray to (_rx, _ry) and tests for tile collision
  73.     // Returns a point (x, y) if found or NO_COLLISION
  74.    
  75.     _rx -= _x;
  76.     _ry -= _y;
  77.    
  78.     var _dot0 = _rx * _rx + _ry * _ry,
  79.         _dist = sqrt(_dot0) + 0.00001; // safe normalize
  80.  
  81.     _rx /= _dist;
  82.     _ry /= _dist;
  83.    
  84.     var _x_length = _ry/_rx,
  85.         _y_length = _rx/_ry,
  86.         _x_dist = sqrt(1 + _x_length * _x_length),
  87.         _y_dist = sqrt(1 + _y_length * _y_length),
  88.         _x_map  = _x div TILE_SIZE,
  89.         _y_map  = _y div TILE_SIZE,
  90.         _x_step = sign(_rx),
  91.         _y_step = sign(_ry);
  92.    
  93.     if (_rx < 0) _x_length = (_x - (_x &~ TILE_SIZE_M1)) / TILE_SIZE * _x_dist;
  94.     else  _x_length = ((_x &~ TILE_SIZE_M1) + TILE_SIZE - _x) / TILE_SIZE *_x_dist;
  95.    
  96.     if (_ry < 0) _y_length = (_y - (_y &~ TILE_SIZE_M1)) / TILE_SIZE * _y_dist;
  97.     else _y_length = ((_y &~ TILE_SIZE_M1) + TILE_SIZE - _y) / TILE_SIZE *_y_dist;
  98.        
  99.     for (var _d = 0; _d < TILE_RANGE; _d++)
  100.     {
  101.         if (_x_length < _y_length)
  102.         {
  103.             _x_map += _x_step;
  104.             if (tilemap_get(_map, _x_map, _y_map) & tile_index_mask == TILE_SOLID)
  105.             {
  106.                 _dist = _x_length * TILE_SIZE;
  107.                 _rx *= _dist;
  108.                 _ry *= _dist;
  109.                 if ((_rx * _rx + _ry * _ry) > _dot0) return NO_COLLISION;
  110.                 else return { x : _x + _rx, y : _y + _ry }
  111.             }
  112.             _x_length += _x_dist;  
  113.         }
  114.         else
  115.         {
  116.             _y_map += _y_step;
  117.             if (tilemap_get(_map, _x_map, _y_map) & tile_index_mask == TILE_SOLID)
  118.             {
  119.                 _dist = _y_length * TILE_SIZE;
  120.                 _rx *= _dist;
  121.                 _ry *= _dist;
  122.                 if ((_rx * _rx + _ry * _ry) > _dot0) return NO_COLLISION;
  123.                 else return { x : _x + _rx, y : _y + _ry }
  124.             }
  125.             _y_length += _y_dist;
  126.         }  
  127.     }
  128.     return NO_COLLISION;
  129. }
  130.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement