Follower/Pet code refining

W

WolfeSpeider

Guest
So far the game I'm working on has been running well, I would describe the game's style inspired by Castlevania, so basically a 2D platformer. I'm in the midst of implementing a follower system, so the main character will be followed by another object that will attack enemy objects if close enough. So far the code I've used works; the follower object follows the player object via this script:

//Follow Player
ds_queue_enqueue(followQueue, obj_player.x);
ds_queue_enqueue(followQueue, obj_player.y);
lag_steps = 10; // How many steps the follower object lags behind the player object
if (ds_queue_size(followQueue) > lag_steps*2) {
x=ds_queue_dequeue(followQueue)-image_xscale*4;
y=ds_queue_dequeue(followQueue);
}

move(); // Universal collision/movement script


However, when the player turns either left or right/changes direction, instead of the follower smoothly doing the same, the follower object will for some reason slide back away from the player for a split second before teleporting behind the player facing the new direction.

I've been wrestling with this issue for a while now, and I think I've narrowed it down to being an issue with either the lag_steps above, or separate script I have for the follower's idle state:

if (instance_exists(obj_player)) {
image_xscale = sign(obj_player.x - x);
var dis = point_distance(x, y, obj_player.x, obj_player.y) + obj_player.hspd;
} else {
dis = 100;
}
if (dis <= 180) {
{

state = follow_state;
}
}


Additionally, I've been using this code to prevent the follower from appearing directly on top of the player by entering the idle state, but I don't know if it is the cause of the problem:

if (distance_to_object(obj_player) < 32 || distance_to_object(obj_player) <= obj_player.sprite_width / 32) {

state = idle_state
}


I appreciate any help.
 

TheouAegis

Member
Well for starters you're saving the player's x and y but you're not moving to the player's old x and y -- you're moving to the player's old x ±4 based on the current image_xscale, not the image_xscale the player was at.

Code:
ds_queue_enqueue(followQueue, obj_player.x << 1 | (obj_player.image_xscale < 0));
ds_queue_enqueue(followQueue, obj_player.y);
lag_steps = 10; // How many steps the follower object lags behind the player object
if (ds_queue_size(followQueue) > lag_steps*2) {
var n = ds_queue_dequeue(followQueue);
x = (n >> 1) - 4 + 8 * (n & 1);
y=ds_queue_dequeue(followQueue);
}

Try that.
 
W

WolfeSpeider

Guest
I actually managed to shorten a number of things in the main follow script, and it's almost working perfectly, save now the follower object will stop right on top of the player now instead of a few steps behind:

//Follow Player
ds_queue_enqueue(followQueue, obj_player.x);
ds_queue_enqueue(followQueue, obj_player.y);
lag_steps = 10;
if (ds_queue_size(followQueue) > lag_steps*2) {
x=ds_queue_dequeue(followQueue)-image_xscale*4;
y=ds_queue_dequeue(followQueue)-1;

}
if (obj_player.image_xscale = -1) {
image_xscale = -1;
} else if (obj_player.image_xscale = 1) {
image_xscale = 1;
}
if (distance_to_object(obj_player) < 32 || distance_to_object(obj_player) <= obj_player.sprite_width / 32) {
sprite_index = spr_follower_idle;
}

move();

Any way to fix? I noticed by adding a "-40" to the obj_player.x in the first line worked for the right direction, but it won't work when walking left.
 

TheouAegis

Member
I think you just need to make sure you're not saving the player's position if he doesn't move. If he's not moving, you don't want to tell the companion to move to where the player moved to.

If you want to use the ±40, then remember to adjust based on the sign(x-player.x) or whatever.
 
Top