Godot Version
4.2.2
Question
So, I am very new to programming in general, but for the past couple of days I have been trying to make some games in godot.
I followed this tutorial https://www.youtube.com/watch?v=LOhfqjmasi0 by Brackeys, but I have since tried remaking the whole thing without looking at the tutorial and instead using the breadcrums of knowledge that I remember to force my brain to learn some of the concepts and allow me to fully understand the why behind each line of code. Also so that I could experiment and try different things.
On the subject of that last point, I got to the point where I was doing a sound effect for picking up a coin and wanted to see if I could do it differently to how he does it in the video, but was struggling because obviously as soon as queue_free() happens the coin disappears and the sound effect isnt played. I thought if I just put it in like this:
@onready var coin_sound= $coin_sound
func _on_body_entered(body):
if body.name == "player":
coin_sound.play()
queue_free()
That it should work because it would play the sound and then make the coin disappear, but obviously its doing it so fast that the coin still disappears before the sound can play. I still want the coin to vanish the moment the player touches it, so I thought I could tie the sound to the player, so that when it entered the body of the coin the sound would technically come from the player but it would seem right hopefully and then tried this:
@onready var coin_sound= $coin_sound
const COIN = preload("res://Scenes/coin.tscn")
func _on_area_2d_body_entered(body):
if body.name == COIN:
coin_sound.play()
I created an area2d node in the scene for the player and gave it a collision shape 2d and connected the _on_area_2d_body_entered function and the sound effect etc, and ctrl+click and dragged the scene for the coin in to create that constant, however when I run the game it just immediately crashes. Which is whatever since it seemed like a messy way of doing things.
Finally I found this post Playing Sound FX where the solution is from someone called FencerDevLog, and the solution was this:
In our game, I use a solution that relies on a global autoload class called
SoundManager, where I keep all sound effects in one place. It can be called
from anywhere, and the sound will always play in full regardless of the
existence of the corresponding game object.
extends Node
@onready var pickup_coin = $PickupCoin
@onready var toilet_flush = $ToiletFlush
# more sounds to add here
func play_sound(key):
var sound = get(key)
if sound is AudioStreamPlayer:
sound.play()
else:
print("Sound " + key + " not found!")
Then you can use this from anywhere:
SoundManager.play_sound("pickup_coin")
And, of course, don’t forget to add SoundManager to Project Settings >
Autoload.
However when I tried this, it just says that “Identifier “SoundManager” not declared in the current scope” and I dont know what else to do. I tried making sure that the sound manager is in the main game scene and when that didnt work I tried putting the sound manager into the scene with the coin, but then it just said the same thing, but for the sound instead.
I assume its because I have to create it in a different way to how I think, but I cant for the life of me figure it out, even when reading through some of the documentation on singletons/autoload.
Sorry this has been a very long post, but is there any way of doing it other than what is in that tutorial?
edit*
I think I figured it out, not the best but I did this:
extends Area2D
@onready var coin_sound = $coin_sound
@onready var animated_sprite = $AnimatedSprite2D
@onready var collision_shape = $CollisionShape2D
func _on_body_entered(body):
if body.name == "player2":
animated_sprite.visible = false
coin_sound.play()
collision_shape.queue_free()
await coin_sound.finished
queue_free()
Technically the coin is still there so the sound plays, but the collision shape disappears so you cant interact with it multiple times. Finally after all of that is done, it finally gets rid of the coin.