Created
November 15, 2022 16:40
-
-
Save gnysek/fcb2a35c3ed52a7abb4c2c61f5e026cd to your computer and use it in GitHub Desktop.
mp_potential_step but in pure GML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// based on https://github.com/YoYoGames/GameMaker-HTML5/blob/develop/scripts/functions/Function_MotionPlanning.js#L232 | |
// | |
global.__mp_settings = { | |
maxrot: 30, | |
rotstep: 10, | |
ahead: 3, | |
onspot: true, | |
} | |
// feather ignore GM2017 (name proposal) | |
/// @param {Real} _x | |
/// @param {Real} _y | |
/// @param {Asset.GMObject, Constant.All} _objind | |
/// @param {Bool} _checkall | |
function TestFree(_x, _y, _objind, _checkall) { | |
if ( _objind == all ) { | |
if ( _checkall ) { | |
return place_empty(_x,_y); | |
} else { | |
return place_free(_x, _y); | |
} | |
} else { | |
return (instance_place(_x, _y, _objind) == noone); | |
} | |
} | |
function TryDir(m, _dir, _speed, _objind, _checkall) { | |
var xnew = 0.0; | |
var ynew = 0.0; | |
// see whether angle is acceptable | |
if (DiffDir(_dir, direction) > global.__mp_settings.maxrot) { | |
return false; | |
} | |
// check position a bit ahead | |
xnew = x + _speed * global.__mp_settings.ahead * cos( pi * _dir / 180 ); | |
ynew = y - _speed * global.__mp_settings.ahead * sin( pi * _dir / 180 ); | |
if (true != TestFree(xnew, ynew, _objind, _checkall)) { | |
return false; | |
} | |
//check next position | |
xnew = x + _speed * cos(pi * _dir / 180); | |
ynew = y - _speed * sin(pi * _dir / 180); | |
if (true != TestFree(xnew, ynew, _objind, _checkall)) { | |
return false; | |
} | |
// OK, so set the position | |
direction = _dir; | |
x = xnew; | |
y = ynew; | |
return true; | |
} | |
function DiffDir(_dir1 , _dir2) { | |
var Result = 0.0; | |
while ( _dir1 <= 0.0 ) { _dir1 = _dir1 + 360; } | |
while ( _dir1 >= 360.0 ) { _dir1 = _dir1 - 360; } | |
while ( _dir2 < 0.0 ) { _dir2 = _dir2 + 360; } | |
while ( _dir2 >= 360. ) { _dir2 = _dir2 - 360; } | |
Result = _dir2 - _dir1; | |
if ( Result < 0 ) { Result = -Result; } | |
if ( Result > 180 ) { Result = 360-Result; } | |
return Result; | |
} | |
/// @param {Real} _x | |
/// @param {Real} _y | |
/// @param {Real} _stepsize | |
/// @param {Bool} _checkall | |
function scr_mp_potential_step(_x, _y, _stepsize, _checkall = false) { | |
return scr_mp_potential_step_object(_x, _y, _stepsize, all, _checkall); | |
} | |
/// @param {Real} _x | |
/// @param {Real} _y | |
/// @param {Real} _stepsize | |
/// @param {Asset.GMObject, Constant.All} _objindex | |
/// @param {Bool} _checkall | |
function scr_mp_potential_step_object(_x, _y, _stepsize, _objindex, _checkall = false) { | |
// check whether at the correct position | |
if ((x == _x) && (y == _y)) | |
{ | |
return true; | |
} | |
var dist = 0; | |
var goaldir = 0; | |
var curdir = 0; | |
// check whether close enough for a single step | |
dist = sqrt(sqr(x - _x) + sqr(y - _y)); | |
if (dist <= _stepsize) | |
{ | |
if (TestFree(_x, _y, _objindex, _checkall)) | |
{ | |
direction = point_direction(x, y, _x, _y); | |
x = _x; | |
y = _y; | |
} | |
return true; | |
} | |
// Try directions as much as possible towards the goal | |
goaldir = point_direction(x, y, _x, _y); | |
curdir = 0; | |
while ( curdir < 180 ) | |
{ | |
if (TryDir(TestFree, goaldir - curdir, _stepsize, _objindex, _checkall)) { | |
return false; | |
} | |
if (TryDir(TestFree, goaldir + curdir, _stepsize, _objindex, _checkall)) { | |
return false; | |
} | |
curdir = curdir + global.__mp_settings.rotstep; | |
} | |
// If we did not succeed a local minima was reached | |
// To avoid that the instance gets stuck we rotate on the spot | |
if (global.__mp_settings.onspot) | |
{ | |
direction = direction + global.__mp_settings.maxrot; | |
} | |
return false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment