|
|
|
 |
Reply From: |
jahu00 |
I’ve been trying to make a multiplayer game recently and one problem with this kind of games is recreating smooth movement on multiple instances of the game. The best way I found so far (result wise) was to make a movement history for each synchronized entity (in my game monsters and players).
How does this relate to your problem? Well, you are trying to recreate the movement of your controlled character with the rest of the party (if I remember correctly from Earthbound). In my multiplayer game I’m constantly updating this movement history (maybe a little foolishly), but in your case, this history would only need updating when your character is moving (and then send past positions to other characters in the party). If your game has smooth framerate, you can skip interpolating those past positions.
You could place something like this, in your party leader’s node (there might be some errors, I’ve been mostly playing with Godot 4 lately).
extends Node2D
var position_history = []
var max_history_length = 20
signal history_updated
func _physics_process():
var character_moved = false
#move your character here and set character_moved if it did
if (character_moved):
add_position_to_history()
emit_signal("history_updated", position_history)
func add_position_to_history():
var past_position = {"x": position.x, "y": position.y}
position_history.append(past_position)
if (position_history.size() > max_history_length):
position_history.pop_front()
Other party members would connect to the history_updated signal and try to set their position to certain index in the history array.
extends Node2D
var party_leader
var tracking_index = 10
# pass party_leader node and delay in physics "frames"
func follow(party_leader, tracking_index):
self.party_leader = party_leader
self.tracking_index = tracking_index
party_leader.connect("history_updated", self, "on_leader_history_updated")
func on_leader_history_updated(position_history):
if (position_history.size() < tracking_index + 1):
return
past_position = position_history[tracking_index]
position = Vector2(past_position["x"], past_position["y"])
You might add extra information besides the position to the past position object (and use a resource or a node for that instead of a dictionary). If you need interpolation, you will need more information besides the position, like speed or delta in there. I used a dictionary, because I don’t remember if Vector2
can be simply passed using signals or not (maybe I’m confusing multiplayer limitations with signal
ones). If Vector2
can be passed, make a copy of the position using var past_position = Vector2(position)
.
Thanks, but I don’t know in which part I should put these codes
MegamanXfangamer | 2023-04-01 18:07
This is just an example of how you could achieve this effect (you may need to change some things in my code for your game), but the first part goes into the script of your main character. The second goes into the script of the character that is following. Additionally if you have a scene that contains both characters, you would have to call the follow
function from inside the script from that scene. For example:
func _ready():
var leader = get_node("Leader")
var follower = get_node("Follower")
#10 is the number of "frames" that the follower lags behind the leader
follower.follow(leader, 10)
jahu00 | 2023-04-01 21:09