VegeCard/Scripts/GameManager.gd
2025-03-27 10:19:13 +08:00

217 lines
6.6 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extends Node
@export var cols : int
@export var cell_size : Vector2i
@export var left_top_of_board : Marker2D
@export var init_card_anchos : Array[Marker2D]
@export var score_num_label : Label
signal dragging_card
signal release_dragging_card
signal place_card
signal kill_cards
var score = 0
var waitting_cards_num = 4
var has_mouse: bool = false
var dragged_card : Card
var hovered_cell_control : ColorRect
var hovered_cell : Vector2 = Global.invalid_cell_index
var board_info : Array = []
const GLOBAL_LEFT_TOP = "global-left-top"
const GLOBAL_CENTER = "global-center"
const INDEX = "index"
const AREA = "area"
const HOLD_CARD = "hold-card"
const HOLD_CARD_VALUE = "hold-card-value"
const HOLD_CARD_CATEGORY = "hold-card-category"
const hovered_color = "015aafb8"
func _ready() -> void:
init_game()
dragging_card.connect(_on_dragging_card)
release_dragging_card.connect(_on_release_dragging_card)
place_card.connect(_on_place_card)
kill_cards.connect(_on_kill_cards)
func init_game() -> void:
board_info = create_cells()
score = 0
waitting_cards_num = init_card_anchos.size()
send_cards()
func create_cells() -> Array:
var cells_matrix = []
var init_pos = Vector2(left_top_of_board.global_position.x, left_top_of_board.global_position.y)
for i in range(0, cols):
var row = []
for j in range(0, cols):
var left_top_pos = Vector2(init_pos.x + i * cell_size.x, init_pos.y + j * cell_size.y)
var center_pos = Vector2(left_top_pos.x + cell_size.x / 2, left_top_pos.y + cell_size.y / 2)
var cell = setup_cell_rect(left_top_pos, cell_size)
$BoardCells.add_child(cell)
var dict = {
GLOBAL_LEFT_TOP : left_top_pos,
GLOBAL_CENTER : center_pos,
INDEX: Vector2i(i, j),
AREA : cell,
HOLD_CARD : null
}
row.append(dict)
cells_matrix.append(row)
return cells_matrix
func setup_cell_rect(left_top: Vector2, size: Vector2i) -> ColorRect:
var cell = ColorRect.new()
cell.color = Color(hovered_color)
cell.size = cell_size
cell.global_position = left_top
cell.visible = false
return cell
func _process(_delta: float) -> void:
var cell = clamp_cell()
if hovered_cell_control != null:
hovered_cell_control.visible = false
if cell != null:
hovered_cell_control = cell
cell.visible = true
func _on_dragging_card(card: Card) -> void:
dragged_card = card
func _on_release_dragging_card(card: Card, index: Vector2i) -> void:
dragged_card = null
waitting_cards_num -= 1
if waitting_cards_num == 0:
waitting_cards_num = init_card_anchos.size()
send_cards()
func _on_place_card(card: Card, index: Vector2i) -> void:
var cell_info = board_info[index.x][index.y]
var lt = cell_info[GLOBAL_LEFT_TOP]
card.global_position = lt
card.settled = true
cell_info[HOLD_CARD] = card
cell_info[HOLD_CARD_VALUE] = card.value
cell_info[HOLD_CARD_CATEGORY] = card.category
card.index = index
try_kill_card(index)
func try_kill_card(index: Vector2i) -> void:
var detected_cards = detect_cards(index)
if detected_cards.size() > 1:
emit_signal("kill_cards", detected_cards)
func detect_cards(index: Vector2i) -> Array[Vector2i]:
var cell_info = board_info[index.x][index.y]
var card = cell_info[HOLD_CARD]
if card == null:
return []
return _detect_cards(index, index, [])
func _detect_cards(index: Vector2i, origin_index: Vector2i, visited) -> Array[Vector2i]:
# 检查是否越界或已经访问
if index.x < 0 or index.y < 0 or index.x >= cols or index.y >= cols:
return []
if index in visited:
return []
# 标记当前格子为已访问
visited.append(index)
var cell_info = board_info[index.x][index.y]
var origin_cell_info = board_info[origin_index.x][origin_index.y]
# 如果当前格子为空值为0则返回空列表
if cell_info[HOLD_CARD] == null:
return []
# 当前格子含有棋子,将其加入结果
if cell_info[HOLD_CARD].category == origin_cell_info[HOLD_CARD].category and cell_info[HOLD_CARD].value == origin_cell_info[HOLD_CARD].value:
var result : Array[Vector2i] = [index]
# 检查上下左右相邻格子
var directions = [
Vector2i(0, 1), # 上
Vector2i(0, -1), # 下
Vector2i(1, 0), # 右
Vector2i(-1, 0) # 左
]
for dir in directions:
result += _detect_cards(index + dir, index, visited)
return result
return []
func _on_kill_cards(index_array: Array[Vector2i]) -> void:
print("------*****--------")
for i in index_array:
var cell_info = board_info[i.x][i.y]
var card = cell_info[HOLD_CARD] as Card
cell_info[HOLD_CARD] = null
cell_info[HOLD_CARD_CATEGORY] = 0
cell_info[HOLD_CARD_VALUE] = -999
card.index = Global.invalid_cell_index
card.queue_free()
print("kill-" + str(i) + "-" + str(cell_info))
score += 1
score_num_label.text = str(score)
print("-------------------")
func get_hover_cell_index() -> Vector2i:
var mouse_global_position = $MouseAnchor.get_global_mouse_position()
return get_cell_on_pos(mouse_global_position)
func get_cell_on_pos(pos: Vector2) -> Vector2i:
if pos.x < left_top_of_board.global_position.x or pos.y < left_top_of_board.global_position.y:
return Global.invalid_cell_index
var relative_pos = Vector2(pos.x - left_top_of_board.global_position.x, pos.y - left_top_of_board.global_position.y)
var index = Vector2i(int(relative_pos.x) / cell_size.x, int(relative_pos.y) / cell_size.y)
if index.x < 0 or index.x >= cols or index.y < 0 or index.y >= cols:
index = Global.invalid_cell_index
return index
func clamp_cell() -> ColorRect:
var index = get_hover_cell_index()
if index != Global.invalid_cell_index:
var cell_info = board_info[index.x][index.y]
var cell = cell_info[AREA]
if cell != null:
var control = cell as ColorRect
return control
return null
func send_cards() -> void:
var card_prefab = load("res://Scenes/Card.tscn")
for i in range(waitting_cards_num):
var pos = init_card_anchos[i].global_position
var card_instance = card_prefab.instantiate() as Card
var card_size = (card_instance as Card).texture_normal.get_size()
card_instance.global_position = Vector2(pos.x - card_size.x / 2, pos.y - card_size.y / 2)
var val = randi() % 9 + 1
var cate_num = randi() % 4
card_instance.setup_card(cate_num, val)
$Cards.add_child(card_instance)
func _on_board_area_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT:
if not event.pressed:
try_place_card(dragged_card)
func try_place_card(card: Card) -> void:
var index = get_hover_cell_index()
if dragged_card == null or index == Global.invalid_cell_index:
return
var cell_info = board_info[index.x][index.y]
if cell_info[HOLD_CARD] == null:
emit_signal("release_dragging_card", card, index)
emit_signal("place_card", card, index)