diff --git a/assets/.DS_Store b/assets/.DS_Store index 02a733829..57f62c7ae 100644 Binary files a/assets/.DS_Store and b/assets/.DS_Store differ diff --git a/nova farma TRAE/dokumentacija/TODO_NEXT_SESSION.md b/nova farma TRAE/dokumentacija/TODO_NEXT_SESSION.md new file mode 100644 index 000000000..aee3d6ae6 --- /dev/null +++ b/nova farma TRAE/dokumentacija/TODO_NEXT_SESSION.md @@ -0,0 +1,97 @@ +# ๐Ÿ“‹ TODO - Next Session (11.2.2026+) + +**Last Session:** 10-11.2.2026 (6 hours) +**Progress:** 23/160 assets (14.4%) + +--- + +## ๐ŸŽฏ PRIORITETE ZA NASLEDNJI SESSION: + +### **1. BATCH 2 - KAI ANIMATIONS (2 Missing)** +- [ ] `kai_death_sheet.png` - Death animation (4-6 frames) +- [ ] `kai_tool_use_sheet.png` - Tool animations (hoe, axe, water) + +**Reference:** `/assets/references/kaj.png` (correct DNA!) + +--- + +### **2. BATCH 11 - STRUCTURES (Missing Assets)** + +#### **MANJKA BARN/SKEDENJ:** +- [ ] Generate `barn_ruined.png` - Ruined state +- [ ] Generate `barn_repaired.png` - Fixed state + +**Important:** +- Reference `skedenj.png` NE OBSTAJA! +- Moraลก generirati iz opisa +- Gothic chibi style +- Dark wood, broken roof (ruined) +- Fixed roof, cleaner (repaired) + +**Specifications:** +- Animal housing (4 animals capacity) +- Storage functionality +- Repair cost: 60 Wood, 25 Stone, 5 Iron +- Repair time: 3 days + +--- + +### **3. BATCH 4 - POLAROID INTRO (8 Images)** + +Critical for narrative intro: +- [ ] `polaroid_13.png` - Kai as child +- [ ] `polaroid_14.png` - Family photo +- [ ] `polaroid_15.png` - Teenage Kai +- [ ] `polaroid_16.png` - Ana closeup +- [ ] `polaroid_17.png` - Cannabis plant memory +- [ ] `polaroid_18.png` - Abandoned island arrival +- [ ] `polaroid_19.png` - Kai + Gronk first meeting +- [ ] `polaroid_20.png` - Valley of Death landscape + +**Style:** Polaroid aesthetic, faded colors, white frame borders + +--- + +### **4. TECHNICAL FIXES** + +- [ ] Test rain system in browser (refresh + verify) +- [ ] Re-enable vegetation system (uncomment lines 1027-1048) +- [ ] Add toggle for rain (T key or UI button?) + +--- + +## โœ… ล E COMPLETED (Session 10-11.2): + +**Zombies:** 7 characters + 2 references โœ… +**Kai:** 4 animations (idle, walk, attack) โœ… +**Environment:** 9 assets (sky, sun, moon, rain) โœ… +**Code:** Rain weather system โœ… +**Docs:** MASTER_GAME_BIBLE + DNEVNIK updated โœ… + +--- + +## ๐Ÿ“Š BATCH STATUS: + +- โœ… **Batch 1 (Zombies): 100%** (8/8) +- โธ๏ธ **Batch 2 (Kai): 67%** (4/6) +- โœ… **Batch 3 (Environment): 100%** (7/7 + rain) +- โธ๏ธ **Batch 4 (Polaroid): 0%** (0/8) +- โธ๏ธ **Batch 11 (Structures): 60%** (missing barn) + +--- + +## ๐ŸŽฎ GAME STATE: + +- Rain system: โœ… Active +- Vegetation: ๐Ÿšซ Disabled (testing) +- Assets: All in correct directories +- Commits: All saved + +--- + +**NEXT SESSION START HERE! ๐Ÿš€** + +Datum: 11.2.2026+ +Focus: Kai animations โ†’ Barn โ†’ Polaroid intro + +--- diff --git a/nova farma TRAE/src/scenes/GrassScene_Clean.js b/nova farma TRAE/src/scenes/GrassScene_Clean.js index c7bba872f..3dc56877c 100644 --- a/nova farma TRAE/src/scenes/GrassScene_Clean.js +++ b/nova farma TRAE/src/scenes/GrassScene_Clean.js @@ -20,6 +20,26 @@ export default class GrassSceneClean extends Phaser.Scene { this.LAYER_TREES = 2; // Trees this.LAYER_CHARACTERS = 10; // Kai, zombies + // === PIXEL-PERFECT SCALE SYSTEM === + // Base tile reference: 32x32 px + // All objects scale to exact pixel sizes on screen + this.PIXEL_TILE = 32; + this.PIXEL_KAI_HEIGHT = 64; // 2 tiles + this.PIXEL_GRASS_LOW = 10; // Max height for low grass + this.PIXEL_GRASS_TALL_MIN = 24; + this.PIXEL_GRASS_TALL_MAX = 28; + this.PIXEL_GRASS_TALL_AVG = 28; // UPDATED: Target 28px (user spec) + this.PIXEL_OAK_WIDTH = 96; // 3 tiles + this.PIXEL_OAK_HEIGHT = 160; // 5 tiles + + // ROOT OFFSET: Bury plants 6px into ground + this.ROOT_OFFSET = 6; // Plants sink into brown dirt texture + + // Asset source dimensions (for scale calculation) + this.SOURCE_KAI_FRAME = 256; // kai_walk_sheet frame size + this.SOURCE_GRASS_TALL = 1024; // visoka_trava_v2.png + this.SOURCE_TREE_AVG = 366; // tree_adult average height + // === GROWTH STATE === this.soilGrid = []; // 50x50 grid for moisture tracking this.grassTiles = []; // Dynamic grass instances @@ -102,6 +122,72 @@ export default class GrassSceneClean extends Phaser.Scene { this.load.image('rain_drops', 'DEMO_FAZA1/Environment/rain_drops.png'); } + // =================================================================== + // AUTO-LOADER SYSTEM: Vegetation & Trees + // =================================================================== + + /** + * MAP_LOADER: Auto-load vegetation with pixel-perfect grounding + * @param {number} x - World X position + * @param {number} y - World Y position (tile bottom) + * @param {string} key - Asset key from Vegetation folder + * @returns {Phaser.GameObjects.Image} Grounded vegetation sprite + */ + loadVegetation(x, y, key) { + // Get source dimensions + const texture = this.textures.get(key); + const sourceHeight = texture.getSourceImage().height; + + // VEGETATION SPEC: 28px final height, 4px burial + const targetHeight = this.PIXEL_GRASS_TALL_AVG; // 28px + const burialOffset = 4; // Vegetation burial depth + + // Calculate scale + const scale = targetHeight / sourceHeight; + + // Create sprite + const sprite = this.add.image(x, y + burialOffset, key) + .setScale(scale) + .setOrigin(0.5, 1.0) // Bottom-center anchor + .setDepth(y + burialOffset); // Y-sorting + + // SMOOTH RENDERING: Linear filter (no pixelation) + sprite.texture.setFilter(Phaser.Textures.FilterMode.LINEAR); + + return sprite; + } + + /** + * TREE_LOADER: Auto-load trees with pixel-perfect grounding + * @param {number} x - World X position + * @param {number} y - World Y position (tile bottom) + * @param {string} key - Asset key from Trees folder + * @returns {Phaser.GameObjects.Image} Grounded tree sprite + */ + loadTree(x, y, key) { + // Get source dimensions + const texture = this.textures.get(key); + const sourceHeight = texture.getSourceImage().height; + + // TREE SPEC: 160px final height, 8px burial + const targetHeight = this.PIXEL_OAK_HEIGHT; // 160px + const burialOffset = 8; // Tree burial depth + + // Calculate scale + const scale = targetHeight / sourceHeight; + + // Create sprite + const sprite = this.add.image(x, y + burialOffset, key) + .setScale(scale) + .setOrigin(0.5, 1.0) // Bottom-center anchor + .setDepth(y + burialOffset); // Y-sorting + + // SMOOTH RENDERING: Linear filter (no pixelation) + sprite.texture.setFilter(Phaser.Textures.FilterMode.LINEAR); + + return sprite; + } + create() { // --- DYNAMIC ASSETS GENERATION --- // Generate 'hole' texture if it doesn't exist @@ -826,10 +912,19 @@ export default class GrassSceneClean extends Phaser.Scene { const SPAWN_Y = WORLD_H / 2; this.kai = this.physics.add.sprite(SPAWN_X, SPAWN_Y, 'kai'); - // Poveฤava na polno velikost (256px) - this.kai.setScale(1); + + // PIXEL-PERFECT SCALE: Kai = 64px height (2 tiles) + // Source frame: 256x256 โ†’ Target: 64px + const kaiScale = this.PIXEL_KAI_HEIGHT / this.SOURCE_KAI_FRAME; + this.kai.setScale(kaiScale); // 0.25x โ†’ 64px exact + this.kai.setCollideWorldBounds(true); - this.kai.setOrigin(0.5, 0.9); + + // ANCHOR POINT: Bottom-center (feet on ground) + this.kai.setOrigin(0.5, 1.0); + + // DYNAMIC DEPTH: Y-sorting for walking between vegetation + this.kai.setDepth(this.kai.y); // RESPAWN SYSTEM this.respawnPoint = { x: SPAWN_X, y: SPAWN_Y }; @@ -854,6 +949,29 @@ export default class GrassSceneClean extends Phaser.Scene { */ console.log('SPALNA VREฤŒA ODSTRANJENA'); + // =================================================================== + // TEST: AUTO-LOADER DEMO + // =================================================================== + // Place test vegetation and tree to verify grounding system + + const testTileBottom = SPAWN_Y + 200; // Tile bottom Y position + + // TEST 1: Vegetation (28px height, 4px burial) + this.testGrass = this.loadVegetation( + SPAWN_X - 100, // Left of Kai + testTileBottom, + 'grass_ref_1' + ); + console.log('๐ŸŒฟ TEST: Grass loaded at 28px with 4px burial'); + + // TEST 2: Tree (160px height, 8px burial) + this.testTree = this.loadTree( + SPAWN_X + 100, // Right of Kai + testTileBottom, + 'tree_adult_0' + ); + console.log('๐ŸŒณ TEST: Oak loaded at 160px with 8px burial'); + // =================================================================== // Adjust Physics Body for larger size // Width ~40, Height ~30 (relative to scaled sprite) @@ -1024,8 +1142,6 @@ export default class GrassSceneClean extends Phaser.Scene { // === FARMING & FOG REMOVED - Ultra Clean === // === PROCEDURAL GROWTH SYSTEM INITIALIZATION === - // TEMPORARILY DISABLED FOR TESTING - /* console.log('๐ŸŒฑ Initializing Procedural Growth System...'); // Initialize soil moisture grid @@ -1048,8 +1164,6 @@ export default class GrassSceneClean extends Phaser.Scene { }); console.log('โœ… Growth system ready - Island will evolve over time!'); - */ - console.log('๐Ÿšซ Vegetation DISABLED for testing'); // === RAIN WEATHER SYSTEM === // Create rain particles that fall from sky @@ -1324,14 +1438,16 @@ export default class GrassSceneClean extends Phaser.Scene { // Check if already placed here if (placed.some(p => p.gridX === gridX && p.gridY === gridY)) continue; - // World coordinates + // World coordinates (tile center) const worldX = this.islandX + (gridX * this.TILE_SIZE) + (this.TILE_SIZE / 2); - const worldY = this.islandY + (gridY * this.TILE_SIZE) + (this.TILE_SIZE / 2); + const tileBottomY = this.islandY + (gridY * this.TILE_SIZE) + this.TILE_SIZE; // Create sapling (small tree) - const sapling = this.add.image(worldX, worldY, 'drevo_faza_1') - .setScale(0.4) // Small sapling - .setDepth(this.LAYER_TREES) + const treeScale = this.PIXEL_OAK_HEIGHT / this.SOURCE_TREE_AVG; // Pixel-perfect oak scale + const sapling = this.add.image(worldX, tileBottomY + this.ROOT_OFFSET, 'drevo_faza_1') + .setScale(treeScale * 0.4) // Small sapling (40% of full oak) + .setOrigin(0.5, 1.0) // ANCHOR: Bottom-center + .setDepth(tileBottomY + this.ROOT_OFFSET) // DYNAMIC DEPTH: Y-sorting .setAlpha(0.8); this.treeSaplings.push({ @@ -1374,14 +1490,16 @@ export default class GrassSceneClean extends Phaser.Scene { this.treeSaplings.forEach(tree => { tree.age++; + const treeScale = this.PIXEL_OAK_HEIGHT / this.SOURCE_TREE_AVG; + // Growth stages: 1โ†’2 at 3 days, 2โ†’3 at 7 days if (tree.age === 3 && tree.stage === 1) { tree.stage = 2; - tree.sprite.setTexture('drevo_faza_2').setScale(0.7); + tree.sprite.setTexture('drevo_faza_2').setScale(treeScale * 0.7); // 70% of full oak treesGrown++; } else if (tree.age === 7 && tree.stage === 2) { tree.stage = 3; - tree.sprite.setTexture('drevo_veliko').setScale(1.0).setAlpha(1.0); + tree.sprite.setTexture('drevo_veliko').setScale(treeScale).setAlpha(1.0); // Full 160px oak! treesGrown++; } }); @@ -1394,15 +1512,19 @@ export default class GrassSceneClean extends Phaser.Scene { /** Grow grass at grid position */ growGrass(gridX, gridY) { const worldX = this.islandX + (gridX * this.TILE_SIZE) + (this.TILE_SIZE / 2); - const worldY = this.islandY + (gridY * this.TILE_SIZE) + (this.TILE_SIZE / 2); + const tileBottomY = this.islandY + (gridY * this.TILE_SIZE) + this.TILE_SIZE; // Random grass sprite (use available grass assets) const grassTypes = ['grass_ref_1', 'grass_cluster_dense', 'grass_cluster_flowery']; const grassType = Phaser.Utils.Array.GetRandom(grassTypes); - const grass = this.add.image(worldX, worldY, grassType) - .setScale(0.6 + Math.random() * 0.4) // Size variation - .setDepth(this.LAYER_VEGETATION) // Layer 1 - below characters! + // PIXEL-PERFECT SCALE: Tall grass = 28px height + const grassScale = this.PIXEL_GRASS_TALL_AVG / this.SOURCE_GRASS_TALL; + + const grass = this.add.image(worldX, tileBottomY + this.ROOT_OFFSET, grassType) + .setScale(grassScale * (0.9 + Math.random() * 0.2)) // Slight variation (90-110% of 28px) + .setOrigin(0.5, 1.0) // ANCHOR: Bottom-center + .setDepth(tileBottomY + this.ROOT_OFFSET) // DYNAMIC DEPTH: Y-sorting .setAlpha(0); // Fade in animation