Godot Version
4.2.1
Question
I’ve been working on a Chess game and got pretty far into it when I realized how long my main script is and decided it’s time to learn how to properly do OOP. I only have basic knowledge of how this works and am struggling with what I think is a pretty basic concept.
When the game starts, I am iterating through a FEN string (a string representing the piece layout on the board) and spawning instantiating Piece.tscn and storing the FEN character and colour etc. Piece.tscn consists of the Piece node with Piece.gd attached to it, and the Icon node (textureRect) which loads the piece’s corresponding icon.
I think what I want to do now is keep Piece.gd as the parent class for all pieces, and then have different scripts such as Pawn.gd which will calculate valid moves (currently all valid moves are calculated in one long spaghetti code script). I’m having trouble summarizing the question because I feel like I have a fundamental misunderstanding on what this setup should look like…
So here’s what I got so far, which does not work. Further down I’ll add the working spaghetti code.
Broken code
Main.gd
func add_piece(fen_char, location) -> void:
#var new_piece = piece_scene.instantiate() #Piece.tscn
var piece_script_path = DataHandler.piece_objects[DataHandler.fen_dict[fen_char]]
var piece_script = load(piece_script_path).new()
var piece_scene_instance = piece_scene.instantiate()
# Here piece_script somehow ends up being Piece.gd even though piece_script_path is pointing to Pawn.gd ??
chess_board_grid.add_child(piece_scene_instance)
piece_scene_instance.set_script(piece_script)
piece_scene_instance.add_child(piece_script)
#piece_scene_instance.icon_path = get_node(piece_scene_instance/Icon)
piece_script.fen_char = fen_char
piece_script.type = DataHandler.fen_dict[fen_char]
piece_script.team = "w" if fen_char == fen_char.capitalize() else "b"
piece_script.load_icon()
Then theres a bit more about location etc, but I don’t get past loading the icon because the reference to the TextureRect doesnt work (returns Nil)
Piece.gd
extends Node2D
class_name Piece
@onready var icon = $Icon
var square_ID : int = -1
var type : int
var team : String
var fen_char : String
var is_revealed : bool = true
var is_pawn : bool = false
var square_ID_history = {}
...
func load_icon() -> void:
icon.texture = load(DataHandler.assets[type])
Pawn.gd
extends Piece
# Called when the node enters the scene tree for the first time.
func _ready():
is_pawn = true
pass # Replace with function body.
Spaghetti code (working)
Main.gd
func add_piece(fen_char, location) -> void:
var new_piece = piece_scene.instantiate()
chess_board_grid.add_child(new_piece)
new_piece.fen_char = fen_char
new_piece.type = DataHandler.fen_dict[fen_char]
new_piece.team = "w" if new_piece.type < 6 else "b"
new_piece.load_icon(new_piece.type)
new_piece.global_position = bg_grid_array[location].global_position + piece_offset
piece_array[location] = new_piece
new_piece.square_ID = location
new_piece.square_ID_history[current_halfmove] = location
Piece.gd
# and here's the beginning of Piece.gd
extends Node2D
@onready var icon_path = $Icon
var square_ID : int = -1
var type : int
var team : String
var fen_char : String
var is_revealed : bool = true
var square_ID_history = {}
...
func load_icon(piece_ID) -> void:
icon_path.texture = load(DataHandler.assets[piece_ID])