From d8435ef46ccc3110d95a84d3de41a737f13588c4 Mon Sep 17 00:00:00 2001 From: Vladimir nett00n Budylnikov Date: Tue, 23 Sep 2025 22:40:00 +0400 Subject: [PATCH] create gem grid --- .gitignore | 3 + docs/CLAUDE.md | 112 ++++++----- docs/CODE_OF_CONDUCT.md | 297 +++++++++++++++++++++++++++++ docs/MAP.md | 209 ++++++++++++++++++++ project.godot | 3 +- scenes/game/game.tscn | 2 +- scenes/main/PressAnyKeyScreen.tscn | 2 +- scenes/main/main.tscn | 2 +- scenes/match3/match3.tscn | 7 +- scenes/match3/tile.gd | 78 +++++++- scenes/ui/MainMenu.tscn | 2 +- scenes/ui/SettingsMenu.tscn | 2 +- 12 files changed, 640 insertions(+), 79 deletions(-) create mode 100644 docs/CODE_OF_CONDUCT.md create mode 100644 docs/MAP.md diff --git a/.gitignore b/.gitignore index 7975bb4..744f1f4 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ *.uid *.tmp *.import~ + +# hidden files +.* diff --git a/docs/CLAUDE.md b/docs/CLAUDE.md index 9c3c65c..05a015c 100644 --- a/docs/CLAUDE.md +++ b/docs/CLAUDE.md @@ -4,38 +4,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -"Skelly" is a Godot 4.4 mobile game project that features a match-3 puzzle game within a broader game framework. The project includes a menu system, settings management, audio handling, and localization support. +"Skelly" is a Godot 4.4 mobile game project featuring a match-3 puzzle game within a broader game framework. The project includes a menu system, settings management, audio handling, localization support, and a comprehensive debug system. -## Project Structure - -### Core Architecture -- **Autoloaded Singletons**: The project uses four global singletons (autoloads) defined in `project.godot`: - - `SettingsManager` - Handles game settings and configuration - - `AudioManager` - Manages music and sound effects with volume controls - - `GameManager` - Handles scene transitions and game state - - `LocalizationManager` - Manages multi-language support (English/Russian) - -### Directory Structure -- `scripts/` - Global singleton scripts and utility classes -- `scenes/` - Game scenes including main game and match-3 components - - `match3/` - Specialized match-3 game implementation -- `ui/` - User interface scenes (MainMenu, SettingsMenu, PressAnyKeyScreen) -- `audio/` - Music and sound effect files -- `resources/` - Game assets (textures, sprites, animations) -- `localization/` - Translation files for internationalization - -### Scene Management Flow -1. Main entry point: `scenes/main.tscn` with press-any-key screen -2. Menu navigation: MainMenu → SettingsMenu (with back navigation) -3. Game flow: MainMenu → Game scene → Match3 game integration -4. All scene transitions handled through `GameManager` singleton - -### Match-3 Game System -- Located in `scenes/match3/` -- Grid-based (8x8) tile matching system -- Implements match detection, tile dropping, and grid refilling -- Uses tile instances with position-based grid management -- Automatic cascade matching after tile drops +**For detailed project architecture, see `docs/MAP.md`** ## Development Commands @@ -43,44 +14,69 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co - Open project in Godot Editor: Import `project.godot` - Run project: Press F5 in Godot Editor or use "Play" button - Debug: Use Godot's built-in debugger and remote inspector +- Debug UI: Press F12 in-game or use debug button to toggle debug panels + +### Testing & Development +- Debug mode can be toggled with F12 key or debug button UI +- Match-3 debug controls include gem count adjustment and board reroll +- Difficulty presets: Easy (3 gems), Normal (5 gems), Hard (8 gems) ### Audio Configuration -- Music: Located in `audio/` directory with loop configuration in AudioManager +- Music: Located in `assets/audio/music/` directory with loop configuration in AudioManager - Sound effects: UI clicks and game audio managed through audio bus system -- Audio buses: "Music" and "SFX" buses configured in `default_bus_layout.tres` +- Audio buses: "Music" and "SFX" buses configured in `data/default_bus_layout.tres` ### Localization - Translations stored in `localization/` as `.translation` files - Currently supports English and Russian - New translations: Add to `project.godot` internationalization section -## Key Components +## Key Development Guidelines -### AudioManager (`scripts/AudioManager.gd`) -- Handles background music with looping -- Manages UI sound effects (click sounds) -- Volume control integration with SettingsManager -- Automatic audio bus configuration +### Scene Management +- **ALWAYS** use `GameManager` for scene transitions - never call `get_tree().change_scene_to_file()` directly +- Scene paths are defined as constants in GameManager +- Error handling is built into GameManager for failed scene loads -### Match3 Game (`scenes/match3/match3.gd`) -- 8x8 grid system with 5 tile types -- Match detection in horizontal and vertical directions -- Tile dropping physics with position-based movement -- Recursive match clearing and grid refilling +### Autoload Usage +- Use autoloads for global state management only +- Prefer signals over direct access for loose coupling +- Don't access autoloads from deeply nested components -### Scene Navigation -- All scene changes go through GameManager for consistency -- Scene paths defined as constants in GameManager -- Error handling for failed scene loads +### Debug System Integration +- Connect to `DebugManager.debug_ui_toggled` signal for debug UI visibility +- Use F12 key for global debug toggle +- Remove debug prints before committing unless permanently useful -## Input System -- Custom input actions defined in `project.godot`: - - `ui_pause` - Space key or gamepad button - - `any_key` - Multiple inputs for menu progression - - `ui_menu_toggle` - Escape key or gamepad button +## Important File References -## Asset Attribution -Asset sources documented in `sources.yaml` including: -- Music from Clement Panchout -- Sound effects from Freesound -- Sprites and textures from various itch.io creators \ No newline at end of file +### Documentation Structure +- **`docs/MAP.md`** - Complete project architecture and structure +- **`docs/CODE_OF_CONDUCT.md`** - Coding standards and best practices +- **This file** - Claude Code specific development guidelines + +### Key Scripts to Understand +- `src/autoloads/GameManager.gd` - Scene transition patterns +- `src/autoloads/DebugManager.gd` - Debug system integration +- `scenes/match3/match3.gd` - Match-3 implementation reference +- `project.godot` - Input actions and autoload definitions + +## Development Workflow + +### Before Making Changes +1. Check `docs/MAP.md` for architecture understanding +2. Review `docs/CODE_OF_CONDUCT.md` for coding standards +3. Understand existing patterns before implementing new features + +### Testing Changes +- Run project with F5 in Godot Editor +- Test debug UI with F12 toggle +- Verify scene transitions work correctly +- Check mobile compatibility if UI changes made + +### Common Implementation Patterns +- Scene transitions: Use `GameManager.change_to_scene()` methods +- Debug integration: Connect to `DebugManager` signals +- Settings: Use `SettingsManager` for persistent configuration +- Audio: Use `AudioManager` for music and sound effects +- Localization: Use `LocalizationManager` for language switching \ No newline at end of file diff --git a/docs/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..7682335 --- /dev/null +++ b/docs/CODE_OF_CONDUCT.md @@ -0,0 +1,297 @@ +# Code of Conduct - Skelly Project + +## Overview + +This document establishes coding standards and development practices for the Skelly project. These guidelines are designed to help junior developers contribute effectively while maintaining code quality and project consistency. + +## Core Principles + +### 1. Code Clarity Over Cleverness +- Write code that is easy to read and understand +- Use descriptive variable and function names +- Prefer explicit code over implicit or "clever" solutions +- Comment complex logic and business rules + +### 2. Consistency First +- Follow existing code patterns in the project +- Use the same naming conventions throughout +- Maintain consistent indentation and formatting +- Follow Godot's GDScript style guide + +### 3. Incremental Development +- Make small, focused commits +- Test changes before committing +- Don't break existing functionality +- Use the debug system to verify your changes + +## GDScript Coding Standards + +### Naming Conventions +```gdscript +# Variables and functions: snake_case +var player_health: int = 100 +func calculate_damage() -> int: + +# Constants: SCREAMING_SNAKE_CASE +const MAX_HEALTH := 100 +const TILE_SPACING := 54 + +# Classes: PascalCase +class_name PlayerController + +# Signals: past_tense +signal health_changed +signal game_started + +# Private functions: prefix with underscore +func _ready(): +func _initialize_grid(): +``` + +### File Organization +```gdscript +# 1. extends statement +extends Node2D + +# 2. class_name (if applicable) +class_name Match3Controller + +# 3. Constants +const GRID_SIZE := Vector2i(8, 8) + +# 4. Signals +signal match_found(tiles: Array) + +# 5. Variables +var grid := [] +@onready var debug_ui = $DebugUI + +# 6. Functions (lifecycle first, then custom) +func _ready(): +func _process(delta): +func custom_function(): +``` + +### Documentation Requirements +```gdscript +# Required for all public functions +func set_gem_pool(gem_indices: Array) -> void: + """Set specific gem types as the active pool""" + _update_all_tiles_gem_pool(gem_indices) + print("Set gem pool to: ", gem_indices) + +# Document complex algorithms +func _get_match_line(start: Vector2i, dir: Vector2i) -> Array: + """Find all matching tiles in a line from start position in given direction""" + var line = [grid[start.y][start.x]] + var type = grid[start.y][start.x].tile_type + # Implementation... +``` + +## Project-Specific Guidelines + +### Scene Management +- All scene transitions MUST go through `GameManager` +- Never use `get_tree().change_scene_to_file()` directly +- Define scene paths as constants in GameManager + +```gdscript +# ✅ Correct +GameManager.start_match3_game() + +# ❌ Wrong +get_tree().change_scene_to_file("res://scenes/match3/match3.tscn") +``` + +### Autoload Usage +- Use autoloads for global state only +- Don't access autoloads from deeply nested components +- Pass data through signals or direct references when possible + +```gdscript +# ✅ Correct - using signals +signal settings_changed +SettingsManager.volume_changed.connect(_on_volume_changed) + +# ✅ Also correct - direct access for global state +var current_language = SettingsManager.get_setting("language") + +# ❌ Wrong - tight coupling +func some_deep_function(): + SettingsManager.set_setting("volume", 0.5) # Too deep in call stack +``` + +### Debug System Integration +- Always connect to DebugManager signals for debug UI +- Use debug prints with clear prefixes +- Remove debug prints before committing (unless permanently useful) + +```gdscript +# ✅ Correct debug integration +func _connect_to_global_debug() -> void: + DebugManager.debug_ui_toggled.connect(_on_debug_ui_toggled) + debug_ui.visible = DebugManager.is_debug_ui_visible() + +# ✅ Good debug prints +print("Match3: Debug UI toggled to: ", visible) +print("TileSystem: Initialized ", tiles.size(), " tiles") + +# ❌ Bad debug prints +print("test") # Not descriptive +print(some_variable) # No context +``` + +### Error Handling +- Always check if resources loaded successfully +- Use `push_error()` for critical failures +- Provide fallback behavior when possible + +```gdscript +# ✅ Correct error handling +func load_scene(path: String) -> void: + var packed_scene := load(path) + if not packed_scene or not packed_scene is PackedScene: + push_error("Failed to load scene at: %s" % path) + return + get_tree().change_scene_to_packed(packed_scene) +``` + +## Git Workflow + +### Commit Guidelines +- Use clear, descriptive commit messages +- Start with a verb in imperative mood +- Keep first line under 50 characters +- Add body if needed for complex changes + +```bash +# ✅ Good commit messages +Add gem pool management to match-3 system +Fix debug UI visibility toggle issue +Update documentation for new debug system + +# ❌ Bad commit messages +fix bug +update +wip +``` + +### Branch Management +- Create feature branches for new functionality +- Use descriptive branch names: `feature/debug-ui`, `fix/tile-positioning` +- Keep branches focused on single features +- Delete branches after merging + +### Before Committing +1. Test your changes in the Godot editor +2. Check that existing functionality still works +3. Use the debug system to verify your implementation +4. Run the project and navigate through affected areas +5. Remove temporary debug code + +## Code Review Guidelines + +### For Reviewers +- Focus on code clarity and maintainability +- Check for adherence to project patterns +- Verify that autoloads are used appropriately +- Ensure debug integration is properly implemented +- Test the changes yourself + +### For Contributors +- Explain complex logic in commit messages or comments +- Provide context for why changes were made +- Test edge cases and error conditions +- Ask questions if project patterns are unclear + +## Testing Approach + +### Manual Testing Requirements +- Test in Godot editor with F5 run +- Verify debug UI works with F12 toggle +- Check scene transitions work correctly +- Test on different screen sizes (mobile target) +- Verify audio and settings integration + +### Debug System Testing +- Ensure debug panels appear/disappear correctly +- Test all debug buttons and controls +- Verify debug state persists across scene changes +- Check that debug code doesn't affect release builds + +## Common Mistakes to Avoid + +### Architecture Violations +```gdscript +# ❌ Don't bypass GameManager +get_tree().change_scene_to_file("some_scene.tscn") + +# ❌ Don't hardcode paths +var tile = load("res://scenes/match3/tile.tscn") + +# ❌ Don't ignore null checks +var node = get_node("SomeNode") +node.do_something() # Could crash if node doesn't exist + +# ❌ Don't create global state in random scripts +# Use autoloads instead +``` + +### Performance Issues +```gdscript +# ❌ Don't search nodes repeatedly +func _process(delta): + var ui = get_node("UI") # Expensive every frame + +# ✅ Cache node references +@onready var ui = $UI +func _process(delta): + ui.update_display() # Much better +``` + +### Debug System Misuse +```gdscript +# ❌ Don't create separate debug systems +var my_debug_enabled = false + +# ✅ Use the global debug system +if DebugManager.is_debug_enabled(): + show_debug_info() +``` + +## Learning Resources + +### Godot-Specific +- [GDScript Style Guide](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_styleguide.html) +- [Godot Best Practices](https://docs.godotengine.org/en/stable/tutorials/best_practices/index.html) +- Project documentation in `docs/map.md` + +### General Programming +- Clean Code principles +- SOLID principles (adapted for game development) +- Git best practices + +## Getting Help + +### When Stuck +1. Check existing code for similar patterns +2. Review project documentation (`docs/`) +3. Use the debug system to understand current state +4. Ask specific questions about project architecture +5. Test your understanding with small experiments + +### Code Review Process +- Submit pull requests early and often +- Ask for feedback on approach before implementing large features +- Be open to suggestions and alternative approaches +- Learn from review feedback for future contributions + +## Summary + +This code of conduct emphasizes: +- **Clarity**: Write code that others can understand +- **Consistency**: Follow established patterns +- **Integration**: Use the project's systems properly +- **Learning**: Continuously improve your skills + +Remember: It's better to ask questions and write clear, simple code than to guess and create complex, hard-to-maintain solutions. The goal is to contribute effectively to a codebase that will grow and evolve over time. \ No newline at end of file diff --git a/docs/MAP.md b/docs/MAP.md new file mode 100644 index 0000000..2c8d764 --- /dev/null +++ b/docs/MAP.md @@ -0,0 +1,209 @@ +# Skelly - Project Structure Map + +## Overview +Skelly is a Godot 4.4 game project featuring a match-3 puzzle game with skeleton character themes. The project follows a modular architecture with clear separation between scenes, autoloads, assets, and data. + +## Project Root Structure + +``` +skelly/ +├── .claude/ # Claude Code configuration +├── .godot/ # Godot engine generated files (ignored) +├── assets/ # Game assets (sprites, audio, textures) +├── data/ # Game data and configuration files +├── docs/ # Documentation +├── localization/ # Internationalization files +├── scenes/ # Godot scenes (.tscn) and scripts (.gd) +├── src/ # Source code organization +├── project.godot # Main Godot project configuration +└── icon.svg # Project icon +``` + +## Core Architecture + +### Autoloads (Global Singletons) +Located in `src/autoloads/`, these scripts are automatically loaded when the game starts: + +1. **SettingsManager** (`src/autoloads/SettingsManager.gd`) + - Manages game settings and user preferences + - Handles configuration file I/O + - Provides language selection functionality + - Dependencies: `localization/languages.json` + +2. **AudioManager** (`src/autoloads/AudioManager.gd`) + - Controls music and sound effects + - Manages audio bus configuration + - Uses: `data/default_bus_layout.tres` + +3. **GameManager** (`src/autoloads/GameManager.gd`) + - Central game state management + - Scene transitions between main/game/match3 + - Navigation flow control + - References: main.tscn, game.tscn, match3.tscn + +4. **LocalizationManager** (`src/autoloads/LocalizationManager.gd`) + - Language switching functionality + - Works with Godot's built-in internationalization system + - Uses translation files in `localization/` + +5. **DebugManager** (`src/autoloads/DebugManager.gd`) + - Global debug state management + - Debug UI visibility control + - F12 toggle functionality + - Signal-based debug system + +## Scene Hierarchy & Flow + +### Main Scenes +``` +main.tscn (Entry Point) +├── PressAnyKeyScreen.tscn +├── MainMenu.tscn +└── SettingsMenu.tscn +``` + +### Game Flow +1. **Main Scene** (`scenes/main/main.tscn` + `Main.gd`) + - Application entry point + - Manages "Press Any Key" screen + - Transitions to main menu + - Dynamic menu loading system + +2. **Press Any Key Screen** (`scenes/main/PressAnyKeyScreen.tscn` + `PressAnyKeyScreen.gd`) + - Initial splash screen + - Input detection for any key/button + - Signals to main scene for transition + +3. **Main Menu** (`scenes/ui/MainMenu.tscn` + `MainMenu.gd`) + - Primary navigation hub + - Start game, settings, quit options + - Connected to GameManager for scene transitions + +4. **Settings Menu** (`scenes/ui/SettingsMenu.tscn` + `SettingsMenu.gd`) + - User preferences interface + - Language selection + - Audio volume controls + - Connected to SettingsManager and AudioManager + +5. **Game Scene** (`scenes/game/game.tscn` + `game.gd`) + - Main gameplay container + - Loads match-3 instance + - Back button for navigation + - Bridge between UI and game logic + +6. **Match-3 Game** (`scenes/match3/match3.tscn` + `match3.gd`) + - Core puzzle game implementation + - Grid-based tile system + - Debug UI integration + - Gem management system + +### UI Components +``` +scenes/ui/ +├── DebugButton.tscn + DebugButton.gd +├── MainMenu.tscn + MainMenu.gd +└── SettingsMenu.tscn + SettingsMenu.gd +``` + +## Match-3 Game System + +### Core Components +1. **Match3 Controller** (`scenes/match3/match3.gd`) + - Grid management (8x8 default) + - Match detection algorithms + - Tile dropping and refilling + - Gem pool management (3-8 gem types) + - Debug UI integration + +2. **Tile System** (`scenes/match3/tile.gd` + `Tile.tscn`) + - Individual tile behavior + - Gem type management + - Visual representation + - Group membership for coordination + +### Debug System +- Global debug state via DebugManager +- Match-3 specific debug UI panel +- Gem count controls (+/- buttons) +- Difficulty presets (Easy: 3 gems, Normal: 5 gems, Hard: 8 gems) +- Reroll functionality +- F12 toggle support + +## Asset Organization + +### Audio (`assets/audio/`) +``` +audio/ +├── music/ # Background music files +└── sfx/ # Sound effects +``` + +### Visual Assets (`assets/`) +``` +assets/ +├── sprites/ +│ ├── characters/skeleton/ # Character artwork +│ ├── gems/ # Match-3 gem sprites +│ └── ui/ # User interface elements +├── textures/ +│ └── backgrounds/ # Background images +└── fonts/ # Custom fonts +``` + +## Data & Configuration + +### Game Data (`data/`) +- `default_bus_layout.tres` - Audio bus configuration for Godot + +### Localization (`localization/`) +- `languages.json` - Available language definitions +- `MainStrings.en.translation` - English translations +- `MainStrings.ru.translation` - Russian translations + +### Project Configuration +- `project.godot` - Main Godot project settings + - Autoload definitions + - Input map configurations + - Rendering settings + - Audio bus references + +## Key Dependencies & Connections + +### Signal Connections +``` +PressAnyKeyScreen --[any_key_pressed]--> Main +MainMenu --[open_settings]--> Main +SettingsMenu --[back_to_main_menu]--> Main +DebugManager --[debug_toggled, debug_ui_toggled]--> Match3 +``` + +### Scene References +``` +GameManager --> main.tscn, game.tscn, match3.tscn +Main --> MainMenu.tscn, SettingsMenu.tscn +Game --> match3.tscn (instantiated) +``` + +### Asset Dependencies +``` +AudioManager --> assets/audio/music/ +SettingsManager --> localization/languages.json +AudioManager --> data/default_bus_layout.tres +``` + +## Development Notes + +### Current Implementation Status +- Match-3 system with 8x8 grid and configurable gem pools +- Debug UI system with F12 toggle functionality +- Scene transition system via GameManager +- Internationalization support for English/Russian + +### Architecture Patterns +1. **Autoload Pattern** - Global managers as singletons +2. **Signal-Based Communication** - Loose coupling between components +3. **Scene Composition** - Modular scene loading and management +4. **Data-Driven Configuration** - JSON for settings and translations +5. **Component Architecture** - Reusable UI and game components + +This structure provides a clean separation of concerns, making the codebase maintainable and extensible for future features. \ No newline at end of file diff --git a/project.godot b/project.godot index a112047..b85da74 100644 --- a/project.godot +++ b/project.godot @@ -55,4 +55,5 @@ locale/translations=PackedStringArray("res://localization/MainStrings.en.transla [rendering] textures/canvas_textures/default_texture_filter=0 -renderer/rendering_method="mobile" +renderer/rendering_method="gl_compatibility" +renderer/rendering_method.mobile="gl_compatibility" diff --git a/scenes/game/game.tscn b/scenes/game/game.tscn index 09d0490..e302b0c 100644 --- a/scenes/game/game.tscn +++ b/scenes/game/game.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=3 format=3 uid="uid://dmwkyeq2l7u04"] -[ext_resource type="Script" uid="uid://bvtr6yhlyuv4v" path="res://scenes/game/game.gd" id="1_uwrxv"] +[ext_resource type="Script" uid="uid://b16jnk7w22mb" path="res://scenes/game/game.gd" id="1_uwrxv"] [ext_resource type="PackedScene" uid="uid://b4kv7g7kllwgb" path="res://scenes/match3/match3.tscn" id="2_yqjtg"] [node name="Game" type="Node"] diff --git a/scenes/main/PressAnyKeyScreen.tscn b/scenes/main/PressAnyKeyScreen.tscn index 8b669a8..d821957 100644 --- a/scenes/main/PressAnyKeyScreen.tscn +++ b/scenes/main/PressAnyKeyScreen.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=15 format=3 uid="uid://gbe1jarrwqsi"] -[ext_resource type="Script" uid="uid://buak21ajgvevl" path="res://scenes/main/PressAnyKeyScreen.gd" id="1_0a4p2"] +[ext_resource type="Script" uid="uid://cxw2fjj5onja3" path="res://scenes/main/PressAnyKeyScreen.gd" id="1_0a4p2"] [ext_resource type="Texture2D" uid="uid://bcr4bokw87m5n" path="res://assets/sprites/characters/skeleton/Skeleton Idle.png" id="2_rjjcb"] [sub_resource type="AtlasTexture" id="AtlasTexture_l6pue"] diff --git a/scenes/main/main.tscn b/scenes/main/main.tscn index 9d37eaa..f59170a 100644 --- a/scenes/main/main.tscn +++ b/scenes/main/main.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=4 format=3 uid="uid://ci2gk11211n0d"] -[ext_resource type="Script" uid="uid://cwlop1ettlqhg" path="res://scenes/main/Main.gd" id="1_0wfyh"] +[ext_resource type="Script" uid="uid://b0uwk2jlm6g08" path="res://scenes/main/Main.gd" id="1_0wfyh"] [ext_resource type="PackedScene" uid="uid://gbe1jarrwqsi" path="res://scenes/main/PressAnyKeyScreen.tscn" id="1_o5qli"] [ext_resource type="Texture2D" uid="uid://c8y6tlvcgh2gn" path="res://assets/textures/backgrounds/beanstalk-dark.webp" id="2_sugp2"] diff --git a/scenes/match3/match3.tscn b/scenes/match3/match3.tscn index cb0cce5..7524cbe 100644 --- a/scenes/match3/match3.tscn +++ b/scenes/match3/match3.tscn @@ -1,13 +1,8 @@ -[gd_scene load_steps=3 format=3 uid="uid://b4kv7g7kllwgb"] +[gd_scene load_steps=2 format=3 uid="uid://b4kv7g7kllwgb"] [ext_resource type="Script" uid="uid://bvyiwvpepqfdu" path="res://scenes/match3/match3.gd" id="1_mvfdp"] -[ext_resource type="Texture2D" uid="uid://ccprr0qrj3lgm" path="res://assets/sprites/gems/rg_19.png" id="2_0fhn8"] [node name="Match3" type="Node2D"] script = ExtResource("1_mvfdp") [node name="GridContainer" type="Node2D" parent="."] - -[node name="Sprite2D" type="Sprite2D" parent="."] -position = Vector2(584, 317) -texture = ExtResource("2_0fhn8") diff --git a/scenes/match3/tile.gd b/scenes/match3/tile.gd index 8eb7217..21f2452 100644 --- a/scenes/match3/tile.gd +++ b/scenes/match3/tile.gd @@ -5,21 +5,32 @@ var grid_position: Vector2i @onready var sprite: Sprite2D = $Sprite2D -# Target size for each tile to fit in the 64x64 grid cells -const TILE_SIZE = 48 # Slightly smaller than 64 to leave some padding +# Target size for each tile to fit in the 54x54 grid cells +const TILE_SIZE = 48 # Slightly smaller than 54 to leave some padding -var tile_textures = [ - preload("res://assets/sprites/gems/bg_19.png"), - preload("res://assets/sprites/gems/dg_19.png"), - preload("res://assets/sprites/gems/gg_19.png"), - preload("res://assets/sprites/gems/mg_19.png"), +# All available gem textures +var all_gem_textures = [ + preload("res://assets/sprites/gems/bg_19.png"), # 0 - Blue gem + preload("res://assets/sprites/gems/dg_19.png"), # 1 - Dark gem + preload("res://assets/sprites/gems/gg_19.png"), # 2 - Green gem + preload("res://assets/sprites/gems/mg_19.png"), # 3 - Magenta gem + preload("res://assets/sprites/gems/rg_19.png"), # 4 - Red gem + preload("res://assets/sprites/gems/yg_19.png"), # 5 - Yellow gem + preload("res://assets/sprites/gems/pg_19.png"), # 6 - Purple gem + preload("res://assets/sprites/gems/sg_19.png"), # 7 - Silver gem ] +# Currently active gem types (indices into all_gem_textures) +var active_gem_types = [0, 1, 2, 3, 4] # Start with first 5 gems + func _set_tile_type(value: int) -> void: tile_type = value - if value >= 0 and value < tile_textures.size(): - sprite.texture = tile_textures[value] + if value >= 0 and value < active_gem_types.size(): + var texture_index = active_gem_types[value] + sprite.texture = all_gem_textures[texture_index] _scale_sprite_to_fit() + else: + push_error("Invalid tile type: " + str(value) + ". Available types: 0-" + str(active_gem_types.size() - 1)) func _scale_sprite_to_fit() -> void: if sprite.texture: @@ -28,6 +39,55 @@ func _scale_sprite_to_fit() -> void: var scale_factor = TILE_SIZE / max_dimension sprite.scale = Vector2(scale_factor, scale_factor) +# Gem pool management functions +static func set_active_gem_pool(gem_indices: Array) -> void: + # Update all tile instances to use new gem pool + var tiles = get_tree().get_nodes_in_group("tiles") + for tile in tiles: + if tile.has_method("_update_active_gems"): + tile._update_active_gems(gem_indices) + +func _update_active_gems(gem_indices: Array) -> void: + active_gem_types = gem_indices.duplicate() + # Re-validate current tile type + if tile_type >= active_gem_types.size(): + tile_type = 0 # Reset to first available type + _set_tile_type(tile_type) + +static func get_active_gem_count() -> int: + # Get from any tile instance or default + var tiles = get_tree().get_nodes_in_group("tiles") + if tiles.size() > 0: + return tiles[0].active_gem_types.size() + return 5 # Default + +static func add_gem_to_pool(gem_index: int) -> void: + var tiles = get_tree().get_nodes_in_group("tiles") + for tile in tiles: + if tile.has_method("_add_gem_type"): + tile._add_gem_type(gem_index) + +func _add_gem_type(gem_index: int) -> void: + if gem_index >= 0 and gem_index < all_gem_textures.size(): + if not active_gem_types.has(gem_index): + active_gem_types.append(gem_index) + +static func remove_gem_from_pool(gem_index: int) -> void: + var tiles = get_tree().get_nodes_in_group("tiles") + for tile in tiles: + if tile.has_method("_remove_gem_type"): + tile._remove_gem_type(gem_index) + +func _remove_gem_type(gem_index: int) -> void: + var type_index = active_gem_types.find(gem_index) + if type_index != -1 and active_gem_types.size() > 2: # Keep at least 2 gem types + active_gem_types.erase(gem_index) + # Update tiles that were using removed type + if tile_type >= active_gem_types.size(): + tile_type = 0 + _set_tile_type(tile_type) + # Called when the node enters the scene tree for the first time. func _ready() -> void: + add_to_group("tiles") # Add to group for gem pool management _set_tile_type(tile_type) diff --git a/scenes/ui/MainMenu.tscn b/scenes/ui/MainMenu.tscn index 19b27a8..e4aad45 100644 --- a/scenes/ui/MainMenu.tscn +++ b/scenes/ui/MainMenu.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=3 uid="uid://m8lf3eh3al5j"] -[ext_resource type="Script" uid="uid://ctu58xq7btp1n" path="res://scenes/ui/MainMenu.gd" id="1_b00nv"] +[ext_resource type="Script" uid="uid://b2c35v0f6rymd" path="res://scenes/ui/MainMenu.gd" id="1_b00nv"] [node name="MainMenu" type="Control"] layout_mode = 3 diff --git a/scenes/ui/SettingsMenu.tscn b/scenes/ui/SettingsMenu.tscn index ff4d062..80dfed5 100644 --- a/scenes/ui/SettingsMenu.tscn +++ b/scenes/ui/SettingsMenu.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=3 uid="uid://57obmcwyos2g"] -[ext_resource type="Script" uid="uid://c8mlvlerv4y03" path="res://scenes/ui/SettingsMenu.gd" id="1_oqkcn"] +[ext_resource type="Script" uid="uid://bv56qwni68qo" path="res://scenes/ui/SettingsMenu.gd" id="1_oqkcn"] [node name="SettingsMenu" type="Control" groups=["localizable"]] layout_mode = 3