You are not logged in.
Pages: 1
Xot Made a wonderful Collision normal script found here: https://www.gmlscripts.com/script/collision_normal
Although I would imagine the script could be updated to improve the efficiency.
Some points of note:
I've noticed that the script is calculating points then seeing if they are even in the circle. This area could definitely be improved by doing the calculations algorithmicly. Making sure there is no point in which a point would be outside the circle.
I've also noticed that the script has no precision argument. Most always this argument would be used to simply check the bounding boxes instead of the precise mask, although for this instance I would imagine we could simply check the outer circle instead. Which would save tons of performance.
I've made a quick mock up of what I would imagine this system would look like.
This image actually shows both methods at once, The blue arrow depicts my method, and the purple arrow shows Xot's method. As you can see both arrows are with in 1 degree of each other. Which is precisely what we want. Although an optimization which Xot's version is making use of is only doing the point calculations 1/4 of the time and using those calculations to interpret the other locations to check. Trying this method with my method shows undesirable results.
If we're able to make this a more uniform shape which could be perfectly expanded to the other quadrons then we would have the (ideally) most efficient method.
Here is an example with the precise collision set to false using my method. Comparing with the vanilla collision normal script.
Since the collision is only checking the outer ring, and the resolution is set to 8 I would say this is a huge success. Although could still use a ton of optimization.
Here is the current code for the non-quadron version I've made.
/// scr_draw_circle(x, y, radius, resolution, prec)
// x
// y
// radius
// resolution - how many pixels of the radius to draw
// prec - (false) = outerring check only; (true) = entire circle check
var cx, cy, xx, yy, radius, res, prec, radius_i, degrees, degrees_i, rads, nx, ny;
cx = argument0
cy = argument1
xx = cx
yy = cy
radius = argument2
radius_i = radius
res = argument3
prec = argument4
degrees = 0
nx = 0
ny = 0
if (res > radius*2){
res = radius*2;
show_debug_message("Error: resolution is larger then the circle")
}
if (collision_circle(cx, cy, radius, obj_solid, true, true)) {
while (radius_i > 0)
{
//pi method
degrees_i = (res/((radius_i*2)*pi))*360
degrees_i = 360/round(360/degrees_i)
while (degrees < 360)
{
rads = degtorad(degrees)
xx = cos(rads) * radius_i
yy = sin(rads) * radius_i
if (collision_point(cx+xx,cy+yy,obj_solid,true,false)){
draw_set_color(c_red);
}else{
draw_set_color(c_green);
nx += xx
ny += yy
}
draw_circle(cx+xx,cy+yy,res/2,0)
degrees += degrees_i
}
degrees = 0
radius_i -= res
if (!prec) radius_i = 0;
}
draw_set_color(c_white)
if (nx == 0 && ny == 0) return (-1);
return point_direction(0,0,nx,ny);
}else{
return (-1);
}
Offline
Of course, if you only wanted the option for non precise checking you could simply mix the two scripts, as Xot's script does work quite well. In his demonstration program it takes about 2000 objects before it drops below the desired fps.
After all, just having the option for non-precise checking allows for roughly 2x fps.
Last edited by redeyesmaster (2020-08-18 03:12:04)
Offline
hmm, we may need to make use of circle checks instead of point checks for the precise checking. It seems sub pixels cause issues between sprites.
Last edited by redeyesmaster (2020-08-18 04:34:07)
Offline
I had an amazing idea, why not make use of ds_grid_disk() and mp_grid. through the mp_grid_to_ds_grid(), then we could copy the section, cull that section down to a circle, then find the center of that circle and normal from that. It would require no collision event, and simply setting the precision or mp_grid, where everything else would be handled for us.
Offline
Pages: 1