added better portal animation

This commit is contained in:
2ManyProjects 2025-02-26 20:15:04 -06:00
parent 707d44862a
commit 4aa9085c9c
6 changed files with 289 additions and 148 deletions

View file

@ -161,7 +161,7 @@ func getCurrentFen() -> String:
emptySquares = 0 emptySquares = 0
var tile = tileManager.active_tiles[str(x) + "-" + str(y)] var tile = tileManager.active_tiles[str(x) + "-" + str(y)]
if tile is WallTile or tile is DoubleWallTile: if tile is WallTile or tile is DoubleWallTile:
if tile is DoubleWallTile: if tile.tile_name == "Double Wall":
fen += "*" fen += "*"
else: else:
fen += "*" fen += "*"
@ -395,22 +395,22 @@ func summonPiece(pieceName: String, color: int) -> Node:
var piece var piece
match pieceName: match pieceName:
"Pawn": "Pawn":
piece = Pawn.new() piece = Pawn.new(self)
piece.name = "Pawn" piece.name = "Pawn"
"King": "King":
piece = King.new() piece = King.new(self)
piece.name = "King" piece.name = "King"
"Queen": "Queen":
piece = Queen.new() piece = Queen.new(self)
piece.name = "Queen" piece.name = "Queen"
"Knight": "Knight":
piece = Knight.new() piece = Knight.new(self)
piece.name = "Knight" piece.name = "Knight"
"Rook": "Rook":
piece = Rook.new() piece = Rook.new(self)
piece.name = "Rook" piece.name = "Rook"
"Bishop": "Bishop":
piece = Bishop.new() piece = Bishop.new(self)
piece.name = "Bishop" piece.name = "Bishop"
piece.Item_Color = color piece.Item_Color = color

View file

@ -79,4 +79,3 @@ func get_overlay(overlay_name: String) -> Node:
func has_piece() -> bool: func has_piece() -> bool:
return piece != null return piece != null

View file

@ -76,7 +76,7 @@ func clear_tiles() -> void:
remove_tile(location) remove_tile(location)
# Function to place random game tiles at the start of each match # Function to place random game tiles at the start of each match
func place_random_game_tiles(num_tiles: int = 0) -> void: func place_random_game_tiles(num_tiles: int = 5) -> void:
if !board_flow: if !board_flow:
push_error("TileManager not initialized with board_flow") push_error("TileManager not initialized with board_flow")
return return
@ -99,37 +99,47 @@ func place_random_game_tiles(num_tiles: int = 0) -> void:
var skipNext = false; var skipNext = false;
var wall: Tile # var wall: Tile
var p = '0-2' # var p = '0-2'
var cntr = board_flow.get_node(p) as PieceContainer # var cntr = board_flow.get_node(p) as PieceContainer
var w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0 # var w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
wall = WallTile.new(cntr, w, -1) # wall = WallTile.new(cntr, w, -1)
add_tile(p, wall) # add_tile(p, wall)
p = '1-2' # # p = '1-2'
cntr = board_flow.get_node(p) as PieceContainer # # cntr = board_flow.get_node(p) as PieceContainer
w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0 # # w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
wall = WallTile.new(cntr, w, -1) # # wall = WallTile.new(cntr, w, -1)
add_tile(p, wall) # # add_tile(p, wall)
p = '2-2' # p = '2-2'
cntr = board_flow.get_node(p) as PieceContainer # cntr = board_flow.get_node(p) as PieceContainer
w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0 # w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
wall = WallTile.new(cntr, w, -1) # wall = WallTile.new(cntr, w, -1)
add_tile(p, wall) # add_tile(p, wall)
p = '5-2' # p = '3-2'
cntr = board_flow.get_node(p) as PieceContainer # cntr = board_flow.get_node(p) as PieceContainer
w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0 # w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
wall = WallTile.new(cntr, w, -1) # wall = WallTile.new(cntr, w, -1)
add_tile(p, wall) # add_tile(p, wall)
p = '6-2' # p = '4-2'
cntr = board_flow.get_node(p) as PieceContainer # cntr = board_flow.get_node(p) as PieceContainer
w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0 # w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
wall = WallTile.new(cntr, w, -1) # wall = WallTile.new(cntr, w, -1)
add_tile(p, wall) # add_tile(p, wall)
p = '7-2' # p = '5-2'
cntr = board_flow.get_node(p) as PieceContainer # cntr = board_flow.get_node(p) as PieceContainer
w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0 # w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
wall = WallTile.new(cntr, w, -1) # wall = WallTile.new(cntr, w, -1)
add_tile(p, wall) # add_tile(p, wall)
# # p = '6-2'
# # cntr = board_flow.get_node(p) as PieceContainer
# # w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
# # wall = WallTile.new(cntr, w, -1)
# # add_tile(p, wall)
# p = '7-2'
# cntr = board_flow.get_node(p) as PieceContainer
# w = (int(p.split("-")[0]) + int(p.split("-")[1])) % 2 == 0
# wall = DoubleWallTile.new(cntr, w, -1)
# add_tile(p, wall)
# Skip over an iteration for a paired tile # Skip over an iteration for a paired tile
for i in range(min(num_tiles, available_positions.size())): for i in range(min(num_tiles, available_positions.size())):
@ -156,8 +166,8 @@ func place_random_game_tiles(num_tiles: int = 0) -> void:
add_tile(pos, tile) add_tile(pos, tile)
continue continue
1: # Double Wall 1: # Double Wall
tile = DoubleWallTile.new(container, is_white, -1) # tile = DoubleWallTile.new(container, is_white, -1)
add_tile(pos, tile) # add_tile(pos, tile)
continue continue
2: # Portal pair 2: # Portal pair
# Only create portal pair if this isn't the last tile # Only create portal pair if this isn't the last tile

