Hi everyone! I’m new to Godot, so sorry if I missed something obvious. In my code in my repo above, I have a class that holds data for a chessboard, and it’s defined in res://Scripts/GameState.gd. I currently have it in the _input function of chess_board_renderer.gd so you first select the piece to move, then the square to move it too. I’m aware that this makes it seem like the pieces teleport. I can’t find anyway to do interpolation so that it looks smooth, mostly because it draws the chess pieces in _draw rather than instantiating Nodes. I’d like to stay away from instantiation though because it’ll clog things up. I don’t know how to smooth it out, so if anyone does please let me know. Thanks!
Well, one way would be to set a flag saying ‘piece is on the move’. In the _process function where your re-draw your board (and you seem to be redrawing it every frame even though for most frames it will not change) you have two variables now, original position and new position for the piece that is on the move. You can then simply in your process function tween or lerp from the old position to the new one. (You may want a slightly more complex process for knight moves later and castling). When it gets to the required position, set the flag to false and stop redrawing anything.
In fact the board never needs to be redrawn. You should draw it once on its own layer. The pieces only need to be redrawn when a piece is moving, and only that piece and possibly the piece being taken (redrawn to remove it that is). As for highlighting squares, you could create a highlights layer to draw over the top of the board. So three layers, one for the board, one for the highlights, and one for the pieces.
In fact, if each piece had its own node, you could move the pieces to their new positions by just tweening the global position of that pieces node.
func _process(delta: float) -> void:
if piece_is_moving:
# lerp or move_to or tween from old position to new position
current_position_of_moving_piece = lerp(current_position_of_moving_piece , target_positon, 0.3)
queue_redraw() # Only redraw moving piece.
if current_position == target_position:
piece_is_moving = false
piece_moved.emit() # Signal for your turn manager or game manager
Any specific reason you don’t want to instantiate scenes? That’s what Godot is basically made for and would make this problem (and future problems) waaay easier to solve. Your solution works too of course, but it’s like you’re trying to ride a Porsche on an off-road track
Anyway, I agree with what @pauldrewett already suggested.
Just to follow on from that, your ‘Chess Engine’ should be completely separate from your games UI mechanics. The chess engine just does one or two things like assess current situation to see who is stronger, and pick the next move. It should respond with your coded byte-array or string or whatever to indicate the state of the board and which piece moved to get to that state. Godot can easily cope with 32 nodes, one for each piece, and another for the board. Your chess engine should be as separated and independent as possible so you could reasonably release it as a stand alone add_on.
All the ‘game’ part has to do is send the chess engine the current move. Like:
1. e4 e5
2. Nf3 Nc6
3. Bxc6
Or whatever standard notation you are adhering to. (It might also have to send different initial board set ups if you are considering offering variations like Fisher Random (which I love watching on YT). I think the engine should maintain the board state during a game. The game should remember all the moves. (You might want to also keep the current board state after each move too in case you want to allow take backs.)
I also noticed on chess.com that their moves are like Godots tweens (linear tweens) or move_toward, where the move takes 1 second, no matter how far accross the board the piece is moving. So when you sweep a rook accross the entire board (sacrifices the ROOOOOK! as Gotham would say) it seems to move faster than when you move a pawn say one square, which is actually quite a nice effect.
In terms of instantiating 32 nodes for the pieces, that is relatively trivial for Godot. In terms of moving your pawn node with a move_toward or tween, this is again relatively trivial. Your chess engine, on the other hand, is the really hard part, and I really look forward to seeing your final results. I wish I could actually help, but as always, time is not on our side.