Why doesn't it work properly when i'm not using print?

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

I have a timer called start_timer that starts incrementing whenever the boolean started becomes true. started turns true when you hit spacebar to start the game. Whenever the timer hits a certain limit the game starts. This is to give time for the sound effect to play, and i also use the timer to determine when to turn the text label on and off, to show a flashing effect (using if start_timer%20 == 0:). I used print to print start_timer when i was testing it, obviously, but when i took the print away it went really fast for some reason? If the game is running at 60 fps, then i expect it to take more than a second for the start timer to reach 90 but it goes by in less than half a second really quickly. And i cant test to see what is happening because when i use print the problem goes away! Anyone have any idea what is going on? Here is the code:

extends Node

var started = false
var labelshowing = true
var start_timer = 0

func _process(delta):
	if Input.is_key_pressed(KEY_SPACE) and started == false:
		$"StartSound".play()
		started = true
		$"MenuText".hide()
	if started == true:
		start_timer += 1
		if start_timer%20 == 0:
			if labelshowing == true:
				$"MenuText".hide()
				labelshowing = false
			elif labelshowing == false:
				$"MenuText".show()
				labelshowing = true
		if start_timer >= 90:
			get_tree().change_scene("res://Main.tscn")
:bust_in_silhouette: Reply From: kidscancode

start_timer % 20 == 0 is going to be true every 20 frames.

Your code is very convoluted - you shouldn’t need triple-nested ifs to accomplish this, and as you are finding, it’s a giant pain to try and troubleshoot.

You could do this in a tiny fraction of the code if you just used a Timer node - that’s what they’re for. Or if all you need is to wait until a sound finishes playing, use the sound’s finished() signal to notify you.

Have you followed any Godot tutorials or read the documentation? You’ll find you make a lot more progress if you work with the engine instead of against it. I highly recommend reading the Step by step section of the official docs, especially the tutorial game, which will demonstrate Godot’s workflow and many common techniques.

The following script would do everything you have above in a fraction of the code:

extends Node

func _input(event):
    if event.is_action_pressed("ui_select") and $MenuText.visible:
        $StartSound.play()
        $MenuText.hide()
    
func _on_StartSound_finished():
    get_tree().change_scene("res://Main.tscn")

Less code is better. You can’t have a bug in code you didn’t write! :wink:

A few other recommendations:

  1. You don’t need to compare boolean values to boolean values because they’re already booleans:
if started:
elif not labelshowing:
  1. You don’t need the quotes around node references: $MenuText.hide()

  2. You don’t need a boolean variable (labelshowing) to track a boolean property ($MenuText.visible)

  3. Prefer input actions over specific keys - it’s more flexible

  4. Checking the Input singleton in _process() polls it every frame. If you only need the pressed event, use _input()

I tried using it whenever the sound ends but i want it to last longer. I had forgotten about the timer node. I completed the Dodge The Creeps tutorial game, but that’s all iv’e done. I’ll probably do more soon, but i just wanted to try making a game myself to practice with the editor and understand it better. The code you have doesn’t make the text turn on and off every 20 frames like i want, rather you just turn the text off. I know that’s going to be true every 20 frames, that’s the point. I’ll see if using a timer node works better.

lincolnpepper | 2018-04-02 16:51

FYI, there are four different Timer nodes used in the “Dodge the Creeps” game.

When I read your question, it wasn’t clear that you wanted the on/off effect. For that you can use a Timer and when its timeout happens, set $MenuText.visible = not $MenuText.visible to toggle it. AnimationPlayer is another possibility. Animations are very powerful, but it does take a little more time to get used to how they work.

kidscancode | 2018-04-02 17:01

Thanks! Works much better with timers. And yeah, i remember them but i forgot to use them when writing this code.

lincolnpepper | 2018-04-02 17:04

:bust_in_silhouette: Reply From: Warlaan

I strongly suggest you use an animation for that. It will be better for the readability and the performance and will be quicker to edit.

I know. I already solved this though. This was a small game where it didn’t matter. Either way the solution that i already learned is simple enough anyway.

lincolnpepper | 2018-04-05 15:00