View file

@ -33,10 +33,61 @@ func apply_effect(piece: Pawn = null) -> void:
if current_container: if current_container:
var target_container = other_portal.base_button as PieceContainer var target_container = other_portal.base_button as PieceContainer
if target_container: if target_container:
# last_piece = piece last_piece = piece
other_portal.last_piece = piece other_portal.last_piece = piece
# Move the piece # Move the piece
target_container.animate_movement(current_container, piece); animate_portal_teleport(piece, current_container, target_container)
# target_container.animate_movement(current_container, piece);
func animate_portal_teleport(piece: Pawn, origin_container: PieceContainer, destination_container: PieceContainer) -> void:
# Save original properties
var original_scale = piece.scale
var original_modulate = piece.modulate
var original_z_index = piece.z_index
# Raise z-index during animation
piece.z_index = 2
# Step 1: Move to portal center
var portal_center = base_button.global_position + (base_button.size / 2)
var step1_tween = piece.create_tween()
step1_tween.set_trans(Tween.TRANS_LINEAR)
step1_tween.tween_property(piece, "global_position", portal_center, 0.2)
await step1_tween.finished
# Step 2: Shrink and fade out
var step2_tween = piece.create_tween()
step2_tween.set_trans(Tween.TRANS_QUAD)
step2_tween.set_ease(Tween.EASE_OUT)
# Ensure modulate maintains the piece's color (white or black)
var fade_color = original_modulate.darkened(0.5)
fade_color.a = 0.0 # Fully transparent
# Animate scale and transparency
step2_tween.tween_property(piece, "scale", Vector2.ZERO, 0.3)
step2_tween.parallel().tween_property(piece, "modulate", fade_color, 0.3)
await step2_tween.finished
# Step 3: Reparent to destination container
# origin_container.remove_child(piece)
# destination_container.add_child(piece)
# Position at target portal center
var target_portal_center = other_portal.base_button.global_position + (other_portal.base_button.size / 2)
piece.global_position = target_portal_center
# Step 4: Grow and fade in at destination
var step4_tween = piece.create_tween()
step4_tween.set_trans(Tween.TRANS_BACK) # A bit of bounce
step4_tween.set_ease(Tween.EASE_OUT)
# Reset scale and opacity
step4_tween.tween_property(piece, "scale", original_scale, 0.3)
step4_tween.parallel().tween_property(piece, "modulate", original_modulate, 0.3)
await step4_tween.finished
# Reset z-index
piece.z_index = original_z_index
func update_appearance() -> void: func update_appearance() -> void:
if is_effect_active() && base_button: if is_effect_active() && base_button:

View file

@ -1,123 +1,202 @@
@tool @tool
extends Pawn extends Pawn
class_name Knight class_name Knight
func _ready(): func _ready():
self.texture = load("res://addons/Chess/Textures/WKnight.svg") self.texture = load("res://addons/Chess/Textures/WKnight.svg")
Points = 3 Points = 3
func _process(_delta): func _process(_delta):
if Item_Color != Temp_Color: if Item_Color != Temp_Color:
Temp_Color = Item_Color Temp_Color = Item_Color
if Item_Color == 0: if Item_Color == 0:
self.texture = load("res://addons/Chess/Textures/WKnight.svg") self.texture = load("res://addons/Chess/Textures/WKnight.svg")
elif Item_Color == 1: elif Item_Color == 1:
self.texture = load("res://addons/Chess/Textures/BKnight.svg") self.texture = load("res://addons/Chess/Textures/BKnight.svg")
func getValidMoves(board_flow, current_location: String) -> Dictionary: func getValidMoves(board_flow, current_location: String) -> Dictionary:
var moves = { var moves = {
"regular_moves": [], "regular_moves": [],
"special_moves": [] "special_moves": []
} }
var loc = current_location.split("-") var loc = current_location.split("-")
var x = int(loc[0]) var x = int(loc[0])
var y = int(loc[1]) var y = int(loc[1])
var game = board_flow.get_parent() as ChessGame game = board_flow.get_parent() as ChessGame
# All possible L-shaped moves # All possible L-shaped moves
var knight_moves = [ var knight_moves = [
[-2, -1], [-2, 1], [-2, -1], [-2, 1],
[-1, -2], [-1, 2], [-1, -2], [-1, 2],
[1, -2], [1, 2], [1, -2], [1, 2],
[2, -1], [2, 1] [2, -1], [2, 1]
] ]
for move in knight_moves: for move in knight_moves:
var target_x = x + move[0] var target_x = x + move[0]
var target_y = y + move[1] var target_y = y + move[1]
var new_loc = str(target_x) + "-" + str(target_y) var new_loc = str(target_x) + "-" + str(target_y)
if is_valid_cell(board_flow, new_loc): if is_valid_cell(board_flow, new_loc):
# Check tiles in the path # Check both possible paths to the target
var path_clear = true var horizontal_first_clear = true
var vertical_first_clear = true
# Check horizontally first, then vertically (or vice versa)
var check_horizontal_first = abs(move[0]) > abs(move[1]) # Path 1: Check horizontal first, then vertical
# Check horizontal movement
if check_horizontal_first: var step_x = sign(move[0])
# Check horizontal movement for i in range(1, abs(move[0]) + 1):
var step_x = sign(move[0]) var path_tile_loc = str(x + (i * step_x)) + "-" + str(y)
for i in range(1, abs(move[0]) + 1): var tile = game.tileManager.get_tile(path_tile_loc)
var path_tile_loc = str(x + (i * step_x)) + "-" + str(y) if tile && !tile.jumpable:
var tile = game.tileManager.get_tile(path_tile_loc) horizontal_first_clear = false
if tile && !tile.jumpable: break
path_clear = false
break # Check vertical movement if horizontal was clear
if horizontal_first_clear:
# Check vertical movement if path still clear var step_y = sign(move[1])
if path_clear: var path_tile_loc = str(target_x) + "-" + str(y + step_y)
var step_y = sign(move[1]) var tile = game.tileManager.get_tile(path_tile_loc)
var path_tile_loc = str(target_x) + "-" + str(y + step_y) if tile && !tile.jumpable:
var tile = game.tileManager.get_tile(path_tile_loc) horizontal_first_clear = false
if tile && !tile.jumpable:
path_clear = false
else:
# Check vertical movement
var step_y = sign(move[1])
for i in range(1, abs(move[1]) + 1):
var path_tile_loc = str(x) + "-" + str(y + (i * step_y))
var tile = game.tileManager.get_tile(path_tile_loc)
if tile && !tile.jumpable:
path_clear = false
break
# Check horizontal movement if path still clear
if path_clear:
var step_x = sign(move[0])
var path_tile_loc = str(x + step_x) + "-" + str(target_y)
var tile = game.tileManager.get_tile(path_tile_loc)
if tile && !tile.jumpable:
path_clear = false
# Only add the move if the path is clear and the destination is valid # Path 2: Check vertical first, then horizontal
if path_clear && (can_move_to_cell(board_flow, new_loc) || can_move_to_cell(board_flow, new_loc, true)): # Check vertical movement
moves.regular_moves.append(new_loc) var step_y = sign(move[1])
for i in range(1, abs(move[1]) + 1):
var path_tile_loc = str(x) + "-" + str(y + (i * step_y))
var tile = game.tileManager.get_tile(path_tile_loc)
if tile && !tile.jumpable:
vertical_first_clear = false
break
# Check horizontal movement if vertical was clear
if vertical_first_clear:
var path_tile_loc = str(x + step_x) + "-" + str(target_y)
var tile = game.tileManager.get_tile(path_tile_loc)
if tile && !tile.jumpable:
vertical_first_clear = false
return moves # Move is valid if EITHER path is clear
if (horizontal_first_clear || vertical_first_clear) && (can_move_to_cell(board_flow, new_loc) || can_move_to_cell(board_flow, new_loc, true)):
moves.regular_moves.append(new_loc)
return moves
# func animate_movement(target_position: Vector2, duration: float = 0.5) -> void:
# z_index = 1
# var tween = create_tween()
# tween.set_trans(Tween.TRANS_LINEAR)
# tween.set_ease(Tween.EASE_IN_OUT)
# var start_pos = global_position
# var total_delta = target_position - start_pos
# var mid_pos: Vector2
# var game = get_tree().get_first_node_in_group("ChessGame") as ChessGame
# var cell_delta_x = int(total_delta.x / game.boardXSize)
# var cell_delta_y = int(total_delta.y / game.boardYSize)
# if abs(cell_delta_x) > abs(cell_delta_y):
# # Moving more horizontally ([-2, ±1])
# mid_pos = Vector2(
# start_pos.x + (cell_delta_x * game.boardXSize),
# start_pos.y
# )
# else:
# # Moving more vertically ([±1, -2])
# mid_pos = Vector2(
# start_pos.x,
# start_pos.y + (cell_delta_y * game.boardYSize)
# )
# # First move (longer distance)
# tween.tween_property(self, "global_position", mid_pos, duration / 3 * 2)
# # Second move (shorter distance)
# tween.tween_property(self, "global_position", target_position, duration / 3 * 1)
# await tween.finished
# z_index = 0
func animate_movement(target_position: Vector2, duration: float = 0.5) -> void: func animate_movement(target_position: Vector2, duration: float = 0.5) -> void:
z_index = 1 z_index = 1
var tween = create_tween() var tween = create_tween()
tween.set_trans(Tween.TRANS_LINEAR) tween.set_trans(Tween.TRANS_LINEAR)
tween.set_ease(Tween.EASE_IN_OUT) tween.set_ease(Tween.EASE_IN_OUT)
var start_pos = global_position var start_pos = global_position
var total_delta = target_position - start_pos var total_delta = target_position - start_pos
var mid_pos: Vector2 var mid_pos: Vector2
var game = get_tree().get_first_node_in_group("ChessGame") as ChessGame var cell_delta_x = int(total_delta.x / game.boardXSize)
var cell_delta_x = int(total_delta.x / game.tileXSize) var cell_delta_y = int(total_delta.y / game.boardYSize)
var cell_delta_y = int(total_delta.y / game.tileYSize)
if abs(cell_delta_x) > abs(cell_delta_y): # Convert current and target positions to board coordinates
# Moving more horizontally ([-2, ±1]) var current_x = int(start_pos.x / game.boardXSize)
mid_pos = Vector2( var current_y = int(start_pos.y / game.boardYSize)
start_pos.x + (cell_delta_x * game.tileXSize),
start_pos.y # Check both possible paths
) var horizontal_first_clear = true
else: var vertical_first_clear = true
# Moving more vertically ([±1, -2])
mid_pos = Vector2( # Check horizontal-first path
start_pos.x, for i in range(1, abs(cell_delta_x) + 1):
start_pos.y + (cell_delta_y * game.tileYSize) var step_x = sign(cell_delta_x)
) var path_tile_loc = str(current_x + (i * step_x)) + "-" + str(current_y)
var tile = game.tileManager.get_tile(path_tile_loc)
if tile && !tile.jumpable:
horizontal_first_clear = false
break
if horizontal_first_clear:
var step_y = sign(cell_delta_y)
var path_tile_loc = str(current_x + cell_delta_x) + "-" + str(current_y + step_y)
var tile = game.tileManager.get_tile(path_tile_loc)
if tile && !tile.jumpable:
horizontal_first_clear = false
# Check vertical-first path
for i in range(1, abs(cell_delta_y) + 1):
var step_y = sign(cell_delta_y)
var path_tile_loc = str(current_x) + "-" + str(current_y + (i * step_y))
var tile = game.tileManager.get_tile(path_tile_loc)
if tile && !tile.jumpable:
vertical_first_clear = false
break
if vertical_first_clear:
var step_x = sign(cell_delta_x)
var path_tile_loc = str(current_x + step_x) + "-" + str(current_y + cell_delta_y)
var tile = game.tileManager.get_tile(path_tile_loc)
if tile && !tile.jumpable:
vertical_first_clear = false
# First move (longer distance) # Choose the valid path for animation
tween.tween_property(self, "global_position", mid_pos, duration / 3 * 2) var use_horizontal_first = true
# Second move (shorter distance) if !horizontal_first_clear && vertical_first_clear:
tween.tween_property(self, "global_position", target_position, duration / 3 * 1) use_horizontal_first = false
elif horizontal_first_clear && vertical_first_clear:
# If both paths are valid, use the traditional logic
use_horizontal_first = abs(cell_delta_x) > abs(cell_delta_y)
elif !horizontal_first_clear && !vertical_first_clear:
push_error("Attempting to animate an invalid move!")
return
await tween.finished if use_horizontal_first:
z_index = 0 mid_pos = Vector2(
start_pos.x + (cell_delta_x * game.boardXSize),
start_pos.y
)
else:
mid_pos = Vector2(
start_pos.x,
start_pos.y + (cell_delta_y * game.boardYSize)
)
tween.tween_property(self, "global_position", mid_pos, duration / 3 * 2)
tween.tween_property(self, "global_position", target_position, duration / 3 * 1)
await tween.finished
z_index = 0

View file

@ -11,6 +11,7 @@ class_name Pawn
@export var Points = 1 @export var Points = 1
var game: ChessGame = null
var duration_label: Label var duration_label: Label
var Temp_Color = 0 var Temp_Color = 0
var Double_Start = true var Double_Start = true
@ -23,7 +24,8 @@ var id: String = Utils.generate_guid()
func _ready(): func _ready():
modulate = Color.WHITE if Item_Color == 0 else Color.BLACK modulate = Color.WHITE if Item_Color == 0 else Color.BLACK
func _init() -> void: func _init(chess: ChessGame) -> void:
game = chess
self.texture = load("res://addons/Chess/Textures/WPawn.svg") self.texture = load("res://addons/Chess/Textures/WPawn.svg")
var background_style = StyleBoxFlat.new() var background_style = StyleBoxFlat.new()
background_style.bg_color = Color.WHITE background_style.bg_color = Color.WHITE