GML Object Trailing

Discussion in 'Programming' started by samspade, May 30, 2018.

  1. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    2,017
    I'm trying to create an object which has other objects following behind it at a set distance along it's exact path. Following an object in its exact path is no problem, but I'm having trouble with the set distance. These are the things I've tried:
    • Put each objects x and y location into a queue and have its follower pull from that queue. This works just fine for following but distance is inconsistent. If the 'head' object moves faster or slower it's various parts bunch up or separate. If 'head' object moves fast enough then there will be a great deal of separation between each following object.

    • Store the movement vector and pass that along. Then have each follower placed at a set distance along that vector. This works, but looks weird. If the 'head' object makes a big loop, the followers will make that same loop but it will be smaller.

    • Create a particle trail. This is the worst of the solutions. Even if you do a fake particle trail and use objecs so you can interact with them, because you are always deleting them it causes a lot of problems.
    Any ideas? I don't need code, unless you want to, I'm just stuck at how to think about it.
     
  2. Jdown79

    Jdown79 Member

    Joined:
    Aug 21, 2016
    Posts:
    69
  3. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    2,017
    This doesn't really work. As written it will just make the worm a straight line pointing away from the direction it's going. I tried a modified version, but it also looks very weird at higher speeds (although it does a better job at lower speeds):

    Code:
    
    //get move coordinates parent
    if (instance_exists(parent)) {
    
        if (ds_queue_size(parent.x_trail_queue) > trail_distance) { 
            ds_queue_enqueue(x_trail_queue, x);                             
            x = ds_queue_dequeue(parent.x_trail_queue);
        }
        if (ds_queue_size(parent.y_trail_queue) > trail_distance) {
            ds_queue_enqueue(y_trail_queue, y);
            y = ds_queue_dequeue(parent.y_trail_queue);
        }
    
        var x_min, x_max, y_min, y_max, angle;
    
        angle = point_direction(parent.x, parent.y, x, y);
    
        x_min = parent.x + lengthdir_x(20, angle);
        y_min = parent.y + lengthdir_y(20, angle);
    
        x_max = parent.x + lengthdir_x(30, angle);
        y_max = parent.y + lengthdir_y(30, angle);
       
        x = clamp(x, x_min, x_max);
        y = clamp(y, y_min, y_max);
    }
    
    
    
    Essentially this moves the part, and after moving the part, clamps it closer. It's still not very good.

    After looking into it a little more it seems like one way to do this would be the physics engine (you could connect the objects with joints and apply forces to the head) but I don't want to turn on physics for one thing. Does anyone know enough of how the physics engine works under the hood that you could point me towards what I would need to learn in order to create a basic joint system?
     
  4. Nocturne

    Nocturne Friendly Tyrant Forum Staff Admin

    Joined:
    Apr 13, 2016
    Posts:
    6,892
    DON'T use physics just for this... it opens a whole other can of worms, and even in the physics system joints can "stretch" and distances can vary depending on how it's set up.

    So, here's what I'd do... Have the "head" instance (the first one created) create the "follow" instances, and in each one set them to follow the previously created instance, something like this:

    Code:
    var front;
    front = id;                                                 // This will hold the previous instance id
    repeat(max_tot)
    {
    parts[tot] = instance_create(x, y, FOLLOW_OBJECT);  // Create follow object
    parts[tot].follow = front;                                  // Tell it who to follow
    front = parts[tot];                                         // Set the follow id to new part for next instance
    tot ++;                                                     // Add one to total followers made
    with (front)
        {
        num = other.tot;                                        // Follower number
        }
    }
    Then in the main object that you want all others to follow, simply have something like this:

    Code:
    with(FOLLOW_OBJECT)
        {
        if instance_exists(follow)
            {
            if point_distance(x, y, follow.x, follow.y) > DIST // DIST here is the maximum distance from each other that you want the instances to be
                {
                direction = point_direction(x, y, follow.x, follow.y)
                x = follow.x - lengthdir_x(DIST, direction)
                y = follow.y - lengthdir_y(DIST, direction)
                }
            }
        }
    I used something very similar to this for my (unfinished :( ) game Ataraxia and as you can see, it works perfectly.

     
    samspade likes this.
  5. samspade

    samspade Member

    Joined:
    Feb 26, 2017
    Posts:
    2,017
    Thanks Nocturne I actually stumbled upon nearly the same solution late last night. Sadly, I didn't see your post before. (Also the game looks cool.) Here's my solution, though it really is pretty much identical just arriving in a slightly different way. (also, I'm typing this from memory so I might have done it slightly wrong, I'll correct it if so)

    Code:
    
    if (instance_exists(parent)) {
        var _target_angle = point_direction(parent.x, parent.y, x, y);
        x = parent.x + lengthdir_x(-dist, _target_angle);
        y = parent.y + lengthdir_y(-dist, _target_angle);
    }
    
    
    It works just fine so long as the head keeps moving (my enemy has very similar movement to your video).

    Edit: I'm also leaving this here for myself as I think this would be another way to do it if for some reason I decide this method doesn't work.

    https://forum.yoyogames.com/index.php?threads/how-to-make-moving-tentacles.8264/#post-58155
     
    Last edited: May 31, 2018

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice