My challenge answer

gdt_s03_polishing_the_gui

#1

I’m afraid I did this differently to Yann. I put the logic for the animation inside the GUI script. I think this separates the code well because it keeps all the GUI details in one place.

This is what my GUI script looks like:

extends CanvasLayer

func _ready():
	Global.GUI = self.get_path()

func addLife(livesLeft):
	updateLives(livesLeft)
	$AnimationPlayer.play("LifePulse")

func takeLife(livesLeft):
	updateLives(livesLeft)
	$AnimationPlayer.play("LifeModulateColour")

func updateLives(livesLeft):
	$Banner/Container/LifeCount.text = str(livesLeft)

func updateCoins(coinsCollected):
	$Banner/Container/CoinCount.text = str(coinsCollected)
	$AnimationPlayer.play("CoinPulse")

In GameState I just tell the GUI to either take a life or add a life and the GUI script decides how to make that happen. It could run an animation or play a sound or do whatever.

func hurt():
	livesLeft -= 1
	if livesLeft < 0:
		endGame()
	else:
		get_node(Global.GUI).takeLife(livesLeft)

func addCoin():
	coinsCollected += 1
	get_node(Global.GUI).updateCoins(coinsCollected)
	addLife()

func addLife():
	if coinsCollected % coin_target == 0:
		livesLeft += 1
		get_node(Global.GUI).addLife(livesLeft)

#2

I did the same thing. I don’t think that GameState should know what the GUI animations are named, just what event has been called.