Skip to content

Instantly share code, notes, and snippets.

@4an70m
Last active November 26, 2023 00:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 4an70m/e32f36144bb436ca4a206c3366f7a173 to your computer and use it in GitHub Desktop.
Save 4an70m/e32f36144bb436ca4a206c3366f7a173 to your computer and use it in GitHub Desktop.
collision_line_point
// https://yal.cc/gamemaker-collision-line-point/
/**
@desc collision_line_point checks along a line from point x1,y1 to point x2,y2 for a collision with any instance of the object or tile map specified by the argument "obj".
@param {real} x1 The x coordinate of the start of the line.
@param {real} y1 The y coordinate of the start of the line.
@param {real} x2 The x coordinate of the end of the line.
@param {real} y2 The y coordinate of the end of the line.
@param {Object Asset or Object Instance or Tile Map Element ID or Array} An object, instance, tile map ID, keywords all/other, or array containing these items
@param {bool} prec Whether the check is based on precise collisions (true, which is slower) or its bounding box in general (false, faster).
@param {bool} notme Whether the calling instance, if relevant, should be excluded (true) or not (false).
@returns {struct} The resulting structure of {colliding object id, collision x, collision y}
*/
function collision_line_point(x1, y1, x2, y2, obj, prec, notme) {
// throw an initial collision line
var _collision_isntance = collision_line(x1, y1, x2, y2, obj, prec, notme);
var _x_collision = x2;
var _y_collision = y2;
// if the initial collision line intersects with something
if (_collision_isntance != noone) {
// if there's a collision, lets go from the start to the end of the line to find the first colliding object
var _segment_start = 0;
var _segment_end = 1;
// repeate the next block log2(distance between start and end points) + 1 times
repeat (ceil(log2(point_distance(x1, y1, x2, y2))) + 1) {
var _next_segment = _segment_start + (_segment_end - _segment_start) * 0.5;
var _next_x = x1 + (x2 - x1) * _next_segment;
var _next_y = y1 + (y2 - y1) * _next_segment;
var _previous_x = x1 + (x2 - x1) * _segment_start;
var _previous_y = y1 + (y2 - y1) * _segment_start;
// throw a new collision line from the updated coordinates
var _new_collision_check_instance = collision_line(_previous_x, _previous_y, _next_x, _next_y, obj, prec, notme);
if (_new_collision_check_instance != noone) {
_collision_isntance = _new_collision_check_instance;
_x_collision = _next_x;
_y_collision = _next_y;
_segment_end = _next_segment;
} else {
_segment_start = _next_segment;
}
}
}
return {
collision_id: _collision_isntance,
x: _x_collision,
y: _y_collision
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment