motion_predict

J

Joe Banko

Guest
Ae there any example of code using this function? I'd like to have a projectile, a spear, follow a path generated by motion_predict but don't understand how to move the coordinates into a path. I can even seem to get motion_predict to generate a list. Any help would be greatly appreciated!!
Thanks,
Joe B
 
J

Joe Banko

Guest
Yes sir, that is correct. I have downloaded the motion_predict script and am trying to use it to generate a path for a projectile such as a spear, arrow, launched stone, etc. I'd just like to see some examples of it being used so I know how to read the returned dsid and create a path. I'm pretty sure someone has used it this way and I try to figure things out myself but there is a time when I need assistance. And here I am!
Thanks for the response,

Joe B
 

chamaeleon

Member
Yes sir, that is correct. I have downloaded the motion_predict script and am trying to use it to generate a path for a projectile such as a spear, arrow, launched stone, etc. I'd just like to see some examples of it being used so I know how to read the returned dsid and create a path. I'm pretty sure someone has used it this way and I try to figure things out myself but there is a time when I need assistance. And here I am!
Thanks for the response,

Joe B
Is your problem using the script or generating a path regardless of where the data comes from? As far as the script is concerned, its return value is a trivial ds_list with index 0, 2, 4, ..., holding x positions for each simulated step, and index 1, 3, 5, ..., holding y positions for each simulated step.
 
J

Joe Banko

Guest
The issue I'm having is I'm get a zero value returned, no list, just a zero. I break inside of the script right before the return and there is nothing in it. That's why I'm trying to find more documentation or samples. There are values for x,y,hspeed,vspeed,gravity,gravity_direction and spd. Here is how I'm calling it. I'm calling it in the Draw event of my player instance.

if mouse_check_button(mb_left) {
direction = point_direction(o_player.x, o_player.y, mouse_x, mouse_y );
draw_set_colour(c_lime);
draw_line(o_player.x, o_player.y - 30, mouse_x, mouse_y );
}
//are we in firing mode
if mouse_check_button_released(mb_left){
var tra_list = ds_list_create();
spd = 1;
hspeed = 1;
vspeed = -.5;
gravity = .12;
gravity_direction = 270;

tra_list = motion_predict(o_stone,5);
var pos_x, pos_y;

}


Here is the script as it is in my game:
/// motion_predict(instance,steps)
//
// Returns a list data structure populated with the predicted
// positions {x1,y1, x2,y2, ... , xsteps,ysteps} of an instance
// with regard to its current motion, friction, and gravity.
//
// instance instance id, real
// steps number of steps to look ahead, real
//
/// GMLscripts.com/license
{
var instance,steps,dsid,posx,posy,hspd,vspd,grvx,grvy,spd,dir;
instance = argument0;
steps = argument1;
dsid = ds_list_create();
with (instance) {
posx = x;
posy = y;
hspd = hspeed;
vspd = vspeed;
grvx = lengthdir_x(gravity,gravity_direction);
grvy = lengthdir_y(gravity,gravity_direction);
repeat (steps) {
spd = point_distance(0,0,hspd,vspd);
spd = max(0, spd-friction)/spd;
hspd *= spd;
vspd *= spd;
hspd += grvx;
vspd += grvy;
posx += hspd;
posy += vspd;
ds_list_add(dsid,posx);
ds_list_add(dsid,posy);
}
}
var bogus = 1;
return dsid;
}

the var bogus line is just so I can put a breakpoint in before the return.

Thanks,

Joe B
 

Roldy

Member
The issue I'm having is I'm get a zero value returned, no list, just a zero.
That is right.

dsid is just an ID and zero is a good ID. Otherwise a bad id is <undefined>.

you need to use the ds_list functions to explore the list: https://docs.yoyogames.com/source/dadiospice/002_reference/data structures/ds lists/

or use accessors: https://docs.yoyogames.com/source/dadiospice/002_reference/001_gml language overview/accessors.html

Consider using ds_list_size to check the size of your list.
 
Last edited:

chamaeleon

Member
The issue I'm having is I'm get a zero value returned, no list, just a zero.
As @Roldy says, that is a valid (and more than likely entirely correct) ds_list id. The debugger will allow you to switch the view of a variable to be a ds_list instead of the the number GMS uses for reference. See the debugger documentation, in the Data Types section for more information about this aspect. You should be able to use all ds_list functions and the ds_list accessor as needed on the id returned.
 
Also, since you are creating the list INSIDE the script, you do not need to create it outside (as in, you don't need the line "var tra_list = ds_list_create();" ). You're outputting the ID of an already created list from the script so catching that with tra_list (as you are already doing) is all you need.
 

chamaeleon

Member
Also, since you are creating the list INSIDE the script, you do not need to create it outside (as in, you don't need the line "var tra_list = ds_list_create();" ). You're outputting the ID of an already created list from the script so catching that with tra_list (as you are already doing) is all you need.
Good catch, this is of course creating a memory leak of ds_lists that will never be freed.
 
J

Joe Banko

Guest
Thanks for all the responses, links and info about creating a memory leak! I also commented out "var tra_list = ds_list_create();" and changed the call to "tra_list = motion_predict(o_stone,12);" changing the steps to an even number. I have a breakpoint in the motion predict script right before the return so the entire script has run, changing the dsid "view as type to ds_list", I get under value in the dsid line:
0 [ds_list(size=0)]
<empty structure>
Checking tra_list I see the same thing.
Anything else that might cause this result?

Thanks,

Joe B
 
You need to make dsid a local variable, instead of an instance variable. Since you are returning the list ID anyway, it doesn't matter that you'll lose that particular reference to the list once the script ends:
Code:
var dsid = ds_list_create();
The reason it's not adding anything is that you are trying to add to the list inside of the with() statement. That means it's looking for a variable called dsid inside of the "instance" instance, and seeing as you very probably do not have a variable called dsid inside of the "instance" instance (since you are actually making that variable in the script, which is presumably not being run by "instance") it is probably failing silently (or maybe not, look at the output tab, I'm not sure how GMS would handle this).

By assigning the ds_list to a local variable, you make it accessible inside of the with() statement, allowing you to add to dsid without any problems.
 

Roldy

Member
Thanks for all the responses, links and info about creating a memory leak! I also commented out "var tra_list = ds_list_create();" and changed the call to "tra_list = motion_predict(o_stone,12);" changing the steps to an even number. I have a breakpoint in the motion predict script right before the return so the entire script has run, changing the dsid "view as type to ds_list", I get under value in the dsid line:
0 [ds_list(size=0)]
<empty structure>
Checking tra_list I see the same thing.
Anything else that might cause this result?

Thanks,

Joe B

Post your code. It makes it easier for people to help you. Use code blocks in this forum so the code is readable. When posting in this forum, the button on the toolbar for code blocks looks like </>
 
J

Joe Banko

Guest
Okey dokey. Here's the code as it exists in the player Draw event. When the mouse button goes down a green line is drawn from the player sprite to whereever the mouse is. When the mouse button goes up I want to generate a path to add a little realism (that code is not in yet because I can't get a list back from motion_predict. I copied and pasted exactly what was in motion_predict which is shown under the player code.

GML:
//in player Draw event
if mouse_check_button(mb_left) {
    direction = point_direction(o_player.x, o_player.y, mouse_x, mouse_y );
        draw_set_colour(c_lime);
        draw_line(o_player.x, o_player.y - 30, mouse_x, mouse_y );
}
    //are we in firing mode           
if mouse_check_button_released(mb_left){
            spd = 1;
            hspeed = 1;
            vspeed = -.5;
            gravity = .12;
            gravity_direction = 270;

        tra_list = motion_predict(o_stone,12);
        var bogus = 1;//for debugging

//MOTION_PREDICT script
    /// motion_predict(instance,steps)
    //
    //  Returns a list data structure populated with the predicted 
    //  positions {x1,y1, x2,y2, ... , xsteps,ysteps} of an instance
    //  with regard to its current motion, friction, and gravity.
    //
    //      instance    instance id, real
    //      steps       number of steps to look ahead, real
    //
    /// GMLscripts.com/license
    {
        var instance,steps,dsid,posx,posy,hspd,vspd,grvx,grvy,spd,dir;
        instance = argument0;
        steps = argument1;
        dsid = ds_list_create();
        with (instance) {
            posx = x;
            posy = y;
            hspd = hspeed;
            vspd = vspeed;
            grvx = lengthdir_x(gravity,gravity_direction);
            grvy = lengthdir_y(gravity,gravity_direction);
            repeat (steps) {
                spd = point_distance(0,0,hspd,vspd);
                spd = max(0, spd-friction)/spd;
                hspd *= spd;
                vspd *= spd;
                hspd += grvx;
                vspd += grvy;
                posx += hspd;
                posy += vspd;
                ds_list_add(dsid,posx);
                ds_list_add(dsid,posy);
            }
        }
return dsid;
    }
        
}
/
 

chamaeleon

Member
Okey dokey. Here's the code as it exists in the player Draw event. When the mouse button goes down a green line is drawn from the player sprite to whereever the mouse is. When the mouse button goes up I want to generate a path to add a little realism (that code is not in yet because I can't get a list back from motion_predict. I copied and pasted exactly what was in motion_predict which is shown under the player code.

GML:
//in player Draw event
if mouse_check_button(mb_left) {
    direction = point_direction(o_player.x, o_player.y, mouse_x, mouse_y );
        draw_set_colour(c_lime);
        draw_line(o_player.x, o_player.y - 30, mouse_x, mouse_y );
}
    //are we in firing mode          
if mouse_check_button_released(mb_left){
            spd = 1;
            hspeed = 1;
            vspeed = -.5;
            gravity = .12;
            gravity_direction = 270;

        tra_list = motion_predict(o_stone,12);
        var bogus = 1;//for debugging

//MOTION_PREDICT script
    /// motion_predict(instance,steps)
    //
    //  Returns a list data structure populated with the predicted
    //  positions {x1,y1, x2,y2, ... , xsteps,ysteps} of an instance
    //  with regard to its current motion, friction, and gravity.
    //
    //      instance    instance id, real
    //      steps       number of steps to look ahead, real
    //
    /// GMLscripts.com/license
    {
        var instance,steps,dsid,posx,posy,hspd,vspd,grvx,grvy,spd,dir;
        instance = argument0;
        steps = argument1;
        dsid = ds_list_create();
        with (instance) {
            posx = x;
            posy = y;
            hspd = hspeed;
            vspd = vspeed;
            grvx = lengthdir_x(gravity,gravity_direction);
            grvy = lengthdir_y(gravity,gravity_direction);
            repeat (steps) {
                spd = point_distance(0,0,hspd,vspd);
                spd = max(0, spd-friction)/spd;
                hspd *= spd;
                vspd *= spd;
                hspd += grvx;
                vspd += grvy;
                posx += hspd;
                posy += vspd;
                ds_list_add(dsid,posx);
                ds_list_add(dsid,posy);
            }
        }
return dsid;
    }
       
}
/
Is o_stone an instance? If not, that's presumably your problem in not getting data back. The script expect an instance, not an object.
 
J

Joe Banko

Guest
Yup, you nailed it, but now the list contains NaN which I assume?? means not a number.
joeb
 
J

Joe Banko

Guest
It does now. Maybe I should just have you write my code I feel like such a moron.....
Thanks,

joeb
 

chamaeleon

Member
It does now. Maybe I should just have you write my code I feel like such a moron.....
Thanks,
joeb
If you don't actually want it to have a speed at the moment of calling the script, but you know what speed it will have at some point in the future when it is supposed to start moving, you can always modify the script to take a parameter for speed as well, and use lengthdir_x() and lengthdir_y() to calculate hspd and vspd instead of using hspeed and vspeed, respectively, in conjunction with the the direction instance variable (assuming it has been set at least, or hspeed and vspeed wouldn't be correct).
 
J

Joe Banko

Guest
A lot of tweaking I see to get the sort of curves I want. Of course once I get the array stuff working I'll be reading the values from the projectile list (other post of mine you're watching). My main background is database architecture, data warehousing and SQL so GMS2 stuff is a little vague right now but as you said, I just need to do more coding AND reading! I'm very appreciative of all the help I'm getting here on the forum unlike some of the other IT forums I used to frequent. Think I'll just bang around some more right now getting a path out of the list which is where I was really going in the first place.

joeb
 

Alexx

Member
Here is an example that uses the script: <LINK BROKEN> Removed by moderator
It's a very basic game based on an old classic. I added a bit to make the projectile alter target based on wind speed, but should be enough there to see how you can get the predicted positions to draw a path-like structure.
 
Last edited by a moderator:
J

Joe Banko

Guest
OK, I'm seriously confused. Where is the file? I bought the book, got charged for it and like tanktrax I'm unable to download it.
 

Alexx

Member
Here is the zip link: <LINK BROKEN> Removed by moderator
 
Last edited by a moderator:
J

Joe Banko

Guest
I modified the motion_predict script to build a path instead of a ds_list:
GML:
    /// motion_predict(instance,steps)
    //
    //  Returns a list data structure populated with the predicted ***JB change to a path instead of ds_list
    //  positions {x1,y1, x2,y2, ... , xsteps,ysteps} of an instance
    //  with regard to its current motion, friction, and gravity.
    //
    //      instance    instance id, real
    //      steps       number of steps to look ahead, real
    //
    /// GMLscripts.com/license
 {
        var instance,steps,dsid,posx,posy,hspd,vspd,grvx,grvy,spd,dir,bogus;
        instance = argument0;
        steps = argument1;
        p_path = path_add();
        with (instance) {
            posx = x;
            posy = y;
            hspd = hspeed;
            vspd = vspeed;
            grvx = lengthdir_x(gravity,gravity_direction);
            grvy = lengthdir_y(gravity,gravity_direction);
            repeat (steps) {
                spd = point_distance(0,0,hspd,vspd);
                spd = max(0, spd-friction)/spd;
                hspd *= spd;
                vspd *= spd;
                hspd += grvx;
                vspd += grvy;
                posx += hspd;
                posy += vspd;
                path_add_point(p_path,posx, posy, 500);
                bogus = 1;//debug point
            }
        }

        return p_path;
    }
But I get a pretty much straight line so I'm doing something wrong. I figured it would be easier just making the path inside the script rather than generating the path from the ds_list.

Just an FYI

joeb
 

chamaeleon

Member
I modified the motion_predict script to build a path instead of a ds_list:
GML:
    /// motion_predict(instance,steps)
    //
    //  Returns a list data structure populated with the predicted ***JB change to a path instead of ds_list
    //  positions {x1,y1, x2,y2, ... , xsteps,ysteps} of an instance
    //  with regard to its current motion, friction, and gravity.
    //
    //      instance    instance id, real
    //      steps       number of steps to look ahead, real
    //
    /// GMLscripts.com/license
{
        var instance,steps,dsid,posx,posy,hspd,vspd,grvx,grvy,spd,dir,bogus;
        instance = argument0;
        steps = argument1;
        p_path = path_add();
        with (instance) {
            posx = x;
            posy = y;
            hspd = hspeed;
            vspd = vspeed;
            grvx = lengthdir_x(gravity,gravity_direction);
            grvy = lengthdir_y(gravity,gravity_direction);
            repeat (steps) {
                spd = point_distance(0,0,hspd,vspd);
                spd = max(0, spd-friction)/spd;
                hspd *= spd;
                vspd *= spd;
                hspd += grvx;
                vspd += grvy;
                posx += hspd;
                posy += vspd;
                path_add_point(p_path,posx, posy, 500);
                bogus = 1;//debug point
            }
        }

        return p_path;
    }
But I get a pretty much straight line so I'm doing something wrong. I figured it would be easier just making the path inside the script rather than generating the path from the ds_list.

Just an FYI

joeb
The script does rely on the gravity variable. If gravity is set to 0, it will not influence the trajectory at all and you get a straight line, which sounds like it would match your current observation.
 
Top