Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script Submission collision_cone_array #7

Open
tinkerer-red opened this issue Oct 1, 2024 · 2 comments
Open

Script Submission collision_cone_array #7

tinkerer-red opened this issue Oct 1, 2024 · 2 comments

Comments

@tinkerer-red
Copy link
Contributor

Submitting a function, the code is all there to expand this into collision_cone the only note is that if angle is less then 180 both checks need to pass prior to returning the first instance it finds.

Additionally I removed the optional argument array which simulates how collision_*_list functions work, as I found it unneeded in practical use cases. one would simply push the array onto the end of their desired array, and including it only slowed down the function substantially with large object counts.

///   collision_cone_array(x, y, dir, length, angle, object, prec, notme, ordered) {
//  
//  Returns:  - Array
//  
//  x         - The x point of the cone
//  y         - The y point of the cone
//  direction - The direction from x,y the cone expands from
//  length    - The radius (distance in pixels from its center to its edge).
//  angle     - The angle width of the cone
//  obj       - An object, instance, tile map ID, keywords all/other, or array containing these items
//  prec      - Whether the check is based on pixel-perfect collisions (true = slow) or its bounding box in general (false = fast). 
//  notme     - Whether the calling instance, if relevant, should be excluded (true) or not (false). 
//  ordered   - Whether the list should be ordered by distance (true) or not (false).

function collision_cone_array(xx, yy, _dir, _length, _angle, object, prec, notme, ordered=false) {
	//helper function
	static __list_to_arr = function(_list){
		var _array = [];
		var _i = 0, _size = ds_list_size(_list);
		repeat(_size) {
			_array[_i] = _list[| _i ];
		++_i;}
		return _array;
	};
	static _plane_radius = 1_000_000; // this is just used to make a circle so large it will cover any practical use case, with floating point erros should act as a "object on this side of line" check
	
	var _list = ds_list_create();
	collision_circle_list(xx, yy, _length, object, prec, notme, _list, ordered);
	var _arr = __list_to_arr(_list)
	ds_list_clear(_list);
	
	
	if (_angle == 360)
	|| (array_length(_arr) == 0) {
		ds_list_destroy(_list);
		return _arr;
	}
	
	if (_angle <= 180){
		//  Plane Check 1
		var _ang = _dir + _angle/2 -90;
		var _plane_x = xx+lengthdir_x(_plane_radius, _ang);
		var _plane_y = yy+lengthdir_y(_plane_radius, _ang);
		collision_circle_list(_plane_x, _plane_y, _plane_radius, _arr, prec, notme, _list, ordered);
		var _arr = __list_to_arr(_list)
		ds_list_clear(_list);
		
		if (array_length(_arr) != 0) {
			//  Plane Check 2
			var _ang = _dir - _angle/2 +90;
			var _plane_x = xx+lengthdir_x(_plane_radius, _ang);
			var _plane_y = yy+lengthdir_y(_plane_radius, _ang);
			collision_circle_list(_plane_x, _plane_y, _plane_radius, _arr, prec, notme, _list, ordered);
			var _arr = __list_to_arr(_list)
		}
	}
	else{  //  if the angle is larger then 180
		//  Plane Check 1
		var _ang = _dir + _angle/2 -90;
		var _plane_x = xx+lengthdir_x(_plane_radius, _ang);
		var _plane_y = yy+lengthdir_y(_plane_radius, _ang);
		collision_circle_list(_plane_x, _plane_y, _plane_radius, _arr, prec, notme, _list, false);
		
		//  Plane Check 2
		var _ang = _dir - _angle/2 +90;
		var _plane_x = xx+lengthdir_x(_plane_radius, _ang);
		var _plane_y = yy+lengthdir_y(_plane_radius, _ang);
		collision_circle_list(_plane_x, _plane_y, _plane_radius, _arr, prec, notme, _list, false);
		
		var _arr = __list_to_arr(_list)
		ds_list_clear(_list);
		
		array_unique_ext(_arr);
		
		if (ordered) {
			//its faster to just re run a collision check to order these then it is to map an array based on distance
			collision_circle_list(xx, yy, _length, _arr, prec, notme, _list, ordered);
			var _arr = __list_to_arr(_list)
		}
	}
	
	ds_list_destroy(_list);
	return _arr;
}
@tinkerer-red
Copy link
Contributor Author

example of it in use:
https://gyazo.com/508091f2711c833ea9a2b37ebe60ccdf.mp4

@FoxyOfJungle
Copy link
Owner

Hey Red, sorry for the delay. As we discussed on Discord, I'd rather keep the point_in_arc function, which does something similar for now. But I'll leave the issue open in case I change my mind or if someone wants to get the function here. Thanks for the suggestion!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants