Hi, Im new to Godot and programming but I want to make a a grid based strategy game. I watched GDquest amazing Learn to code from zero with Godot. That helped me setting up a Grid by code (see the picture).

How can I code a signal 'is mouse clicked' on each individual cell that starts a 'func on_cell_clicked' that prints the clicked cell coördinates. In a later stage I can use these coördinates to move my sprite to this location.

thanks in advance

best regards

  • You can calculate i and j from the mouse postion the same way you calculated cell positions from i and j when creating cells. Just in reverse:

    func on_cell_clicked(event):
    	if event is InputEventMouseButton:
    		if event.pressed:
    			var cell_index = event.position / cell_size

Isn't the code you posted already doing this? You just need to check the type of event passed to on_cell_clicked() and act accordingly.

    xyz

    Yes I think I am almost there. I just don't know how I can get the i and j value to the on_cell_clicked function so I can print it like this:
    print("cell" + str(i) + "," + str(j))

    How would I check the type of event passed to on_cell_clicked()?

    thanks

      You can calculate i and j from the mouse postion the same way you calculated cell positions from i and j when creating cells. Just in reverse:

      func on_cell_clicked(event):
      	if event is InputEventMouseButton:
      		if event.pressed:
      			var cell_index = event.position / cell_size

        xyz

        thanks, seems logical now you typed it. Still learning how to use the signals etc.
        Maybe a grid-based click to move game isn't the most simple one to start out with. ><

        • xyz replied to this.

          BuildingDigital If you're completely new to all this, maybe the best place to start is Godot's famous Dodge The Creeps tutorial. It shows you how to build a simple game from start to finish.

          BuildingDigital How would I check the type of event passed to on_cell_clicked()?

          print_debug(event) is helpful here.

          print_debug() works the same as print(), but is useful for testing/debugging because it also shows the location of the print_debug() statement.

            class_name Grid
            extends Node2D
            @export var row := 5
            @export var column := 5
            @export var cell_size := 150
            func _ready():
            	for i in range(row):
            		for j in range(column):
            			var cell = ColorRect.new()
            			cell.color = Color.WHITE
            			cell.size = Vector2(cell_size, cell_size)
            			cell.position = Vector2(j * cell_size, i * cell_size)
            			add_child(cell)
            					
            			#for debugging						
            			var border = Line2D.new()
            			border.default_color = Color.BLUE
            			border.width = 1 # set the border width to 1 pixel
            			border.points = [Vector2(0, 0), Vector2(cell_size, 0), Vector2(cell_size, cell_size), Vector2(0, cell_size), Vector2(0, 0)] # set the border points to form a rectangle
            			border.position = Vector2(j * cell_size, i * cell_size)
            			add_child(border)
            
            			var label = Label.new()
            			label.text = str(j) + "," + str(i) # set the label text to the cell's row and column number
            			label.set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER)
            			label.set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER)
            			label.position = Vector2(j * cell_size, i * cell_size)
            			label.size = Vector2(cell_size, cell_size)
            			label.set("theme_override_colors/font_color", Color(1, 0, 0))
            			add_child(label)
            			
            			cell.connect("mouse_button_pressed", on_cell_clicked)
            			
            func on_cell_clicked(event):
            	if event is InputEventMouseButton:
            		if event.pressed:
            			var cell_index = event.position / cell_size			
            			print(str(cell_index))

            I have this code now but its not printing anything at the moment. So it's not activating the on_cell_clicked function yet. I am getting this error in the compiler when I run the scene. My grid is showing perfectly

            Attempt to connect nonexistent signal 'mouse_button_pressed' to callable 'Node2D(gameboard.gd)::on_cell_clicked'.
            <C++ Fout> Condition "!signal_is_valid" is true. Returning: ERR_INVALID_PARAMETER
            <C++ Source> core/object/object.cpp:1256 @ connect()
            <Stack Trace> gameboard.gd:32 @ _ready()

            thanks

            best regards

            As the error message says a ColorRect node does not emit a signal called mouse_button_pressed.
            If you check Godot's documentation for the Control class (the base class of ColorRect) you'll see there's gui_input signal that forwards all received input events. So try to connect to that signal instead.

              xyz

              Thanks, is there a way to see which inputs a node can handle? I have looked in the online documentation but no luck.
              Because I changed the cell variable from ColorRect to Area2D. Now its not printing anything anymore because I assume that Area2D does not emit a signal called gui_input.

              thanks

              • xyz replied to this.

                BuildingDigital
                You can probably use input_event signal for Area2D node, but beware, the callback function is in that case expected to have 3 arguments instead of only 1 needed for gui_input signal.

                In editor, you can see all possible signals a node can emit if you select a node and switch to Node tab. By default it's on the right panel next to Inspector tab:

                Here you can also make manual connections by right clicking on a signal.

                Note that many signals are actually inherited from node's ancestor classes. So when you look at the reference page for a specific node it will only describe signals for node's immediate class. To get info on all possible signals for that node, you'll also have to check reference pages for classes this node inherits from. The inheritance chain is always listed at the top of the node's reference page:

                  xyz

                  thanks, after looking into different Node's and there signals I noticed that the Control node also has the gui_input signal so I just used that one and it works fine.

                  I also added a player scene with following code:

                  extends CharacterBody2D
                  
                  func _on_input_event(viewport, event, shape_idx):
                  	if event.is_action_pressed("left_click"):
                  		print("Tank clicked")

                  It works fine but when I instance the player scene in my main scene it doesn't print anymore which means the function is not called in my main scene.