init
This commit is contained in:
872
docs/API.md
Normal file
872
docs/API.md
Normal file
@@ -0,0 +1,872 @@
|
||||
# Card Framework API Reference
|
||||
|
||||
Complete API reference for the Godot 4.x Card Framework addon. This framework provides a modular system for creating 2D card games with drag-and-drop functionality, flexible container management, and extensible card factories.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Configuration](#configuration)
|
||||
- [CardFrameworkSettings](#cardframeworksettings)
|
||||
- [Core Classes](#core-classes)
|
||||
- [CardManager](#cardmanager)
|
||||
- [Card](#card)
|
||||
- [CardContainer](#cardcontainer)
|
||||
- [CardFactory](#cardfactory)
|
||||
- [JsonCardFactory](#jsoncardfactory)
|
||||
- [Specialized Containers](#specialized-containers)
|
||||
- [Pile](#pile)
|
||||
- [Hand](#hand)
|
||||
- [Supporting Classes](#supporting-classes)
|
||||
- [DraggableObject](#draggableobject)
|
||||
- [DropZone](#dropzone)
|
||||
- [HistoryElement](#historyelement)
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
### CardFrameworkSettings
|
||||
|
||||
**Extends:** `RefCounted`
|
||||
|
||||
Centralized configuration constants for all Card Framework components. This class provides consistent default values without requiring Autoload, allowing components to reference framework-wide constants directly.
|
||||
|
||||
#### Animation Constants
|
||||
|
||||
| Constant | Type | Value | Description |
|
||||
|----------|------|-------|-------------|
|
||||
| `ANIMATION_MOVE_SPEED` | `float` | `2000.0` | Speed of card movement animations in pixels per second |
|
||||
| `ANIMATION_HOVER_DURATION` | `float` | `0.10` | Duration of hover animations in seconds |
|
||||
| `ANIMATION_HOVER_SCALE` | `float` | `1.1` | Scale multiplier applied during hover effects |
|
||||
| `ANIMATION_HOVER_ROTATION` | `float` | `0.0` | Rotation in degrees applied during hover effects |
|
||||
|
||||
#### Physics Constants
|
||||
|
||||
| Constant | Type | Value | Description |
|
||||
|----------|------|-------|-------------|
|
||||
| `PHYSICS_HOVER_DISTANCE` | `float` | `10.0` | Distance threshold for hover detection in pixels |
|
||||
| `PHYSICS_CARD_HOVER_DISTANCE` | `float` | `30.0` | Distance cards move up during hover in pixels |
|
||||
|
||||
#### Visual Layout Constants
|
||||
|
||||
| Constant | Type | Value | Description |
|
||||
|----------|------|-------|-------------|
|
||||
| `VISUAL_DRAG_Z_OFFSET` | `int` | `1000` | Z-index offset applied to cards during drag operations |
|
||||
| `VISUAL_PILE_Z_INDEX` | `int` | `3000` | Z-index for pile cards to ensure proper layering |
|
||||
| `VISUAL_SENSOR_Z_INDEX` | `int` | `-1000` | Z-index for drop zone sensors (below everything) |
|
||||
| `VISUAL_OUTLINE_Z_INDEX` | `int` | `1200` | Z-index for debug outlines (above UI) |
|
||||
|
||||
#### Container Layout Constants
|
||||
|
||||
| Constant | Type | Value | Description |
|
||||
|----------|------|-------|-------------|
|
||||
| `LAYOUT_DEFAULT_CARD_SIZE` | `Vector2` | `Vector2(150, 210)` | Default card size used throughout the framework |
|
||||
| `LAYOUT_STACK_GAP` | `int` | `8` | Distance between stacked cards in piles |
|
||||
| `LAYOUT_MAX_STACK_DISPLAY` | `int` | `6` | Maximum cards to display in stack before hiding |
|
||||
| `LAYOUT_MAX_HAND_SIZE` | `int` | `10` | Maximum number of cards in hand containers |
|
||||
| `LAYOUT_MAX_HAND_SPREAD` | `int` | `700` | Maximum pixel spread for hand arrangements |
|
||||
|
||||
#### Debug Constants
|
||||
|
||||
| Constant | Type | Value | Description |
|
||||
|----------|------|-------|-------------|
|
||||
| `DEBUG_OUTLINE_COLOR` | `Color` | `Color(1, 0, 0, 1)` | Color used for sensor outlines and debug indicators |
|
||||
|
||||
#### Usage
|
||||
|
||||
```gdscript
|
||||
# Reference constants directly in component @export variables
|
||||
@export var moving_speed: int = CardFrameworkSettings.ANIMATION_MOVE_SPEED
|
||||
@export var hover_distance: int = CardFrameworkSettings.PHYSICS_HOVER_DISTANCE
|
||||
|
||||
# Or use in code
|
||||
z_index = stored_z_index + CardFrameworkSettings.VISUAL_DRAG_Z_OFFSET
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Core Classes
|
||||
|
||||
### CardManager
|
||||
|
||||
**Extends:** `Control`
|
||||
|
||||
The central orchestrator for all card game operations. Manages card containers, handles drag-and-drop operations, and maintains game history for undo functionality.
|
||||
|
||||
#### Properties
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `card_size` | `Vector2` | `Vector2(150, 210)` | Default size for all cards in the game |
|
||||
| `card_factory_scene` | `PackedScene` | - | Scene containing the CardFactory implementation |
|
||||
| `debug_mode` | `bool` | `false` | Enables visual debugging for drop zones |
|
||||
|
||||
#### Methods
|
||||
|
||||
##### undo() -> void
|
||||
Undoes the last card movement operation by restoring cards to their previous container.
|
||||
|
||||
```gdscript
|
||||
card_manager.undo()
|
||||
```
|
||||
|
||||
##### reset_history() -> void
|
||||
Clears all stored history elements, preventing further undo operations.
|
||||
|
||||
```gdscript
|
||||
card_manager.reset_history()
|
||||
```
|
||||
|
||||
#### Internal Methods
|
||||
|
||||
These methods are called automatically by the framework:
|
||||
|
||||
- `_add_card_container(id: int, card_container: CardContainer)` - Registers a container
|
||||
- `_delete_card_container(id: int)` - Unregisters a container
|
||||
- `_on_drag_dropped(cards: Array)` - Handles completed drag operations
|
||||
- `_add_history(to: CardContainer, cards: Array)` - Records movement for undo
|
||||
|
||||
---
|
||||
|
||||
### Card
|
||||
|
||||
**Extends:** `DraggableObject`
|
||||
|
||||
Represents an individual playing card with front/back faces and interaction capabilities.
|
||||
|
||||
#### Properties
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `card_name` | `String` | `""` | Unique identifier for the card |
|
||||
| `card_size` | `Vector2` | `Vector2(150, 210)` | Dimensions of the card |
|
||||
| `front_image` | `Texture2D` | - | Texture for card front face |
|
||||
| `back_image` | `Texture2D` | - | Texture for card back face |
|
||||
| `show_front` | `bool` | `true` | Whether front face is visible |
|
||||
|
||||
#### Variables
|
||||
|
||||
| Variable | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `card_info` | `Dictionary` | Additional card data from JSON |
|
||||
| `card_container` | `CardContainer` | Container currently holding this card |
|
||||
|
||||
#### Methods
|
||||
|
||||
##### set_faces(front_face: Texture2D, back_face: Texture2D) -> void
|
||||
Sets both front and back textures for the card.
|
||||
|
||||
```gdscript
|
||||
card.set_faces(front_texture, back_texture)
|
||||
```
|
||||
|
||||
##### return_card() -> void
|
||||
Returns card to its original position with no rotation.
|
||||
|
||||
```gdscript
|
||||
card.return_card()
|
||||
```
|
||||
|
||||
##### start_hovering() -> void
|
||||
Initiates hover effect, raising card visually and adjusting global hover count.
|
||||
|
||||
```gdscript
|
||||
card.start_hovering()
|
||||
```
|
||||
|
||||
##### end_hovering(restore_object_position: bool) -> void
|
||||
Ends hover effect and optionally restores position.
|
||||
|
||||
```gdscript
|
||||
card.end_hovering(true) # Restore position
|
||||
card.end_hovering(false) # Keep current position
|
||||
```
|
||||
|
||||
##### set_holding() -> void
|
||||
*[Deprecated]* Legacy method for setting holding state. Use state machine transitions instead.
|
||||
|
||||
```gdscript
|
||||
card.set_holding() # Put card into holding state
|
||||
```
|
||||
|
||||
##### get_string() -> String
|
||||
Returns string representation of the card for debugging.
|
||||
|
||||
```gdscript
|
||||
var card_info = card.get_string() # Returns card_name
|
||||
```
|
||||
|
||||
#### Static Variables
|
||||
|
||||
| Variable | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `hovering_card_count` | `int` | Global count of currently hovering cards |
|
||||
|
||||
---
|
||||
|
||||
### CardContainer
|
||||
|
||||
**Extends:** `Control`
|
||||
|
||||
Abstract base class for all card containers. Provides core functionality for holding, managing, and organizing cards with drag-and-drop support.
|
||||
|
||||
#### Drop Zone Properties
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `enable_drop_zone` | `bool` | `true` | Enables drop zone functionality |
|
||||
| `sensor_size` | `Vector2` | `Vector2(0, 0)` | Size of drop sensor (follows card_size if unset) |
|
||||
| `sensor_position` | `Vector2` | `Vector2(0, 0)` | Position offset for drop sensor |
|
||||
| `sensor_texture` | `Texture` | - | Visual texture for sensor (debugging) |
|
||||
| `sensor_visibility` | `bool` | `false` | Whether sensor is visible |
|
||||
|
||||
#### Variables
|
||||
|
||||
| Variable | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `unique_id` | `int` | Auto-generated unique identifier |
|
||||
| `cards_node` | `Control` | Node containing all card children |
|
||||
| `card_manager` | `CardManager` | Reference to parent CardManager |
|
||||
| `debug_mode` | `bool` | Debug mode state from CardManager |
|
||||
|
||||
#### Core Methods
|
||||
|
||||
##### add_card(card: Card, index: int = -1) -> void
|
||||
Adds a card to the container at specified index (-1 for end).
|
||||
|
||||
```gdscript
|
||||
container.add_card(my_card) # Add to end
|
||||
container.add_card(my_card, 0) # Add to beginning
|
||||
```
|
||||
|
||||
##### remove_card(card: Card) -> bool
|
||||
Removes a card from the container. Returns true if successful.
|
||||
|
||||
```gdscript
|
||||
var success = container.remove_card(my_card)
|
||||
```
|
||||
|
||||
##### has_card(card: Card) -> bool
|
||||
Checks if container holds the specified card.
|
||||
|
||||
```gdscript
|
||||
if container.has_card(my_card):
|
||||
print("Card is in this container")
|
||||
```
|
||||
|
||||
##### get_card_count() -> int
|
||||
Returns the number of cards currently in the container.
|
||||
|
||||
```gdscript
|
||||
var count = container.get_card_count()
|
||||
print("Container has %d cards" % count)
|
||||
```
|
||||
|
||||
##### clear_cards() -> void
|
||||
Removes all cards from the container.
|
||||
|
||||
```gdscript
|
||||
container.clear_cards()
|
||||
```
|
||||
|
||||
##### move_cards(cards: Array, index: int = -1, with_history: bool = true) -> bool
|
||||
Moves multiple cards to this container with optional history tracking.
|
||||
|
||||
```gdscript
|
||||
var cards_to_move = [card1, card2, card3]
|
||||
container.move_cards(cards_to_move, 0, true) # Move to beginning with history
|
||||
```
|
||||
|
||||
##### shuffle() -> void
|
||||
Randomly shuffles all cards in the container using Fisher-Yates algorithm.
|
||||
|
||||
```gdscript
|
||||
deck_container.shuffle()
|
||||
```
|
||||
|
||||
##### undo(cards: Array, from_indices: Array = []) -> void
|
||||
Restores cards to their original positions with index precision. Supports both simple restoration and precise index-based positioning for complex undo scenarios.
|
||||
|
||||
**Parameters:**
|
||||
- `cards`: Array of cards to restore to this container
|
||||
- `from_indices`: Optional array of original indices for precise positioning (since v1.1.4)
|
||||
|
||||
**Features:**
|
||||
- **Adaptive Algorithm**: Automatically detects consecutive vs non-consecutive card groups
|
||||
- **Order Preservation**: Maintains correct card order for bulk consecutive moves
|
||||
- **Fallback Safety**: Gracefully handles missing or invalid index data
|
||||
|
||||
```gdscript
|
||||
# Simple undo (backward compatible)
|
||||
source_container.undo([card1, card2])
|
||||
|
||||
# Precise index-based undo (new in v1.1.4)
|
||||
source_container.undo([card1, card2, card3], [0, 1, 2])
|
||||
|
||||
# Handles complex scenarios automatically
|
||||
hand_container.undo(moved_cards, original_indices)
|
||||
```
|
||||
|
||||
#### Drop Zone Methods
|
||||
|
||||
##### check_card_can_be_dropped(cards: Array) -> bool
|
||||
Determines if the provided cards can be dropped into this container.
|
||||
|
||||
```gdscript
|
||||
if container.check_card_can_be_dropped([my_card]):
|
||||
# Cards can be dropped here
|
||||
```
|
||||
|
||||
##### get_partition_index() -> int
|
||||
Gets the drop partition index based on mouse position. Returns -1 if no partitioning.
|
||||
|
||||
```gdscript
|
||||
var drop_index = container.get_partition_index()
|
||||
```
|
||||
|
||||
#### Event Handlers
|
||||
|
||||
##### on_card_move_done(_card: Card) -> void
|
||||
Called when a card finishes moving. Override in subclasses for custom behavior.
|
||||
|
||||
```gdscript
|
||||
func on_card_move_done(card: Card):
|
||||
print("Card movement completed: ", card.card_name)
|
||||
```
|
||||
|
||||
##### on_card_pressed(_card: Card) -> void
|
||||
Called when a card in this container is pressed. Override for custom behavior.
|
||||
|
||||
```gdscript
|
||||
func on_card_pressed(card: Card):
|
||||
print("Card pressed: ", card.card_name)
|
||||
```
|
||||
|
||||
#### Utility Methods
|
||||
|
||||
##### hold_card(card: Card) -> void
|
||||
Puts a card into holding state, preparing it for drag operations.
|
||||
|
||||
```gdscript
|
||||
container.hold_card(my_card) # Put card into holding state
|
||||
```
|
||||
|
||||
##### get_string() -> String
|
||||
Returns string representation for debugging.
|
||||
|
||||
```gdscript
|
||||
print(container.get_string()) # "card_container: 1"
|
||||
```
|
||||
|
||||
#### Abstract Methods
|
||||
|
||||
These methods should be overridden in subclasses:
|
||||
|
||||
##### update_card_ui() -> void
|
||||
Updates visual positioning and appearance of all cards.
|
||||
|
||||
##### _card_can_be_added(_cards: Array) -> bool
|
||||
Returns true if the specified cards can be added to this container. Base implementation always returns true.
|
||||
|
||||
##### _update_target_positions() -> void
|
||||
Calculates and applies target positions for all cards.
|
||||
|
||||
##### _update_target_z_index() -> void
|
||||
Updates Z-index layering for all cards.
|
||||
|
||||
---
|
||||
|
||||
### CardFactory
|
||||
|
||||
**Extends:** `Node`
|
||||
|
||||
Abstract base class for creating cards. Implement this class to define custom card creation logic.
|
||||
|
||||
#### Variables
|
||||
|
||||
| Variable | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `preloaded_cards` | `Dictionary` | Cache for card data to improve performance |
|
||||
| `card_size` | `Vector2` | Size to apply to created cards |
|
||||
|
||||
#### Abstract Methods
|
||||
|
||||
##### create_card(card_name: String, target: CardContainer) -> Card
|
||||
Creates and returns a new card instance. Must be implemented by subclasses.
|
||||
|
||||
```gdscript
|
||||
# In your custom factory:
|
||||
func create_card(card_name: String, target: CardContainer) -> Card:
|
||||
var new_card = card_scene.instantiate()
|
||||
# Configure card...
|
||||
return new_card
|
||||
```
|
||||
|
||||
##### preload_card_data() -> void
|
||||
Preloads card data for improved performance. Called automatically by CardManager.
|
||||
|
||||
```gdscript
|
||||
func preload_card_data() -> void:
|
||||
# Load and cache card data
|
||||
pass
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### JsonCardFactory
|
||||
|
||||
**Extends:** `CardFactory`
|
||||
|
||||
Concrete implementation of CardFactory that creates cards from JSON metadata and image assets.
|
||||
|
||||
#### Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `default_card_scene` | `PackedScene` | Base card scene to instantiate |
|
||||
| `card_asset_dir` | `String` | Directory containing card image files |
|
||||
| `card_info_dir` | `String` | Directory containing JSON card definitions |
|
||||
| `back_image` | `Texture2D` | Common back face texture for all cards |
|
||||
|
||||
#### Methods
|
||||
|
||||
##### create_card(card_name: String, target: CardContainer) -> Card
|
||||
Creates a card from JSON data and image assets.
|
||||
|
||||
```gdscript
|
||||
var my_card = factory.create_card("ace_of_spades", target_container)
|
||||
```
|
||||
|
||||
The factory looks for:
|
||||
- JSON file: `{card_info_dir}/{card_name}.json`
|
||||
- Image file: `{card_asset_dir}/{front_image}` (from JSON)
|
||||
|
||||
#### JSON Card Format
|
||||
|
||||
Cards are defined using JSON files with the following structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "ace_of_spades",
|
||||
"front_image": "cardSpadesA.png",
|
||||
"suit": "spades",
|
||||
"value": "A",
|
||||
"custom_property": "additional_data"
|
||||
}
|
||||
```
|
||||
|
||||
**Required fields:**
|
||||
- `front_image`: Filename of the card's front face image
|
||||
|
||||
**Optional fields:**
|
||||
- `name`: Display name for the card
|
||||
- Any additional properties for game-specific logic
|
||||
|
||||
---
|
||||
|
||||
## Specialized Containers
|
||||
|
||||
### Pile
|
||||
|
||||
**Extends:** `CardContainer`
|
||||
|
||||
A container that stacks cards in a pile formation with configurable direction and display options.
|
||||
|
||||
#### Enums
|
||||
|
||||
```gdscript
|
||||
enum PileDirection {
|
||||
UP, # Cards stack upward
|
||||
DOWN, # Cards stack downward
|
||||
LEFT, # Cards stack leftward
|
||||
RIGHT # Cards stack rightward
|
||||
}
|
||||
```
|
||||
|
||||
#### Properties
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `stack_display_gap` | `int` | `8` | Pixel distance between cards in stack |
|
||||
| `max_stack_display` | `int` | `6` | Maximum cards to show stacked |
|
||||
| `card_face_up` | `bool` | `true` | Whether cards show front face |
|
||||
| `layout` | `PileDirection` | `UP` | Direction to stack cards |
|
||||
| `allow_card_movement` | `bool` | `true` | Whether cards can be moved |
|
||||
| `restrict_to_top_card` | `bool` | `true` | Only top card is interactive |
|
||||
| `align_drop_zone_with_top_card` | `bool` | `true` | Drop zone follows top card |
|
||||
|
||||
#### Methods
|
||||
|
||||
##### get_top_cards(n: int) -> Array
|
||||
Returns the top N cards from the pile.
|
||||
|
||||
```gdscript
|
||||
var top_three = pile.get_top_cards(3) # Get top 3 cards
|
||||
var top_card = pile.get_top_cards(1)[0] # Get just the top card
|
||||
```
|
||||
|
||||
#### Usage Example
|
||||
|
||||
```gdscript
|
||||
# Create a deck pile
|
||||
@export var deck_pile: Pile
|
||||
|
||||
func _ready():
|
||||
deck_pile.layout = Pile.PileDirection.UP
|
||||
deck_pile.card_face_up = false # Cards face down
|
||||
deck_pile.restrict_to_top_card = true
|
||||
|
||||
# Add cards to deck
|
||||
for card_name in card_names:
|
||||
var card = card_factory.create_card(card_name, deck_pile)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Hand
|
||||
|
||||
**Extends:** `CardContainer`
|
||||
|
||||
A container that displays cards in a fan-like hand formation with curves and spacing.
|
||||
|
||||
#### Properties
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `max_hand_size` | `int` | `10` | Maximum cards that can be held |
|
||||
| `max_hand_spread` | `int` | `700` | Maximum pixel spread of hand |
|
||||
| `card_face_up` | `bool` | `true` | Whether cards show front face |
|
||||
| `card_hover_distance` | `int` | `30` | Distance cards hover when interacted with |
|
||||
|
||||
#### Curve Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `hand_rotation_curve` | `Curve` | Controls rotation of cards across hand |
|
||||
| `hand_vertical_curve` | `Curve` | Controls vertical positioning of cards |
|
||||
|
||||
#### Drop Zone Properties
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `align_drop_zone_size_with_current_hand_size` | `bool` | `true` | Drop zone adapts to hand size |
|
||||
| `swap_only_on_reorder` | `bool` | `false` | Reordering swaps positions instead of shifting |
|
||||
|
||||
#### Methods
|
||||
|
||||
##### get_random_cards(n: int) -> Array
|
||||
Returns N random cards from the hand without removing them.
|
||||
|
||||
```gdscript
|
||||
var random_cards = hand.get_random_cards(3)
|
||||
```
|
||||
|
||||
##### move_cards(cards: Array, index: int = -1, with_history: bool = true) -> bool
|
||||
Enhanced version of CardContainer.move_cards() with hand-specific optimizations:
|
||||
- **Single Card Reordering**: Optimized reordering when moving cards within same hand
|
||||
- **Swap Mode**: Uses swap_card() when `swap_only_on_reorder` is enabled
|
||||
- **Fallback**: Uses parent implementation for external card moves
|
||||
|
||||
```gdscript
|
||||
# Move card to specific position in hand
|
||||
hand.move_cards([my_card], 2) # Move to index 2
|
||||
|
||||
# External card move (uses parent implementation)
|
||||
hand.move_cards([external_card], -1) # Add external card to end
|
||||
```
|
||||
|
||||
##### swap_card(card: Card, index: int) -> void
|
||||
Swaps a card with the card at the specified index.
|
||||
|
||||
```gdscript
|
||||
hand.swap_card(my_card, 0) # Move card to first position
|
||||
```
|
||||
|
||||
#### Usage Example
|
||||
|
||||
```gdscript
|
||||
# Configure hand curves
|
||||
@export var hand: Hand
|
||||
|
||||
func _ready():
|
||||
# Create rotation curve: -30° to +30°
|
||||
hand.hand_rotation_curve = Curve.new()
|
||||
hand.hand_rotation_curve.add_point(0.0, -30.0)
|
||||
hand.hand_rotation_curve.add_point(1.0, 30.0)
|
||||
|
||||
# Create vertical curve: arc shape
|
||||
hand.hand_vertical_curve = Curve.new()
|
||||
hand.hand_vertical_curve.add_point(0.0, 0.0)
|
||||
hand.hand_vertical_curve.add_point(0.5, 50.0) # Peak in middle
|
||||
hand.hand_vertical_curve.add_point(1.0, 0.0)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Supporting Classes
|
||||
|
||||
### DraggableObject
|
||||
|
||||
**Extends:** `Control`
|
||||
|
||||
State machine-based drag-and-drop system with Tween animations. Provides robust interaction handling with safe state transitions and smooth visual feedback.
|
||||
|
||||
#### Enums
|
||||
|
||||
##### DraggableState
|
||||
Defines possible interaction states with controlled transitions.
|
||||
|
||||
| State | Description |
|
||||
|-------|-------------|
|
||||
| `IDLE` | Default state - ready for interaction |
|
||||
| `HOVERING` | Mouse over with visual feedback |
|
||||
| `HOLDING` | Active drag state following mouse |
|
||||
| `MOVING` | Programmatic movement ignoring input |
|
||||
|
||||
#### Properties
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `moving_speed` | `int` | `2000` | Speed of programmatic movement (pixels/second) |
|
||||
| `can_be_interacted_with` | `bool` | `true` | Whether object responds to input |
|
||||
| `hover_distance` | `int` | `10` | Distance to hover when interacted with |
|
||||
| `hover_scale` | `float` | `1.1` | Scale multiplier when hovering |
|
||||
| `hover_rotation` | `float` | `0.0` | Rotation in degrees when hovering |
|
||||
| `hover_duration` | `float` | `0.10` | Duration for hover animations |
|
||||
|
||||
#### State Management
|
||||
|
||||
| Variable | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `current_state` | `DraggableState` | Current interaction state |
|
||||
| `is_pressed` | `bool` | Legacy compatibility - mouse pressed |
|
||||
| `is_holding` | `bool` | Legacy compatibility - being dragged |
|
||||
| `stored_z_index` | `int` | Original Z-index before interactions |
|
||||
|
||||
#### Methods
|
||||
|
||||
##### move(target_destination: Vector2, degree: float) -> void
|
||||
Moves object to target position with optional rotation using smooth Tween animation. Automatically transitions to MOVING state.
|
||||
|
||||
```gdscript
|
||||
draggable.move(new_position, deg_to_rad(45)) # Move with 45° rotation
|
||||
draggable.move(Vector2(100, 200), 0) # Move without rotation
|
||||
```
|
||||
|
||||
##### return_to_original() -> void
|
||||
Returns the object to its original position with smooth animation. Sets internal tracking flag for proper position management.
|
||||
|
||||
```gdscript
|
||||
draggable.return_to_original() # Return to original position and rotation
|
||||
```
|
||||
|
||||
##### change_state(new_state: DraggableState) -> bool
|
||||
Safely transitions between interaction states using predefined rules. Returns true if transition was successful.
|
||||
|
||||
```gdscript
|
||||
# Manual state transitions
|
||||
if draggable.change_state(DraggableObject.DraggableState.HOVERING):
|
||||
print("Now hovering")
|
||||
|
||||
# State machine prevents invalid transitions
|
||||
draggable.change_state(DraggableObject.DraggableState.MOVING) # Force to MOVING
|
||||
```
|
||||
|
||||
**State Transition Rules:**
|
||||
- `IDLE` → `HOVERING`, `HOLDING`, `MOVING`
|
||||
- `HOVERING` → `IDLE`, `HOLDING`, `MOVING`
|
||||
- `HOLDING` → `IDLE`, `MOVING`
|
||||
- `MOVING` → `IDLE`
|
||||
|
||||
#### Virtual Methods
|
||||
|
||||
##### _on_move_done() -> void
|
||||
Called when movement animation completes. Override in subclasses for custom behavior.
|
||||
|
||||
```gdscript
|
||||
func _on_move_done():
|
||||
print("Movement finished")
|
||||
# Custom post-movement logic
|
||||
```
|
||||
|
||||
##### _can_start_hovering() -> bool
|
||||
Virtual method to determine if hovering animation can start. Override for custom conditions.
|
||||
|
||||
```gdscript
|
||||
func _can_start_hovering() -> bool:
|
||||
return not is_card_locked # Example: prevent hover if locked
|
||||
```
|
||||
|
||||
#### Animation System
|
||||
|
||||
The new Tween-based animation system provides:
|
||||
- **Smooth Transitions**: All state changes use smooth animations
|
||||
- **Memory Management**: Proper cleanup of animation resources
|
||||
- **Interrupt Handling**: Safe animation interruption and cleanup
|
||||
- **Performance**: Optimized for multiple simultaneous animations
|
||||
|
||||
---
|
||||
|
||||
### DropZone
|
||||
|
||||
**Extends:** `Control`
|
||||
|
||||
Handles drop detection and partitioning for card containers.
|
||||
|
||||
#### Properties
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `sensor_size` | `Vector2` | Size of the drop detection area |
|
||||
| `sensor_position` | `Vector2` | Position offset of the sensor |
|
||||
| `sensor_texture` | `Texture` | Visual texture for debugging |
|
||||
| `sensor_visible` | `bool` | Whether sensor is visible |
|
||||
| `sensor_outline_visible` | `bool` | Whether debug outline is visible |
|
||||
| `accept_types` | `Array` | Array of acceptable drop types |
|
||||
|
||||
#### Variables
|
||||
|
||||
| Variable | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `vertical_partition` | `Array` | Global X coordinates for vertical partitions |
|
||||
| `horizontal_partition` | `Array` | Global Y coordinates for horizontal partitions |
|
||||
|
||||
#### Methods
|
||||
|
||||
##### init(_parent: Node, accept_types: Array = []) -> void
|
||||
Initializes the drop zone with parent reference and accepted types.
|
||||
|
||||
```gdscript
|
||||
drop_zone.init(self, ["card"])
|
||||
```
|
||||
|
||||
##### check_mouse_is_in_drop_zone() -> bool
|
||||
Returns true if mouse cursor is within the drop zone area.
|
||||
|
||||
```gdscript
|
||||
if drop_zone.check_mouse_is_in_drop_zone():
|
||||
# Mouse is over drop zone
|
||||
```
|
||||
|
||||
##### set_sensor(_size: Vector2, _position: Vector2, _texture: Texture, _visible: bool) -> void
|
||||
Configures the drop sensor properties.
|
||||
|
||||
```gdscript
|
||||
drop_zone.set_sensor(Vector2(200, 300), Vector2(10, 10), null, false)
|
||||
```
|
||||
|
||||
##### set_vertical_partitions(positions: Array) -> void
|
||||
Sets vertical partition lines for precise drop positioning.
|
||||
|
||||
```gdscript
|
||||
drop_zone.set_vertical_partitions([100, 200, 300]) # Three partition lines
|
||||
```
|
||||
|
||||
##### set_horizontal_partitions(positions: Array) -> void
|
||||
Sets horizontal partition lines for precise drop positioning.
|
||||
|
||||
```gdscript
|
||||
drop_zone.set_horizontal_partitions([50, 150, 250]) # Three partition lines
|
||||
```
|
||||
|
||||
##### get_vertical_layers() -> int
|
||||
Returns the vertical partition index under the mouse cursor.
|
||||
|
||||
```gdscript
|
||||
var partition = drop_zone.get_vertical_layers()
|
||||
if partition != -1:
|
||||
print("Dropping in partition: ", partition)
|
||||
```
|
||||
|
||||
##### get_horizontal_layers() -> int
|
||||
Returns the horizontal partition index under the mouse cursor.
|
||||
|
||||
---
|
||||
|
||||
### HistoryElement
|
||||
|
||||
**Extends:** `Object`
|
||||
|
||||
Represents a single card movement operation for undo functionality.
|
||||
|
||||
#### Variables
|
||||
|
||||
| Variable | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `from` | `CardContainer` | Source container |
|
||||
| `to` | `CardContainer` | Destination container |
|
||||
| `cards` | `Array` | Array of cards that were moved |
|
||||
|
||||
#### Methods
|
||||
|
||||
##### get_string() -> String
|
||||
Returns string representation for debugging.
|
||||
|
||||
```gdscript
|
||||
var history_info = history_element.get_string()
|
||||
# Returns: "from: [container_1], to: [container_2], cards: [ace_of_spades, king_of_hearts]"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Usage Patterns
|
||||
|
||||
### Basic Setup
|
||||
|
||||
```gdscript
|
||||
# Scene structure:
|
||||
# CardManager (CardManager)
|
||||
# ├── DeckPile (Pile)
|
||||
# ├── PlayerHand (Hand)
|
||||
# └── DiscardPile (Pile)
|
||||
|
||||
@onready var card_manager: CardManager = $CardManager
|
||||
@onready var deck: Pile = $CardManager/DeckPile
|
||||
@onready var hand: Hand = $CardManager/PlayerHand
|
||||
|
||||
func _ready():
|
||||
# Cards are automatically managed by CardManager
|
||||
deal_initial_cards()
|
||||
|
||||
func deal_initial_cards():
|
||||
var cards_to_deal = deck.get_top_cards(7)
|
||||
hand.move_cards(cards_to_deal)
|
||||
```
|
||||
|
||||
### Custom Container
|
||||
|
||||
```gdscript
|
||||
class_name CustomPile
|
||||
extends CardContainer
|
||||
|
||||
@export var max_cards: int = 5
|
||||
|
||||
func _card_can_be_added(cards: Array) -> bool:
|
||||
return _held_cards.size() + cards.size() <= max_cards
|
||||
|
||||
func _update_target_positions():
|
||||
for i in range(_held_cards.size()):
|
||||
var card = _held_cards[i]
|
||||
var offset = Vector2(i * 20, i * 5) # Slight offset for each card
|
||||
card.move(global_position + offset, 0)
|
||||
```
|
||||
|
||||
### Custom Card Factory
|
||||
|
||||
```gdscript
|
||||
class_name MyCardFactory
|
||||
extends CardFactory
|
||||
|
||||
@export var custom_card_scene: PackedScene
|
||||
|
||||
func create_card(card_name: String, target: CardContainer) -> Card:
|
||||
var card = custom_card_scene.instantiate()
|
||||
card.card_name = card_name
|
||||
# Custom card setup logic
|
||||
return card
|
||||
|
||||
func preload_card_data():
|
||||
# Custom preloading logic
|
||||
pass
|
||||
```
|
||||
|
||||
This API reference provides complete documentation for all public methods and properties in the Card Framework. For implementation examples, see the included example projects and the FreeCell game demonstration.
|
||||
171
docs/CHANGELOG.md
Normal file
171
docs/CHANGELOG.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to Card Framework will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.2.3] - 2025-09-23
|
||||
|
||||
### Fixed
|
||||
- **Mouse Interaction**: Fixed "dead cards" bug where rapid clicks made cards unresponsive ([#22](https://github.com/chun92/card-framework/issues/22))
|
||||
|
||||
## [1.2.2] - 2025-08-23
|
||||
|
||||
### Added
|
||||
- **CardContainer API**: Added `get_card_count()` method to return the number of cards in a container
|
||||
|
||||
### Fixed
|
||||
- **CardFactory Configuration**: Set proper JsonCardFactory defaults in `card_factory.tscn`
|
||||
|
||||
### Improved
|
||||
- **Documentation**: Enhanced API reference with missing methods and corrected code examples
|
||||
- **Getting Started**: Fixed code formatting and updated examples to use current API patterns
|
||||
- **Code Examples**: Standardized API usage across all documentation and README files
|
||||
|
||||
### Contributors
|
||||
- **Community**: Documentation improvements by @psin09
|
||||
|
||||
## [1.2.1] - 2025-08-19
|
||||
|
||||
### Refactored
|
||||
- **DraggableObject API Enhancement**: Added `return_to_original()` method to base class for improved code reusability
|
||||
- **Card API Simplification**: `Card.return_card()` now uses inherited `return_to_original()` wrapper pattern for better maintainability
|
||||
|
||||
## [1.2.0] - 2025-08-14
|
||||
|
||||
### Added
|
||||
- **CardFrameworkSettings**: Centralized configuration constants for all framework values
|
||||
- **State Machine System**: Complete rewrite of DraggableObject with robust state management
|
||||
- **Tween Animation System**: Smooth, interruptible animations replacing _process-based movement
|
||||
- **Precise Undo System**: Index-based undo with adaptive algorithm for correct card ordering
|
||||
- **Comprehensive Documentation**: Full GDScript style guide compliance with detailed API docs
|
||||
|
||||
### Changed
|
||||
- **BREAKING**: `CardContainer.undo()` method signature now includes optional `from_indices` parameter
|
||||
- **Magic Numbers**: All hardcoded values replaced with `CardFrameworkSettings` constants
|
||||
- **Animation System**: All movement and hover effects now use Tween-based animations
|
||||
- **State Management**: Drag-and-drop interactions now use validated state machine transitions
|
||||
- **Memory Management**: Improved Tween resource cleanup preventing memory leaks
|
||||
|
||||
### Fixed
|
||||
- **Multi-Card Undo Ordering**: Resolved card sequence corruption when undoing consecutive multi-card moves
|
||||
- **Tween Memory Leaks**: Proper cleanup of animation resources in DraggableObject
|
||||
- **Mouse Interaction**: Resolved various mouse control issues after card movements
|
||||
- **Hover Animation**: Fixed scale accumulation bug preventing proper hover reset
|
||||
- **Z-Index Management**: Foundation cards maintain proper z-index after auto-move completion
|
||||
- **Hand Reordering**: Optimized internal reordering to prevent card position drift
|
||||
|
||||
### Developer Experience
|
||||
- **MCP Integration**: Added Claude Code and TaskMaster AI integration for development workflow
|
||||
- **Documentation Tools**: Custom Claude commands for automated documentation sync
|
||||
- **Code Quality**: Applied comprehensive GDScript style guide with detailed method documentation
|
||||
|
||||
## [1.1.3] - 2025-07-10
|
||||
|
||||
### Added
|
||||
- **Debug Mode**: Visual debugging support in `CardManager` with `debug_mode` flag
|
||||
- **Drop Zone Visualization**: Reference guides matching Sensor Drop Zone size for debugging
|
||||
- **Swap Reordering**: `swap_only_on_reorder` flag in `Hand` for alternative card reordering behavior
|
||||
|
||||
### Changed
|
||||
- **Reordering Behavior**: `Hand` now supports both shifting (default) and swapping modes
|
||||
- **History Optimization**: Moves within the same `CardContainer` no longer recorded in history
|
||||
|
||||
### Deprecated
|
||||
- `sensor_visibility` property in `CardContainer` (use `debug_mode` in `CardManager`)
|
||||
- `sensor_texture` property in `CardContainer` (replaced by automatic debug visualization)
|
||||
|
||||
### Fixed
|
||||
- **Mouse Control**: Resolved inconsistent mouse control when adding cards to `CardContainer` at specific index
|
||||
- **Performance**: Improved reliability of card positioning and interaction handling
|
||||
|
||||
## [1.1.2] - 2025-06-20
|
||||
|
||||
### Added
|
||||
- **DraggableObject System**: Separated drag-and-drop functionality from `Card` class
|
||||
- **Enhanced DropZone**: `accept_type` property for broader compatibility beyond `CardContainer`
|
||||
- **Runtime Drop Zone Control**: Dynamic enable/disable of drop zones during gameplay
|
||||
|
||||
### Changed
|
||||
- **Architecture**: Drag-and-drop now inheritable by any object via `DraggableObject`
|
||||
- **Flexibility**: `DropZone` usable for non-card objects with type filtering
|
||||
|
||||
### Fixed
|
||||
- **Hand Reordering**: Cards in full `Hand` containers can now be properly reordered
|
||||
- **Drop Zone Reliability**: Improved drop zone detection and interaction handling
|
||||
|
||||
## [1.1.1] - 2025-06-06
|
||||
|
||||
### Fixed
|
||||
- **Card Sizing**: Critical fix for `card_size` property not applying correctly
|
||||
- **Visual Consistency**: Cards now properly respect configured size settings
|
||||
|
||||
## [1.1.0] - 2025-06-02
|
||||
|
||||
### Added
|
||||
- **Enhanced Hand Functionality**: Card reordering within hands via drag-and-drop
|
||||
- **JsonCardFactory**: Separated card creation logic for better extensibility
|
||||
- **Improved Architecture**: Generic `CardFactory` base class for custom implementations
|
||||
|
||||
### Changed
|
||||
- **Factory Pattern**: Refactored card creation system with abstract `CardFactory`
|
||||
- **Drop Zone Logic**: Significantly improved drop zone handling and reliability
|
||||
- **Code Organization**: Better separation of concerns between factory types
|
||||
|
||||
### Improved
|
||||
- **Extensibility**: Easier to create custom card factories for different data sources
|
||||
- **Reliability**: More robust card movement and container interactions
|
||||
|
||||
## [1.0.0] - 2025-01-03
|
||||
|
||||
### Added
|
||||
- **Initial Release**: Complete Card Framework for Godot 4.x
|
||||
- **Core Classes**: `CardManager`, `Card`, `CardContainer`, `Pile`, `Hand`
|
||||
- **Drag & Drop System**: Intuitive card interactions with validation
|
||||
- **JSON Card Support**: Data-driven card creation and configuration
|
||||
- **Sample Projects**: `example1` demonstration and complete `freecell` game
|
||||
- **Flexible Architecture**: Extensible base classes for custom game types
|
||||
|
||||
### Features
|
||||
- **Card Management**: Creation, movement, and lifecycle management
|
||||
- **Container System**: Specialized containers for different card layouts
|
||||
- **Visual System**: Animations, hover effects, and visual feedback
|
||||
- **Game Logic**: Move history, undo functionality, and rule validation
|
||||
- **Asset Integration**: Image loading and JSON data parsing
|
||||
|
||||
---
|
||||
|
||||
## Version Support
|
||||
|
||||
| Version | Godot Support | Status | EOL Date |
|
||||
|---------|---------------|--------|----------|
|
||||
| 1.1.x | 4.4+ | Active | - |
|
||||
| 1.0.x | 4.0-4.3 | Legacy | 2025-12-31 |
|
||||
|
||||
## Upgrade Guide
|
||||
|
||||
### 1.1.2 → 1.1.3
|
||||
- **Optional**: Enable `debug_mode` in `CardManager` for development
|
||||
- **Deprecated**: Update any usage of `sensor_visibility` and `sensor_texture`
|
||||
- **New Feature**: Consider `swap_only_on_reorder` for different hand behavior
|
||||
|
||||
### 1.1.1 → 1.1.2
|
||||
- **Breaking**: Review custom drag-and-drop implementations
|
||||
- **Migration**: Update to use `DraggableObject` base class if extending drag functionality
|
||||
- **Enhancement**: Utilize new `accept_type` in `DropZone` for type filtering
|
||||
|
||||
### 1.1.0 → 1.1.1
|
||||
- **Fix**: No code changes required, automatic improvement for card sizing
|
||||
|
||||
### 1.0.x → 1.1.0
|
||||
- **Migration**: Update `CardFactory` references to `JsonCardFactory` if using custom factories
|
||||
- **Enhancement**: Take advantage of improved hand reordering functionality
|
||||
- **Testing**: Verify drop zone interactions work correctly with improvements
|
||||
|
||||
## Contributing
|
||||
|
||||
See [Contributing Guidelines](../README.md#contributing) for information on reporting issues and contributing improvements.
|
||||
|
||||
## License
|
||||
|
||||
This project is open source. See [License](../README.md#license--credits) for details.
|
||||
254
docs/GETTING_STARTED.md
Normal file
254
docs/GETTING_STARTED.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# Getting Started with Card Framework
|
||||
|
||||
Complete step-by-step guide to set up and use the Card Framework in your Godot 4.x projects.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Godot Engine 4.4+** installed
|
||||
- Basic knowledge of Godot scenes and nodes
|
||||
- Understanding of GDScript fundamentals
|
||||
|
||||
## Installation Methods
|
||||
|
||||
### Method 1: AssetLib Installation (Recommended)
|
||||
|
||||
1. **Open Godot Editor** and create or open your project
|
||||
2. **Navigate to AssetLib** tab in the main editor
|
||||
3. **Search** for "Card Framework"
|
||||
4. **Download** and import the latest version
|
||||
5. **Verify Installation** - Check `res://addons/card-framework/` exists
|
||||
|
||||
### Method 2: Manual Installation
|
||||
|
||||
1. **Download** Card Framework from the repository
|
||||
2. **Extract** the contents to your project
|
||||
3. **Copy** the `addons/card-framework/` folder to `res://addons/`
|
||||
4. **Refresh** the FileSystem dock in Godot
|
||||
|
||||
## Project Setup
|
||||
|
||||
### Step 1: Scene Structure
|
||||
|
||||
Create your main game scene with this hierarchy:
|
||||
```
|
||||
Main (Node2D)
|
||||
└── CardManager (CardManager)
|
||||
├── Deck (Pile)
|
||||
├── PlayerHand (Hand)
|
||||
└── DiscardPile (Pile)
|
||||
```
|
||||
|
||||
### Step 2: CardManager Configuration
|
||||
|
||||
1. **Add CardManager Scene**
|
||||
- In your main scene, **Add Child Node**
|
||||
- **Instance** `res://addons/card-framework/card_manager.tscn`
|
||||
|
||||
2. **Configure Basic Properties**
|
||||
```
|
||||
Card Size: (150, 210) # Standard playing card dimensions
|
||||
Debug Mode: false # Enable for development
|
||||
```
|
||||
|
||||
3. **Create Your Card Factory**
|
||||
Instead of using the card factory directly, create your own:
|
||||
|
||||
**Option A: Inherit from JsonCardFactory (Recommended)**
|
||||
- **Create New Scene** → **Add Node** → **JsonCardFactory**
|
||||
- **Save** as `res://scenes/my_card_factory.tscn`
|
||||
- **Set** `card_factory_scene` to `res://scenes/my_card_factory.tscn`
|
||||
|
||||
**Option B: Create Custom Factory**
|
||||
- **Create New Scene** → **Add Node** → **CardFactory**
|
||||
- **Attach Script** and implement `create_card()` method
|
||||
- **Save** as `res://scenes/my_card_factory.tscn`
|
||||
|
||||
### Step 3: Directory Structure Setup
|
||||
|
||||
Create this folder structure in your project:
|
||||
```
|
||||
res://
|
||||
├── cards/
|
||||
│ ├── images/ # Card artwork
|
||||
│ └── data/ # JSON card definitions
|
||||
└── scenes/
|
||||
└── main.tscn # Your main scene
|
||||
```
|
||||
|
||||
### Step 4: Card Assets Preparation
|
||||
|
||||
#### 4.1 Card Images
|
||||
- **Format**: PNG recommended (supports transparency)
|
||||
- **Size**: 150x210 pixels for standard cards
|
||||
- **Naming**: Use descriptive names (e.g., `cardClubs2.png`, `cardHeartsK.png`)
|
||||
- **Location**: Store in `res://cards/images/`
|
||||
|
||||
#### 4.2 Card Data Files
|
||||
Create JSON files in `res://cards/data/` for each card:
|
||||
|
||||
**Example: `club_2.json`**
|
||||
```json
|
||||
{
|
||||
"name": "club_2",
|
||||
"front_image": "cardClubs2.png",
|
||||
"suit": "club",
|
||||
"value": "2",
|
||||
"color": "black"
|
||||
}
|
||||
```
|
||||
|
||||
**Required Fields**:
|
||||
- `name` - Unique identifier for the card
|
||||
- `front_image` - Filename of the card's front texture
|
||||
|
||||
**Optional Fields**:
|
||||
- Add any custom properties needed for your game logic
|
||||
|
||||
### Step 5: Card Factory Configuration
|
||||
|
||||
**If using JsonCardFactory (Option A from Step 2):**
|
||||
|
||||
Open your `my_card_factory.tscn` scene and configure the JsonCardFactory node:
|
||||
|
||||
```
|
||||
Card Asset Dir: "res://cards/images/"
|
||||
Card Info Dir: "res://cards/data/"
|
||||
Back Image: [Assign a card back texture]
|
||||
Default Card Scene: [Assign custom card scene - required field]
|
||||
```
|
||||
|
||||
**If using Custom Factory (Option B):**
|
||||
- Implement your own card creation logic in the attached script
|
||||
- No additional configuration needed here
|
||||
|
||||
### Step 6: Container Setup
|
||||
|
||||
#### 6.1 Adding Containers
|
||||
|
||||
Add container nodes as children of CardManager:
|
||||
|
||||
1. **Right-click** CardManager in Scene dock
|
||||
2. **Add Child** → Choose container type:
|
||||
- `Pile` for stacked cards (decks, discard piles)
|
||||
- `Hand` for fanned card layouts (player hands)
|
||||
3. **Position Containers**
|
||||
- Select each container in the Scene dock
|
||||
- In **Inspector** → **Transform** → **Position**, set appropriate coordinates:
|
||||
- Example: Deck at (100, 300), PlayerHand at (400, 500), DiscardPile at (700, 300)
|
||||
- Adjust positions based on your game screen size and layout needs
|
||||
|
||||
#### 6.2 Pile Configuration
|
||||
|
||||
**Basic Properties**:
|
||||
```
|
||||
Enable Drop Zone: true
|
||||
Card Face Up: false # For deck, true for discard
|
||||
Layout: UP # Stack direction
|
||||
Allow Card Movement: true
|
||||
Restrict To Top Card: true # Only top card moveable
|
||||
```
|
||||
|
||||
**Visual Properties**:
|
||||
```
|
||||
Stack Display Gap: 8 # Pixel spacing between cards
|
||||
Max Stack Display: 6 # Maximum visible cards
|
||||
```
|
||||
|
||||
#### 6.3 Hand Configuration
|
||||
|
||||
**Layout Properties**:
|
||||
```
|
||||
Max Hand Size: 10
|
||||
Max Hand Spread: 700 # Pixel width of fanned cards
|
||||
Card Face Up: true
|
||||
Card Hover Distance: 30 # Hover effect height
|
||||
```
|
||||
|
||||
**Required Curves** (Create in Inspector):
|
||||
- `Hand Rotation Curve`: 2-point linear curve for card rotation
|
||||
- `Hand Vertical Curve`: 3-point curve for arc shape (0→1→0)
|
||||
|
||||
### Step 7: Basic Scripting
|
||||
|
||||
Add this script to your main scene to start using cards:
|
||||
|
||||
```gdscript
|
||||
extends Node2D
|
||||
|
||||
@onready var card_manager = $CardManager
|
||||
@onready var deck = $CardManager/Deck
|
||||
@onready var player_hand = $CardManager/PlayerHand
|
||||
|
||||
func _ready():
|
||||
setup_game()
|
||||
|
||||
func setup_game():
|
||||
# Create a deck of cards
|
||||
create_standard_deck()
|
||||
|
||||
# Deal initial hand
|
||||
deal_cards_to_hand(5)
|
||||
|
||||
func create_standard_deck():
|
||||
var suits = ["club", "diamond", "heart", "spade"]
|
||||
var values = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
|
||||
|
||||
for suit in suits:
|
||||
for value in values:
|
||||
var card_name = "%s_%s" % [suit, value]
|
||||
var card = card_manager.card_factory.create_card(card_name, deck)
|
||||
deck.add_card(card)
|
||||
|
||||
func deal_cards_to_hand(count: int):
|
||||
for i in count:
|
||||
if deck.get_card_count() > 0:
|
||||
var card = deck.get_top_cards(1).front()
|
||||
player_hand.move_cards([card])
|
||||
```
|
||||
|
||||
## Testing Your Setup
|
||||
|
||||
### Quick Test Checklist
|
||||
|
||||
1. **Run Your Scene** - Press F6 and select your main scene
|
||||
2. **Verify Cards Appear** - You should see cards in your containers
|
||||
3. **Test Interactions** - Try dragging cards between containers
|
||||
4. **Check Debug Mode** - Enable in CardManager to see drop zones
|
||||
5. **Console Errors** - Ensure no error messages appear
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Cards Not Appearing**:
|
||||
- Verify JSON files exist and match card names
|
||||
- Check `card_asset_dir` and `card_info_dir` paths
|
||||
- Ensure image files exist in the asset directory
|
||||
|
||||
**Drag and Drop Issues**:
|
||||
- Confirm `enable_drop_zone` is true on containers
|
||||
- Check that `can_be_interacted_with` is true on cards
|
||||
- Verify container positions don't overlap incorrectly
|
||||
|
||||
**JSON Loading Errors**:
|
||||
- Validate JSON syntax using online validator
|
||||
- Ensure required `name` and `front_image` fields exist
|
||||
- Check for typos in field names
|
||||
|
||||
## Next Steps
|
||||
|
||||
### Explore Sample Projects
|
||||
- **`example1/`** - Basic demonstration of all container types
|
||||
- **`freecell/`** - Complete game implementation with custom rules
|
||||
|
||||
### Advanced Customization
|
||||
- [API Reference](API.md) - Complete class documentation
|
||||
- [Creating Custom Containers](API.md#extending-cardcontainer)
|
||||
- [Custom Card Properties](API.md#extending-card)
|
||||
|
||||
### Performance Optimization
|
||||
- Use `preload_card_data()` for better loading performance
|
||||
- Implement object pooling for frequently created/destroyed cards
|
||||
- Consider `max_stack_display` for large piles
|
||||
|
||||
---
|
||||
|
||||
**Need Help?** Check the [API Documentation](API.md) or examine the sample projects for working examples.
|
||||
27
docs/index.md
Normal file
27
docs/index.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Card Framework Documentation
|
||||
|
||||
## 📚 Documentation Index
|
||||
|
||||
### Getting Started
|
||||
- [Quick Start Guide](../README.md) - Essential setup and installation
|
||||
- [Detailed Getting Started](GETTING_STARTED.md) - Complete step-by-step guide
|
||||
- [Example1 Tutorial](../example1/README.md) - Beginner-friendly framework introduction
|
||||
- [FreeCell Implementation](../freecell/README.md) - Advanced production-ready reference
|
||||
|
||||
### API Reference
|
||||
- [Complete API Documentation](API.md) - Full class reference
|
||||
- [CardManager](API.md#cardmanager) - Root orchestrator
|
||||
- [Card](API.md#card) - Individual card nodes
|
||||
- [CardContainer](API.md#cardcontainer) - Container base class
|
||||
- [Pile & Hand](API.md#pile) - Specialized containers
|
||||
|
||||
### Release Information
|
||||
- [Changelog](CHANGELOG.md) - Version history and updates
|
||||
|
||||
### Contributing
|
||||
- [Contributing Guidelines](../README.md#contributing) - How to contribute
|
||||
- [GitHub Repository](https://github.com/chun92/card-framework) - Source code and issues
|
||||
|
||||
---
|
||||
|
||||
**Version**: 1.2.3 | **Godot**: 4.4+ | **License**: Open Source
|
||||
Reference in New Issue
Block a user