El sistema de cartas en Beast Card Clash tiene dos capas: un nodo visual (CardScene) que maneja el renderizado y la interacción, y un objeto de datos ligero (Card) que viaja a través de la lógica del juego sin la sobrecarga de la escena. Comprender la frontera entre estas dos capas es clave para trabajar de manera efectiva con las cartas.
- CardScene: Una subclase de
TextureButtonque posee el sprite, las animaciones y la señalcard_selected. Vive en el árbol de escenas. - Card (clase interna): Un contenedor mínimo de datos que solo almacena
elementyvalue. Es seguro pasarlo entre sistemas y almacenarlo en arreglos.
CardScene
class_name CardScene extends TextureButton
CardScene es el objeto que colocas en el árbol de escenas cuando quieres mostrar una carta jugable. Gestiona su propio sprite, ejecuta animaciones continuas o basadas en eventos y emite una señal cuando el jugador la selecciona.
Propiedades exportadas
- element (
GameConstants.Elements): El tipo elemental de la carta (Aire, Tierra, Energía, Fuego o Agua). Al establecer esta propiedad, se llama automáticamente a_update_sprite()para cambiar a la textura correspondiente. - value (
int): El valor numérico de poder de la carta. Rango válido: de1aMAX_CARD_VAlUE(= 10). Al establecer esta propiedad se invoca a_update_sprite(). Los valores fuera del rango válido se limitan a0mediante el setter de la clase internaCard. - hide_card (
bool): Cuando estrue, la carta se muestra boca abajo utilizando la texturaplaceholderdeCardsList. Modificar esta propiedad activa la animación_flip_card()en lugar de realizar un intercambio de textura instantáneo. - disable_card (
bool): Cuando estrue, la carta se muestra en gris y se bloquea la interacción. Modificar esta propiedad invoca a_update_sprite()para aplicar visualmente el estado desactivado. - cards_list (
CardsList): Un recurso que mapea cada combinación de(element, value)a su textura, además de una texturaplaceholderpara las cartas boca abajo. Se asigna en el Inspector o se carga mediante código.
Señal
signal card_selected(card: Card)
Se emite cuando el jugador presiona la carta. La señal transporta un objeto de datos ligero Card (ver clase interna abajo), no el nodo completo CardScene. La señal se suprime si hide_card o disable_card están configurados en true.
# Conectar desde BattleManager o desde un nodo de visualización de la mano
card_scene.card_selected.connect(_on_card_selected)
func _on_card_selected(card: Card) -> void:
print("El jugador seleccionó una carta de elemento %s con valor %d" % [card.element, card.value])
Métodos
set_properties(values: Dictionary) -> void
Establece por lotes múltiples propiedades exportadas a partir de un diccionario en una sola llamada. Invoca a _update_sprite() una única vez después de aplicar todas las propiedades, lo cual resulta más eficiente que establecerlas por separado si necesitas cambiar varias a la vez.
- values (
Dictionary): Un diccionario que asocia cadenas con nombres de propiedades a sus nuevos valores.
Si pasas una clave que no coincida con ninguna propiedad de
CardScene, se llamará apush_errory esa clave será omitida. El diccionario no se valida antes de la iteración, por lo que es posible una aplicación parcial de los cambios.
get_abstract_card() -> Card
Devuelve un objeto de datos ligero Card construido con el element y el value actuales de esta CardScene.
- Retorno (
Card): Una nueva instancia deCard(element, value). Utiliza esto siempre que necesites transferir datos de la carta a un sistema que no deba mantener una referencia al nodo de la escena.
Clase interna Card
La clase interna Card es un contenedor puro de datos sin dependencias de escena.
# Definida dentro de CardScene
func _init(new_element: GameConstants.Elements, new_value: int)
var element: GameConstants.Elements
var value: int # setter: si v < 0 o v > 10, value = 0
- element (
GameConstants.Elements): El tipo elemental. Uno de los siguientes:AIR,EARTH,ENERGY,FIRE,WATER. - value (
int): Nivel de poder de la carta. El setter limita el rango a0..10: cualquier valor por debajo de0o por encima de10se almacena como0.
La clase interna
Cardno tiene intencionadamente ninguna referencia a su nodo padreCardScene. Esto significa que puedes crear objetosCardcon libertad dentro de la lógica del juego.
Recurso CardsList
CardsList es un recurso (Resource) de Godot que mapea cada combinación válida de (element, value) a una textura Texture2D, además de una textura placeholder para las cartas boca abajo. CardScene lo utiliza internamente en _update_sprite() para buscar la textura correcta cada vez que cambia element, value, hide_card o disable_card.
Animaciones visuales
Ondulación: balanceo continuo en reposo
Las cartas se balancean suavemente de arriba a abajo cuando están inactivas utilizando una onda senoidal calculada en _physics_process.
| Constante | Valor | Efecto |
|---|---|---|
ONDULAION_SPEED | 3.5 | Frecuencia del ciclo de la onda |
ONDULAION_STRENGHT | 2 | Amplitud en píxeles del movimiento vertical |
Los nombres de estas constantes contienen erratas en el archivo fuente (
ONDULAIONen lugar deONDULATION, ySTRENGHTen lugar deSTRENGTH).
Hover: reacción al pasar el cursor
Cuando el cursor entra en el área de la carta, esta se amplía (height * 1.5), se desplaza ligeramente hacia arriba y se tiñe de un tono gris tenue.
| Constante | Valor |
|---|---|
HOVER_TIME | 0.2s |
Flip: transición al voltear boca arriba / boca abajo
Se activa cuando cambia hide_card. La animación utiliza una escala de dos fases:
- Reducción de escala a cero:
scale.xrealiza una animación de1.0a0.0duranteROTATION_TIME(15 fotogramas). - Intercambio de textura: Mientras
scale.xestá en cero,_update_sprite()cambia la textura. - Restauración de escala:
scale.xse anima de0.0de vuelta a1.0para completar el giro.
| Constante | Valor |
|---|---|
ROTATION_TIME | 15 (entero, ver nota en el código) |
Patrones comunes
Instanciar y configurar una carta
var card_scene: CardScene = preload("res://assets/cards/card.tscn").instantiate()
card_scene.cards_list = preload("res://assets/cards/cards_list.tres")
card_scene.set_properties({
"element": GameConstants.Elements.WATER,
"value": 5
})
hand_container.add_child(card_scene)
card_scene.card_selected.connect(_on_card_selected)
Mostrar una carta boca abajo
# Revelar la carta (activa automáticamente la animación _flip_card)
card_scene.hide_card = false
Extraer datos para la lógica del juego
# Obtener una instancia ligera de Card
var card_data: Card = card_scene.get_abstract_card()
battle_manager.evaluate_play(card_data)