Search code examples
game-developmentgodotgodot4

Godot INPUT Shift + "Key" Only playing "Key"


I am working in godot and this is my first project i decided on making a piano game like on those virtual piano games where you can play on your keyboard and i have everything working except when i want to play the black note its shift + the white note which its parent from so for example i have c2 as 1 and i want to play c#2 its should be shift + 1 but instead it plays c2 (edit - now when i hold shift it plays nothing)

extends Node

# Define the note keymap for left and right hands
var left_hand = ['Z', 'S', 'X', 'D', 'C', 'V', 'G', 'B', 'H', 'N', 'J', 'M']
var right_hand = ['R', '5', 'T', '6', 'Y', 'U', '8', 'I', '9', 'O', '0', 'P']

# Define the piano notes
var piano_notes = ['C2', 'D2', 'E2', 'F2', 'G2','A2', 'B2', 'C3', 'D3', 'E3', 'F3', 'G3','A3', 'B3', 'C4', 
                   'D4', 'E4', 'F4', 'G4','A4', 'B4', 'C5', 'D5', 'E5', 'F5', 'G5','A5', 'B5', 'C6', 'D6', 'E6', 'F6', 'F6#', 'G6', 'G6#',
                   'A6', 'B6', 'C7']

# Define white and black notes separately
var white_notes = ['C2', 'D2', 'E2', 'F2', 'G2',
                   'A2', 'B2', 'C3', 'D3', 'E3', 'F3', 'G3',
                   'A3', 'B3', 'C4', 'D4', 'E4', 'F4', 'G4',
                   'A4', 'B4', 'C5', 'D5', 'E5', 'F5', 'G5',
                   'A5', 'B5', 'C6', 'D6', 'E6', 'F6', 'G6',
                   'A6', 'B6', 'C7']

var black_notes = ['C#2', 'D#2', 'F#2', 'G#2',
                   'A#2', 'C#3', 'D#3', 'F#3', 'G#3',
                   'A#3', 'C#4', 'D#4', 'F#4', 'G#4',
                   'A#4', 'C#5', 'D#5', 'F#5', 'G#5',
                   'A#5', 'C#6', 'D#6', 'F#6', 'G#6',
                   'A#6', 'C#7']

# Combine white and black notes
var all_notes = white_notes + black_notes

# Dictionary to keep track of whether a key is pressed
var key_pressed = {}

func _ready():  
    # Initialize key_pressed dictionary
    for note in all_notes:
        key_pressed[note] = false
        # Connect input event
    set_process_input(true)

func _process(delta):
    # Check if a keybind is pressed for each white note
    for note in white_notes:
        var action = "play_note_" + note
        if Input.is_action_pressed(action) and !key_pressed[note] and !Input.is_key_pressed(KEY_SHIFT):
            play_note(note)
            key_pressed[note] = true
        elif !Input.is_action_pressed(action) and key_pressed[note]:
            key_pressed[note] = false
    #Now checking black notes:
    for note in black_notes:
        var action = "play_note_" + note
        if Input.is_action_pressed(action) and !key_pressed[note]:
            play_note(note)
            key_pressed[note] = true
        elif !Input.is_action_pressed(action) and key_pressed[note]:
            key_pressed[note] = false

func play_note(note):
    # Load the audio file
    var audio_stream = load("res://notes/" + note + ".wav")
    if audio_stream:
        # Create an AudioStreamPlayer node
        var audio_player = AudioStreamPlayer.new()
        # Assign the audio stream to the player
        audio_player.stream = audio_stream
        # Add the player to the scene
        add_child(audio_player)
        # Play the audio
        audio_player.play()

I went and added comments to all of the code for you guys (or at least ask chat gpt to explain everything and add comments)

I tried to add a Boolean variable that checked if shift is pressed then plays the input name + "#" + note but that made a double hash tag

what the f


Solution

  • You configure actions in project settings, the idea that you would have actions with abstract names such as "jump" that are mapped to some hardware input by default. This allows you to let the player configure to a different input (for example a different keyboard or gamepad key).

    As you can see, Godot is correct, all of these actions you are trying to use do not exist. You have not created them in project settings.

    With that said, I do not believe it is your intention to allow remapping these inputs. Thus, instead of suggesting you create all the actions you are using, I'm going to suggest to not use actions...

    Instead use Input.is_physical_key_pressed which takes a value from the Key enum.

    I'm suggesting to use is_physical_key_pressed under the assumption that what matters is the physical position of the key, and not which letter it represents (which can change from one keyboard layout to another). However, I'll also mention that you could use Input.is_key_pressed or Input.is_key_label_pressed in similar fashion.