GMLscripts.com

Discuss and collaborate on GML scripts
Invert

You are not logged in.

#1 2021-07-26 12:42:14

maras
Member
Registered: 2021-04-25
Posts: 22
Website

collision_cone

Doesn't work with precision

Expand/// collision_cone(x, y, obj, cone_dir, cone_len, cone_angle, return_arr, force_col_point)
//
// returns array/bool
//
//	x			x from, real
//	y			y from, real
//	obj			object to check, id/object_index
//	cone_dir		facing direction of the cone, real
//	cone_len		length of the sides, real
//	cone_angle		inner cone angle, real
//	return_arr		return all objects inside as an array, otherwise return true/false, bool
//	force_col_point		check x, y coordinates only instead of sprite bboxes, bool
//	
// if the object doesn't have a sprite it checks the x, y coordinates automatically 
//
/// GMLscripts.com/license

function collision_cone(x, y, obj, cone_dir, cone_len, cone_angle, return_arr, force_col_point) {
	
	if !instance_exists(obj) return return_arr ? [] : false;
	var obj_arr = [];
	
	cone_len = max(cone_len, 1);
	cone_angle = clamp(cone_angle, 0.1, 360);
	
	var tri = [];
	var tri_count = 0;
	
	var ab_len = cone_len * 1.425;
	var dir = cone_dir - cone_angle * 0.5;
	
	var next_a = 90;
	var br = false;

	for(var a = 0; a < 360; a += 90) {
		
		if a + next_a >= cone_angle {
			
			next_a = cone_angle - a;
			br = true;
		}
		
		tri[tri_count++] = [
			x + lengthdir_x(ab_len, a + dir),
			y + lengthdir_y(ab_len, a + dir),
			x + lengthdir_x(ab_len, a + dir + next_a),
			y + lengthdir_y(ab_len, a + dir + next_a)
		];
		
		if br break;
	}
	
	// just in case you'd like to see it
	/*draw_circle(x, y, cone_len, true);
	draw_line(x, y, tri[0][0], tri[0][1]);
	draw_line(x, y, tri[tri_count-1][2], tri[tri_count-1][3]);
	draw_set_alpha(0.35);
	draw_arrow(x, y, x+lengthdir_x(cone_len, cone_dir), y+lengthdir_y(cone_len, cone_dir), 20);
	draw_set_alpha(1);*/
	
	with(obj) {
		
		if sprite_index != -1 and !force_col_point {
				
			if rectangle_in_circle(id.bbox_left, id.bbox_top, id.bbox_right, id.bbox_bottom, x, y, cone_len) {
				
				for(var ti = 0; ti < array_length(tri); ti++) {
					
					if rectangle_in_triangle(id.bbox_left, id.bbox_top, id.bbox_right, id.bbox_bottom, 
											 x, y, tri[ti][0], tri[ti][1], tri[ti][2], tri[ti][3]) {
						
						if !return_arr return true;
						else obj_arr[array_length(obj_arr)] = id;
					}
				}
			}
		}
		else {
			
			if point_in_circle(id.x, id.y, x, y, cone_len) {
				
				for(var ti = 0; ti < array_length(tri); ti++) {
					
					if point_in_triangle(id.x, id.y, x, y, tri[ti][0], tri[ti][1], tri[ti][2], tri[ti][3]) {
						
						if !return_arr return true;
						else obj_arr[array_length(obj_arr)] = id;
					}
				}
			}
		}
	}
	
	return return_arr ? obj_arr : false;
}

Works with angles over 180
5IlmU3P.png

Last edited by maras (2021-07-26 18:31:38)

Offline

Board footer

Powered by FluxBB