Simple turn-based demo, need help on yield function

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By turbostack

Hello,

I am making a simple turn-based movement demo in Godot. It features three sprites that are the default Godot icon. The demo is meant to demonstrate each sprite taking one movement (with a singular press of the right arrow key by the user) before going to the next two sprites to make their movement. Then, the queue would restart from the beginning. The hierarchy of the nodes goes:

Node2D

  • Sprite 1
  • Sprite 2
  • Sprite 3

The parent, Node2D, is meant to manage the turns of each child. The code is below:

extends Node2D

var active_character
var players

func _ready():
	players = get_children()
	active_character = players[0]
	print(active_character)

func play_turn():
	yield(active_character, "end_turn")
	active_character = players[(active_character.get_index() + 1) % get_child_count()]
	print(active_character)

On the start of the game, _ready() gets the list of children, and starts the queue on the first child in the hierarchy of nodes. The print functions are only there for myself to make sure that turns were going properly.

The first child has the following code:

extends Node2D

signal end_turn

var velocity = Vector2(0, 0)
var speed = 200
var TQParent

func _ready():
	TQParent = get_parent()

func _process(delta):
	if Input.is_action_just_pressed("ui_right"):
		TQParent.play_turn()
		velocity.x = 50
		global_position += velocity * speed * delta
		emit_signal("end_turn")

The second and third children have the same code, except the TQParent.play_turn() call is taken out. Functionally, I understand that this does not make sense. However, my output shows me that each subsequent keypress of the right arrow key goes to the next node in the list and restarts after the last one. This is my desired result. Yet, all of the sprites are moving at the same time and not one after the other with each keypress.

I understand this is likely not the best way to structure everything. I have messed around with the placement of TQParent.play_turn() in each script, the placement of the yield() function, etc. Yet, this is the closest I have come to to getting my desired result.

I am still new to Godot, and all help is appreciated. I’ve been dealing with this problem on the turn queue for a while now. I am willing to go to any length necessary to get this fixed. I will be as active on this post and the forum as possible. Thanks so much!

:bust_in_silhouette: Reply From: jgodfrey

The above seems to share some similarities with some of the code and concepts from GDQuest’s excellent turn-based tutorial here:

Based on those similarities, I’m not sure whether you’re aware of the tutorial or not, but I’d recommend you watch it. (It’s only ~13 mins long)…

Thank you for the quick response!

I have looked at this tutorial and modeled my code after it. Yet, I still am not able to obtain the desired result. The main issue I’m having, I think, is how this is implemented into each child node’s movement. The parent script is easy enough to understand. Do you know what might be causing the disconnect in my scripts?

turbostack | 2020-10-20 22:00

:bust_in_silhouette: Reply From: Snafuey

All of your nodes are running the process function 60 times a second. Since you are getting inputs in that function it with execute them. I would suggest a variable as type bool. When your turn manager activates a node call a function that switches the bool to true. Then put an if statement before you get the inputs. Then set the variable back to false just before the turn ends.

That way only the active node will get the inputs.

Hope this helps.