📚 Documentation + scripts from today's exploration
- ASSET_COUNT_STATUS_01_01_2026.md - asset tracking - CHARACTER_PRODUCTION_PLAN.md - character animation plan - CHARACTER_GENERATION_FINAL_PLAN.md - API alternatives research - COMFYUI_SETUP_TODAY.md - ComfyUI setup guide - TASKS_01_01_2026.md - consolidated task list - FULL_STORY_OVERVIEW.md - game narrative summary - preview_animations.html - animation preview gallery - Test scripts for API exploration (test_minimal.py, test_imagen.py) - Character generation scripts (generate_all_characters_complete.py, generate_characters_working.py) These were created during API troubleshooting and production planning.
This commit is contained in:
289
ASSET_COUNT_STATUS_01_01_2026.md
Normal file
289
ASSET_COUNT_STATUS_01_01_2026.md
Normal file
@@ -0,0 +1,289 @@
|
||||
# 📊 ASSET COUNT STATUS - 1.1.2026
|
||||
|
||||
**Datum**: 1.1.2026 @ 12:45
|
||||
**Trenutno**: 752 PNG
|
||||
**Target**: 13,500 PNG
|
||||
**Progress**: 5.6%
|
||||
|
||||
---
|
||||
|
||||
## 📈 TRENUTNO STANJE
|
||||
|
||||
| Kategorija | PNG Files | % Complete | Status |
|
||||
|:-----------|----------:|:----------:|:------:|
|
||||
| **kai** | 265 | ✅ | Animations complete |
|
||||
| **ana** | 15 | 🟡 | Need animations |
|
||||
| **gronk** | 14 | 🟡 | Need animations |
|
||||
| **npcs** | 48 | 🔴 | Need 132 more |
|
||||
| **sovrazniki** | 68 | 🔴 | Need more zombies |
|
||||
| **zgradbe** | 16 | 🔴 | Need 150+ |
|
||||
| **orodja** | 10 | 🟡 | Need upgrades |
|
||||
| **hrana** | 10 | 🔴 | Need 100+ |
|
||||
| **orozje** | 10 | 🔴 | Need 50+ |
|
||||
| **rastline** | 71 | 🟡 | Need seasonal |
|
||||
| **ui** | 24 | 🟡 | Need 200+ |
|
||||
| **dinozavri** | 32 | ✅ | COMPLETE! |
|
||||
| **ostalo** | 169 | 🔴 | Misc assets |
|
||||
| **TOTAL** | **752** | **5.6%** | 🚀 **Production Active** |
|
||||
|
||||
---
|
||||
|
||||
## 🧟 GLAVNI KARAKTERJI + SOVRAŽNIKI - PODROBNO
|
||||
|
||||
### 👥 Heroes (Main Characters)
|
||||
| Karakter | PNG Files | Status | Lokacija |
|
||||
|:---------|----------:|:------:|:---------|
|
||||
| **Kai** | 1 | 🔴 MASTER ONLY | `assets/slike/kai/MASTER_KAI.png` |
|
||||
| **Ana** | 0 | 🔴 NEED MASTER | `assets/slike/ana/` |
|
||||
| **Gronk** | 1 | 🔴 MASTER ONLY | `assets/slike/gronk/` |
|
||||
| **konsistentno/** | 6 | ✅ LOCKED REFS | Style A + B (all 3) |
|
||||
| **Heroes Total** | **8** | 🔴 **NEED ~174 ANIMATIONS** | - |
|
||||
|
||||
#### 🎬 Animations Needed:
|
||||
| Character | Walk Cycle | Idle | Actions | Tools | TOTAL Needed |
|
||||
|:----------|:----------:|:----:|:-------:|:-----:|-----------:|
|
||||
| Kai | 32 PNG | 4 | 12 | 8 | +56 PNG |
|
||||
| Ana | 32 PNG | 4 | 12 | 12 | +60 PNG |
|
||||
| Gronk | 32 PNG | 4 | 16 | 6 | +58 PNG |
|
||||
| **TOTAL** | **96** | **12** | **40** | **26** | **+174 PNG** |
|
||||
|
||||
---
|
||||
|
||||
### 🧟 Zombies & Enemies
|
||||
| Category | PNG Files | 1024px | 256px | Status | Lokacija |
|
||||
|:---------|----------:|:------:|:-----:|:------:|:---------|
|
||||
| **Zombiji** | 36 | 18 | 18 | 🟡 BASIC SET | `sovrazniki/zombiji/` |
|
||||
| **Mutanti** | 6 | 3 | 3 | 🔴 NEED MORE | `sovrazniki/mutanti/` |
|
||||
| **Bossi** | 26 | 13 | 13 | 🟡 GOOD START | `sovrazniki/bossi/` |
|
||||
| **Enemies Total** | **68** | **34** | **34** | 🟡 **~23% Complete** | - |
|
||||
|
||||
#### 🧟 Zombie Types (36 PNG):
|
||||
| Type | Count | Status |
|
||||
|:-----|:-----:|:------:|
|
||||
| Basic Zombies | ~18 | ✅ Core set |
|
||||
| Zombie Variants | ~18 | 🟡 Previews |
|
||||
| **NEED**: Animations | +144 | 🔴 Walk/Attack cycles |
|
||||
| **NEED**: Hybrids | +50 | 🔴 Special types |
|
||||
| **Target Total** | **230** | 🔴 **84% remaining** |
|
||||
|
||||
#### 🐾 Mutants (6 PNG):
|
||||
- ✅ Mutant Spider (2 PNG - 1024 + 256)
|
||||
- ✅ Mutant Dog (2 PNG - 1024 + 256)
|
||||
- ✅ Mutant Rat Giant (2 PNG - 1024 + 256)
|
||||
- ❌ NEED: +44 PNG (more mutant types + animations)
|
||||
- **Target**: 50 PNG total
|
||||
|
||||
#### 👹 Bosses (26 PNG):
|
||||
- ✅ Boss Dragon Fire (2 PNG)
|
||||
- ✅ Boss Dragon Ice (2 PNG)
|
||||
- ✅ Boss Phoenix (2 PNG)
|
||||
- ✅ Boss Vampire (2 PNG)
|
||||
- ✅ Boss Hydra (2 PNG)
|
||||
- ✅ Boss Kraken (2 PNG)
|
||||
- ✅ Boss Golem (2 PNG)
|
||||
- ✅ Boss Spider Queen (2 PNG)
|
||||
- ✅ Boss Demon (2 PNG)
|
||||
- ✅ Boss T-Rex (2 PNG)
|
||||
- ✅ +3 more bosses (6 PNG)
|
||||
- ❌ NEED: +54 PNG (animations + 7 more bosses)
|
||||
- **Target**: 80 PNG total (20 bosses × 4 PNG each)
|
||||
|
||||
---
|
||||
|
||||
## 📊 ENEMIES - PRODUCTION TARGET
|
||||
|
||||
| Category | Current | Today | Target | Remaining | Priority |
|
||||
|:---------|--------:|------:|-------:|----------:|:--------:|
|
||||
| **Zombies** | 36 | - | 230 | 194 | 🔥 HIGH |
|
||||
| **Mutants** | 6 | - | 50 | 44 | 🔶 MEDIUM |
|
||||
| **Bosses** | 26 | +20? | 80 | 54 | 🔷 MEDIUM |
|
||||
| **Hybrids** | 0 | - | 100 | 100 | 🔵 LOW |
|
||||
| **TOTAL** | **68** | **+20** | **460** | **392** | - |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 NAČRT ZA DANES (1.1.2026)
|
||||
|
||||
| Task | PNG Output | Čas | Status |
|
||||
|:-----|:----------:|:---:|:------:|
|
||||
| **Task 1.1: Anomalous Fauna** | +96 | 90 min | ⏳ Pending |
|
||||
| **Task 1.2: Character Animations** | +120 | 2h | ⏳ Pending |
|
||||
| **Task 1.3: Biome Packs (Optional)** | +200-300 | 3-4h | ⏳ Optional |
|
||||
| **Task 1.4: Background Removal** | Processing | 30 min | ⏳ Pending |
|
||||
| **TOTAL DANES** | **+216 (min)** <br> **+516 (max)** | **3-7h** | 🚀 **Ready!** |
|
||||
|
||||
---
|
||||
|
||||
## 📊 ASSET COUNT PROJECTION
|
||||
|
||||
### Scenario A: Minimum (Core Tasks Only)
|
||||
| Category | Current | Today | Total After | Progress |
|
||||
|:---------|--------:|------:|------------:|---------:|
|
||||
| **Existing Assets** | 752 | - | 752 | - |
|
||||
| **Anomalous Fauna** | 32 | +96 | 128 | +300% |
|
||||
| **Character Animations** | 294 | +120 | 414 | +41% |
|
||||
| **TOTAL** | **752** | **+216** | **968** | **7.2%** |
|
||||
|
||||
### Scenario B: Maximum (All Optional Tasks)
|
||||
| Category | Current | Today | Total After | Progress |
|
||||
|:---------|--------:|------:|------------:|---------:|
|
||||
| **Existing Assets** | 752 | - | 752 | - |
|
||||
| **Anomalous Fauna** | 32 | +96 | 128 | +300% |
|
||||
| **Character Animations** | 294 | +120 | 414 | +41% |
|
||||
| **Biome Packs (2-3)** | 0 | +300 | 300 | NEW! |
|
||||
| **TOTAL** | **752** | **+516** | **1,268** | **9.4%** |
|
||||
|
||||
---
|
||||
|
||||
## 🏆 MILESTONE TRACKING
|
||||
|
||||
| Milestone | PNG Target | Current | Remaining | ETA |
|
||||
|:----------|:----------:|--------:|----------:|:---:|
|
||||
| **MVP Demo** | 1,000 | 752 | 248 | 🟢 Today-Tomorrow |
|
||||
| **Kickstarter** | 2,500 | 752 | 1,748 | 🟡 Week 1-2 |
|
||||
| **Alpha 1.0** | 5,000 | 752 | 4,248 | 🟡 Month 1 |
|
||||
| **Alpha 2.0** | 8,000 | 752 | 7,248 | 🔴 Month 2 |
|
||||
| **Full Game** | 13,500 | 752 | 12,748 | 🔴 Month 3-4 |
|
||||
|
||||
---
|
||||
|
||||
## 📋 DETAILED BREAKDOWN BY CATEGORY
|
||||
|
||||
### 🧑 Characters (Total Target: 1,500)
|
||||
| Asset Type | Current | Today | After | Target | Remaining |
|
||||
|:-----------|--------:|------:|------:|-------:|----------:|
|
||||
| Kai Animations | 265 | +40 | 305 | 400 | 95 |
|
||||
| Ana Animations | 15 | +40 | 55 | 400 | 345 |
|
||||
| Gronk Animations | 14 | +40 | 54 | 400 | 346 |
|
||||
| NPCs | 48 | - | 48 | 180 | 132 |
|
||||
| **Subtotal** | **342** | **+120** | **462** | **1,380** | **918** |
|
||||
|
||||
### 🦖 Biomes - Anomalous Zones (Target: 1,800)
|
||||
| Biome | Current | Today | After | Target | % |
|
||||
|:------|--------:|------:|------:|-------:|--:|
|
||||
| Dinozavri | 32 | - | 32 | 100 | 32% |
|
||||
| Mythical Highlands | 0 | +12 | 12 | 100 | 12% |
|
||||
| Endless Forest | 0 | +12 | 12 | 100 | 12% |
|
||||
| Loch Ness | 0 | +12 | 12 | 100 | 12% |
|
||||
| Egyptian Desert | 0 | +12 | 12 | 100 | 12% |
|
||||
| Amazonas | 0 | +12 | 12 | 100 | 12% |
|
||||
| Atlantis | 0 | +12 | 12 | 100 | 12% |
|
||||
| Chernobyl | 0 | +12 | 12 | 100 | 12% |
|
||||
| Catacombs | 0 | +12 | 12 | 100 | 12% |
|
||||
| Mexican Cenotes | 0 | *(+100)* | 100 | 100 | 0%→100% |
|
||||
| Witch Forest | 0 | *(+100)* | 100 | 100 | 0%→100% |
|
||||
| Auroras | 0 | - | 0 | 100 | 0% |
|
||||
| **Subtotal** | **32** | **+96 (+200)** | **328** | **1,800** | **18%** |
|
||||
|
||||
*Note: (+200) = optional biome packs if doing Task 1.3*
|
||||
|
||||
### 🗡️ Combat & Equipment (Target: 2,500)
|
||||
| Asset Type | Current | Today | After | Target | Remaining |
|
||||
|:-----------|--------:|------:|------:|-------:|----------:|
|
||||
| Weapons | 10 | - | 10 | 150 | 140 |
|
||||
| Armor/Clothing | 0 | - | 0 | 200 | 200 |
|
||||
| Tools | 10 | - | 10 | 80 | 70 |
|
||||
| **Subtotal** | **20** | **0** | **20** | **430** | **410** |
|
||||
|
||||
### 🌾 Resources & Items (Target: 3,500)
|
||||
| Asset Type | Current | Today | After | Target | Remaining |
|
||||
|:-----------|--------:|------:|------:|-------:|----------:|
|
||||
| Food | 10 | - | 10 | 200 | 190 |
|
||||
| Plants | 71 | - | 71 | 300 | 229 |
|
||||
| Materials | 0 | - | 0 | 250 | 250 |
|
||||
| Seeds | 0 | - | 0 | 150 | 150 |
|
||||
| **Subtotal** | **81** | **0** | **81** | **900** | **819** |
|
||||
|
||||
### 🏘️ World & Environment (Target: 4,000)
|
||||
| Asset Type | Current | Today | After | Target | Remaining |
|
||||
|:-----------|--------:|------:|------:|-------:|----------:|
|
||||
| Buildings | 16 | - | 16 | 500 | 484 |
|
||||
| Terrain Tiles | 0 | - | 0 | 800 | 800 |
|
||||
| Props | 0 | - | 0 | 600 | 600 |
|
||||
| Decorations | 0 | - | 0 | 400 | 400 |
|
||||
| **Subtotal** | **16** | **0** | **16** | **2,300** | **2,284** |
|
||||
|
||||
### 🧟 Enemies (Target: 1,200)
|
||||
| Asset Type | Current | Today | After | Target | Remaining |
|
||||
|:-----------|--------:|------:|------:|-------:|----------:|
|
||||
| Zombies | 68 | - | 68 | 300 | 232 |
|
||||
| Mutants | 0 | - | 0 | 150 | 150 |
|
||||
| Bosses | 0 | - | 0 | 80 | 80 |
|
||||
| Hybrids | 0 | - | 0 | 100 | 100 |
|
||||
| **Subtotal** | **68** | **0** | **68** | **630** | **562** |
|
||||
|
||||
### 🎨 UI & Effects (Target: 1,000)
|
||||
| Asset Type | Current | Today | After | Target | Remaining |
|
||||
|:-----------|--------:|------:|------:|-------:|----------:|
|
||||
| UI Elements | 24 | - | 24 | 400 | 376 |
|
||||
| VFX/Particles | 0 | - | 0 | 300 | 300 |
|
||||
| Icons | 0 | - | 0 | 200 | 200 |
|
||||
| **Subtotal** | **24** | **0** | **24** | **900** | **876** |
|
||||
|
||||
### 📦 Misc & Other (Target: 500)
|
||||
| Asset Type | Current | Today | After | Target | Remaining |
|
||||
|:-----------|--------:|------:|------:|-------:|----------:|
|
||||
| Ostalo | 169 | - | 169 | 500 | 331 |
|
||||
| **Subtotal** | **169** | **0** | **169** | **500** | **331** |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 GRAND TOTAL SUMMARY
|
||||
|
||||
| Metric | Value |
|
||||
|:-------|------:|
|
||||
| **Current Assets** | 752 PNG |
|
||||
| **Generated Today (Min)** | +216 PNG |
|
||||
| **Generated Today (Max)** | +516 PNG |
|
||||
| **Total After Today (Min)** | 968 PNG |
|
||||
| **Total After Today (Max)** | 1,268 PNG |
|
||||
| **Final Target** | 13,500 PNG |
|
||||
| **Remaining After Today (Min)** | 12,532 PNG |
|
||||
| **Remaining After Today (Max)** | 12,232 PNG |
|
||||
| **Current Progress** | 5.6% |
|
||||
| **Progress After Today (Min)** | 7.2% |
|
||||
| **Progress After Today (Max)** | 9.4% |
|
||||
|
||||
---
|
||||
|
||||
## 📅 PRODUCTION VELOCITY ESTIMATE
|
||||
|
||||
**Assuming 200-500 PNG per day**:
|
||||
- **Week 1**: 752 → 2,252 PNG (16.7%)
|
||||
- **Week 2**: 2,252 → 3,752 PNG (27.8%)
|
||||
- **Month 1**: 752 → 6,752 PNG (50%)
|
||||
- **Month 2**: 6,752 → 13,252 PNG (98.2%)
|
||||
- **ETA to 13,500**: **~45-60 days** (end of February 2026)
|
||||
|
||||
---
|
||||
|
||||
## ✅ TODAY'S GOALS
|
||||
|
||||
### Minimum Success Criteria:
|
||||
- [x] Current: 752 PNG
|
||||
- [ ] After Task 1.1: 848 PNG (+96 fauna)
|
||||
- [ ] After Task 1.2: 968 PNG (+120 animations)
|
||||
- [ ] **Target**: **968 PNG = 7.2%** ✅
|
||||
|
||||
### Stretch Goals:
|
||||
- [ ] Complete 1 Biome Pack: +100 PNG → 1,068 PNG (7.9%)
|
||||
- [ ] Complete 2 Biome Packs: +200 PNG → 1,168 PNG (8.7%)
|
||||
- [ ] Complete 3 Biome Packs: +300 PNG → 1,268 PNG (9.4%)
|
||||
- [ ] **Stretch Target**: **1,268 PNG = 9.4%** 🚀
|
||||
|
||||
---
|
||||
|
||||
## 🎆 NEXT MILESTONES
|
||||
|
||||
1. **1,000 PNG** - MVP Demo Ready (Today-Tomorrow)
|
||||
2. **2,500 PNG** - Kickstarter Launch (Week 2)
|
||||
3. **5,000 PNG** - Alpha 1.0 (Month 1)
|
||||
4. **8,000 PNG** - Alpha 2.0 (Month 2)
|
||||
5. **13,500 PNG** - Full Game Release (Month 2-3)
|
||||
|
||||
---
|
||||
|
||||
**Status**: 🚀 **PRODUCTION ACTIVE!**
|
||||
**Created**: 1.1.2026 @ 12:45
|
||||
**Last Count**: 752 PNG
|
||||
**Next Update**: After Task 1.1 completion
|
||||
104
CHARACTER_GENERATION_FINAL_PLAN.md
Normal file
104
CHARACTER_GENERATION_FINAL_PLAN.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# 🎯 CHARACTER ANIMATION GENERATION - FINAL PLAN
|
||||
|
||||
**Datum**: 1.1.2026
|
||||
**Status**: API Configured, Billing Enabled ✅
|
||||
|
||||
---
|
||||
|
||||
## ❌ **PROBLEM IDENTIFICIRAN:**
|
||||
|
||||
Google Gemini API **NE PODPIRA IMAGE GENERATION** preko REST API-ja!
|
||||
|
||||
- Gemini 2.0 Flash = **text generation model**
|
||||
- Imagen 3 = **ni dostopen preko Gemini API**
|
||||
- Image generation = **samo v AI Studio UI**
|
||||
|
||||
---
|
||||
|
||||
## ✅ **3 DELUJOČE ALTERNATIVE:**
|
||||
|
||||
### **Option 1: Google AI Studio Manual (DANES, ZASTONJ!)**
|
||||
|
||||
1. Pojdi na: https://aistudio.google.com
|
||||
2. Nov chat → Gemini Advanced (ker imaš naročnino!)
|
||||
3. Prompt: "Generate character Kai - green pink dreadlocks, age 17, walking animation frame 1, front view, bold outlines, transparent background"
|
||||
4. **Generate Image** button
|
||||
5. Download sliko
|
||||
6. Repeat za vse frame (58 frames = 1 ura ročnega dela)
|
||||
|
||||
**Pros**: Zastonj, dela takoj
|
||||
**Cons**: Ročno (58× ponavljanje)
|
||||
|
||||
---
|
||||
|
||||
### **Option 2: Bing Image Creator (DANES, UNLIMITED!)**
|
||||
|
||||
1. https://www.bing.com/create
|
||||
2. Sign in z Microsoft
|
||||
3. Paste prompt
|
||||
4. Generira 4 slike naenkrat!
|
||||
5. Download batch
|
||||
6. **UNLIMITED** - brez limitov!
|
||||
|
||||
**Pros**: Unlimited, hitro (4 slike/min)
|
||||
**Cons**: Microsoft račun potreben
|
||||
|
||||
---
|
||||
|
||||
### **Option 3: Leonardo.AI (DANES, 150 slik)**
|
||||
|
||||
1. https://leonardo.ai
|
||||
2. Sign up zastonj
|
||||
3. 150 credits/dan
|
||||
4. Batch generation možen
|
||||
5. API dostop
|
||||
|
||||
**Pros**: API iz Pythona, batch download
|
||||
**Cons**: 150/dan limit (need 3 dni za vse)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 **PRIPOROČILO:**
|
||||
|
||||
### **ZA DANES (Option 2 - Bing):**
|
||||
|
||||
1. **Setup** (2 min):
|
||||
- Pojdi na https://www.bing.com/create
|
||||
- Sign in
|
||||
|
||||
2. **Batch generacija** (2-3h):
|
||||
- Kopiraj prompte iz `CHARACTER_PRODUCTION_PLAN.md`
|
||||
- Paste v Bing
|
||||
- Download vse 4 slike
|
||||
- Repeat 15× (58 frames ÷ 4 = 15 batch-ov)
|
||||
|
||||
3. **Organize** (30 min):
|
||||
- Rename files (kai_walk_frame1.png, etc.)
|
||||
- Move v `assets/slike/kai/`, `ana/`, `gronk/`
|
||||
- Background removal batch
|
||||
|
||||
**Total čas**: ~3-4 ure
|
||||
**Cost**: ZASTONJ
|
||||
**Result**: Vse 58 essential frames ✅
|
||||
|
||||
---
|
||||
|
||||
## 💡 **ALI PA:**
|
||||
|
||||
**Za JUTRI** (Google AI Studio):
|
||||
- Pojdi na https://console.cloud.google.com/vertex-ai
|
||||
- Enable **Vertex AI Imagen API**
|
||||
- Potem ima pravilni API endpoint za image generation
|
||||
- Script bo delal!
|
||||
|
||||
---
|
||||
|
||||
## 📋 **NEXT STEPS:**
|
||||
|
||||
**Katera opcija izbirateš?**
|
||||
|
||||
1. **Bing Image Creator** → Dam ti prompte, ti generiraš ročno (3h)
|
||||
2. **Google AI Studio UI** → Dam ti prompte, generiraš v UI (1h)
|
||||
3. **Počakaj jutri** → Enableam Vertex AI, script avtomatsko (setup 10min potem 3h generacija)
|
||||
|
||||
**Povej mi!** 🎯
|
||||
270
CHARACTER_PRODUCTION_PLAN.md
Normal file
270
CHARACTER_PRODUCTION_PLAN.md
Normal file
@@ -0,0 +1,270 @@
|
||||
# 👥 GLAVNI KARAKTERJI - PRODUCTION PLAN
|
||||
|
||||
**Datum**: 1.1.2026
|
||||
**Status**: Planning Phase
|
||||
**Cilj**: Definirati vse potrebne assete za Kai, Ana, Gronk
|
||||
|
||||
---
|
||||
|
||||
## 📊 TRENUTNO STANJE
|
||||
|
||||
| Karakter | Trenutno | Master Ref | Animacije | Status |
|
||||
|:---------|:--------:|:----------:|:---------:|:------:|
|
||||
| **Kai** | 1 PNG | ✅ | ❌ | 🔴 NEED WORK |
|
||||
| **Ana** | 0 PNG | ✅ (konsistentno) | ❌ | 🔴 NEED WORK |
|
||||
| **Gronk** | 1 PNG | ✅ | ❌ | 🔴 NEED WORK |
|
||||
|
||||
**Locked References** (v `assets/slike/konsistentno/`):
|
||||
- ✅ `kai_master_styleA_reference.png`
|
||||
- ✅ `kai_master_styleB_reference.png`
|
||||
- ✅ `ana_master_styleA_reference.png`
|
||||
- ✅ `ana_master_styleB_reference.png`
|
||||
- ✅ `gronk_master_styleA_reference.png`
|
||||
- ✅ `gronk_master_styleB_reference.png`
|
||||
|
||||
---
|
||||
|
||||
## 🎮 KAJ POTREBUJEMO ZA VSAK KARAKTER?
|
||||
|
||||
### 🧑 **1. KAI (Protagonist - Zombie Whisperer)**
|
||||
|
||||
#### A. Osnovne Animacije (CRITICAL)
|
||||
| Animation | Frames | Directions | Total PNG | Prioriteta |
|
||||
|:----------|:------:|:----------:|:---------:|:----------:|
|
||||
| **Walk Cycle** | 4 | 8 (N,NE,E,SE,S,SW,W,NW) | 32 | 🔥 HIGH |
|
||||
| **Idle** | 4 | 2 (side, front) | 8 | 🔥 HIGH |
|
||||
| **Run** | 4 | 8 | 32 | 🔶 MEDIUM |
|
||||
| **SUBTOTAL** | - | - | **72** | - |
|
||||
|
||||
#### B. Action Animacije (GAMEPLAY)
|
||||
| Action | Frames | Directions | Total PNG | Prioriteta |
|
||||
|:-------|:------:|:----------:|:---------:|:----------:|
|
||||
| **Attack (Sword/Melee)** | 4 | 4 (N,E,S,W) | 16 | 🔥 HIGH |
|
||||
| **Dig (Shovel)** | 4 | 4 | 16 | 🔥 HIGH |
|
||||
| **Plant (Seeds)** | 3 | 2 | 6 | 🔶 MEDIUM |
|
||||
| **Harvest** | 3 | 2 | 6 | 🔶 MEDIUM |
|
||||
| **Drink/Eat** | 3 | 1 | 3 | 🔷 LOW |
|
||||
| **Use Item** | 3 | 2 | 6 | 🔷 LOW |
|
||||
| **SUBTOTAL** | - | - | **53** | - |
|
||||
|
||||
#### C. Emotional/Story Animacije (CUTSCENE)
|
||||
| Animation | Frames | Total PNG | Prioriteta |
|
||||
|:----------|:------:|:---------:|:----------:|
|
||||
| **Sad/Crying** | 4 | 4 | 🔷 LOW |
|
||||
| **Happy/Celebrate** | 4 | 4 | 🔷 LOW |
|
||||
| **Thinking** | 3 | 3 | 🔷 LOW |
|
||||
| **Shocked** | 2 | 2 | 🔷 LOW |
|
||||
| **SUBTOTAL** | - | **13** | - |
|
||||
|
||||
#### D. Combat Special (ALPHA 2.0)
|
||||
| Animation | Frames | Total PNG | Prioriteta |
|
||||
|:----------|:------:|:---------:|:----------:|
|
||||
| **Zombie Command** (gesture) | 4 | 4 | 🔵 LATER |
|
||||
| **Telepathy Effect** | 6 | 6 | 🔵 LATER |
|
||||
| **Hurt/Damaged** | 3 | 3 | 🔶 MEDIUM |
|
||||
| **Death** | 5 | 5 | 🔷 LOW |
|
||||
| **SUBTOTAL** | - | **18** | - |
|
||||
|
||||
### **KAI TOTAL: 156 PNG**
|
||||
|
||||
---
|
||||
|
||||
### 💜 **2. ANA (Twin Sister - Scientist)**
|
||||
|
||||
#### A. Osnovne Animacije (CRITICAL)
|
||||
| Animation | Frames | Directions | Total PNG | Prioriteta |
|
||||
|:----------|:------:|:----------:|:---------:|:----------:|
|
||||
| **Walk Cycle** | 4 | 8 | 32 | 🔥 HIGH |
|
||||
| **Idle** | 4 | 2 | 8 | 🔥 HIGH |
|
||||
| **Run** | 4 | 8 | 32 | 🔶 MEDIUM |
|
||||
| **SUBTOTAL** | - | - | **72** | - |
|
||||
|
||||
#### B. Action Animacije (SCIENTIST THEME)
|
||||
| Action | Frames | Directions | Total PNG | Prioriteta |
|
||||
|:-------|:------:|:----------:|:---------:|:----------:|
|
||||
| **Research** (notebook) | 4 | 2 | 8 | 🔥 HIGH |
|
||||
| **Heal** (apply bandage) | 4 | 2 | 8 | 🔥 HIGH |
|
||||
| **Examine** (magnifying glass) | 3 | 2 | 6 | 🔶 MEDIUM |
|
||||
| **Mix Potion** | 4 | 1 | 4 | 🔶 MEDIUM |
|
||||
| **Collect Sample** | 3 | 2 | 6 | 🔷 LOW |
|
||||
| **SUBTOTAL** | - | - | **32** | - |
|
||||
|
||||
#### C. Emotional/Story (TWIN BOND THEME)
|
||||
| Animation | Frames | Total PNG | Prioriteta |
|
||||
|:----------|:------:|:---------:|:----------:|
|
||||
| **Worried** | 4 | 4 | 🔥 HIGH (story) |
|
||||
| **Relief** | 4 | 4 | 🔥 HIGH (story) |
|
||||
| **Twin Bond Glow** | 6 | 6 | 🔶 MEDIUM |
|
||||
| **Flashback Pose** | 3 | 3 | 🔷 LOW |
|
||||
| **SUBTOTAL** | - | **17** | - |
|
||||
|
||||
#### D. Combat/Support (SUPPORT ROLE)
|
||||
| Animation | Frames | Total PNG | Prioriteta |
|
||||
|:----------|:------:|:---------:|:----------:|
|
||||
| **Defend** (staff block) | 4 | 4 | 🔶 MEDIUM |
|
||||
| **Cure Cast** | 5 | 5 | 🔶 MEDIUM |
|
||||
| **Hurt** | 3 | 3 | 🔷 LOW |
|
||||
| **Death** | 5 | 5 | 🔷 LOW |
|
||||
| **SUBTOTAL** | - | **17** | - |
|
||||
|
||||
### **ANA TOTAL: 138 PNG**
|
||||
|
||||
---
|
||||
|
||||
### 💚 **3. GRONK (Zen Troll - Comic Relief)**
|
||||
|
||||
#### A. Osnovne Animacije (CRITICAL)
|
||||
| Animation | Frames | Directions | Total PNG | Prioriteta |
|
||||
|:----------|:------:|:----------:|:---------:|:----------:|
|
||||
| **Walk Cycle** (heavy) | 4 | 8 | 32 | 🔥 HIGH |
|
||||
| **Idle** (chill stance) | 4 | 2 | 8 | 🔥 HIGH |
|
||||
| **Run** (slow lumbering) | 4 | 8 | 32 | 🔶 MEDIUM |
|
||||
| **SUBTOTAL** | - | - | **72** | - |
|
||||
|
||||
#### B. Action Animacije (TROLL THEME)
|
||||
| Action | Frames | Directions | Total PNG | Prioriteta |
|
||||
|:-------|:------:|:----------:|:---------:|:----------:|
|
||||
| **Vape** 💨 (signature!) | 6 | 2 | 12 | 🔥 HIGH |
|
||||
| **Smash** (club attack) | 5 | 4 | 20 | 🔥 HIGH |
|
||||
| **Lift Heavy** | 4 | 2 | 8 | 🔶 MEDIUM |
|
||||
| **Meditate** (zen pose) | 4 | 1 | 4 | 🔷 LOW |
|
||||
| **SUBTOTAL** | - | - | **44** | - |
|
||||
|
||||
#### C. Emotional (COMIC RELIEF)
|
||||
| Animation | Frames | Total PNG | Prioriteta |
|
||||
|:----------|:------:|:---------:|:----------:|
|
||||
| **Laugh** | 4 | 4 | 🔶 MEDIUM |
|
||||
| **Confused** | 3 | 3 | 🔷 LOW |
|
||||
| **Chill/Relaxed** | 3 | 3 | 🔷 LOW |
|
||||
| **SUBTOTAL** | - | **10** | - |
|
||||
|
||||
#### D. Combat (TANK ROLE)
|
||||
| Animation | Frames | Total PNG | Prioriteta |
|
||||
|:----------|:------:|:---------:|:----------:|
|
||||
| **Block** (shield up) | 3 | 3 | 🔶 MEDIUM |
|
||||
| **Taunt** | 4 | 4 | 🔷 LOW |
|
||||
| **Hurt** | 3 | 3 | 🔶 MEDIUM |
|
||||
| **Death** | 5 | 5 | 🔷 LOW |
|
||||
| **SUBTOTAL** | - | **15** | - |
|
||||
|
||||
### **GRONK TOTAL: 141 PNG**
|
||||
|
||||
---
|
||||
|
||||
## 📊 GRAND TOTAL SUMMARY
|
||||
|
||||
| Character | Walk/Run | Actions | Emotions | Combat | TOTAL |
|
||||
|:----------|:--------:|:-------:|:--------:|:------:|------:|
|
||||
| **Kai** | 72 | 53 | 13 | 18 | **156** |
|
||||
| **Ana** | 72 | 32 | 17 | 17 | **138** |
|
||||
| **Gronk** | 72 | 44 | 10 | 15 | **141** |
|
||||
| **GRAND TOTAL** | **216** | **129** | **40** | **50** | **435** |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 PHASED PRODUCTION STRATEGY
|
||||
|
||||
### **PHASE 1: CORE GAMEPLAY** (Priority 🔥 HIGH)
|
||||
**Cilj**: Playable characters z basic animations
|
||||
|
||||
| Character | Animations | PNG Count | Čas Est. |
|
||||
|:----------|:-----------|:---------:|:--------:|
|
||||
| Kai | Walk (32) + Idle (8) + Attack (16) + Dig (16) | 72 | 1.5h |
|
||||
| Ana | Walk (32) + Idle (8) + Research (8) + Heal (8) | 56 | 1h |
|
||||
| Gronk | Walk (32) + Idle (8) + Vape (12) + Smash (20) | 72 | 1.5h |
|
||||
| **PHASE 1 TOTAL** | - | **200 PNG** | **~4h** |
|
||||
|
||||
---
|
||||
|
||||
### **PHASE 2: EXPANDED GAMEPLAY** (Priority 🔶 MEDIUM)
|
||||
**Cilj**: More actions + story emotions
|
||||
|
||||
| Character | Animations | PNG Count | Čas Est. |
|
||||
|:----------|:-----------|:---------:|:--------:|
|
||||
| Kai | Run (32) + Plant (6) + Harvest (6) + Hurt (3) | 47 | 1h |
|
||||
| Ana | Run (32) + Examine (6) + Mix (4) + Worried (4) | 46 | 1h |
|
||||
| Gronk | Run (32) + Lift (8) + Laugh (4) + Hurt (3) | 47 | 1h |
|
||||
| **PHASE 2 TOTAL** | - | **140 PNG** | **~3h** |
|
||||
|
||||
---
|
||||
|
||||
### **PHASE 3: POLISH & CUTSCENES** (Priority 🔷 LOW)
|
||||
**Cilj**: Full emotional range + story sequences
|
||||
|
||||
| Character | Animations | PNG Count | Čas Est. |
|
||||
|:----------|:-----------|:---------:|:--------:|
|
||||
| Kai | Emotions (13) + Use Item (6) + Eat (3) + Death (5) | 27 | 45 min |
|
||||
| Ana | Twin Bond (6) + Flashback (3) + Death (5) + Relief (4) | 18 | 30 min |
|
||||
| Gronk | Meditate (4) + Confused (3) + Taunt (4) + Death (5) | 16 | 30 min |
|
||||
| **PHASE 3 TOTAL** | - | **61 PNG** | **~2h** |
|
||||
|
||||
---
|
||||
|
||||
### **PHASE 4: ADVANCED SYSTEMS** (Priority 🔵 ALPHA 2.0)
|
||||
**Cilj**: Special abilities + effects
|
||||
|
||||
| Character | Animations | PNG Count | Čas Est. |
|
||||
|:----------|:-----------|:---------:|:--------:|
|
||||
| Kai | Zombie Command (4) + Telepathy (6) | 10 | 20 min |
|
||||
| Ana | Collect Sample (6) + Cure Cast (5) | 11 | 20 min |
|
||||
| Gronk | Block (3) + Chill (3) | 6 | 15 min |
|
||||
| **PHASE 4 TOTAL** | - | **27 PNG** | **~1h** |
|
||||
|
||||
---
|
||||
|
||||
## ✅ PRODUCTION TIMELINE ESTIMATE
|
||||
|
||||
| Phase | PNG Output | Čas | Prioriteta | Kdaj? |
|
||||
|:------|:----------:|:---:|:----------:|:-----:|
|
||||
| **Phase 1: Core** | 200 | 4h | 🔥 CRITICAL | **Danes!** |
|
||||
| **Phase 2: Expanded** | 140 | 3h | 🔶 HIGH | Jutri |
|
||||
| **Phase 3: Polish** | 61 | 2h | 🔷 MEDIUM | Dan 3 |
|
||||
| **Phase 4: Advanced** | 27 | 1h | 🔵 LOW | Alpha 2.0 |
|
||||
| **TOTAL** | **428** | **10h** | - | Week 1 |
|
||||
|
||||
---
|
||||
|
||||
## 🎨 ART STYLE REQUIREMENTS
|
||||
|
||||
### Vsak karakter rabi 2 verzije:
|
||||
- **Style A** (Cartoon): Bright colors, bold outlines
|
||||
- **Style B** (Noir): Dark, gritty, high contrast
|
||||
|
||||
**Total PNG × 2 = 856 PNG** (if doing both styles)
|
||||
|
||||
---
|
||||
|
||||
## 📝 GENERATION STRATEGY
|
||||
|
||||
### Option A: Batch Generation (Recommended)
|
||||
1. Generate ALL Phase 1 animations for Kai (72 PNG) - 1.5h
|
||||
2. Generate ALL Phase 1 animations for Ana (56 PNG) - 1h
|
||||
3. Generate ALL Phase 1 animations for Gronk (72 PNG) - 1.5h
|
||||
4. Background removal batch - 30 min
|
||||
5. **TOTAL TODAY: 200 PNG in 4.5h**
|
||||
|
||||
### Option B: Character-by-Character
|
||||
1. Kai complete (156 PNG) - 3h
|
||||
2. Ana complete (138 PNG) - 3h
|
||||
3. Gronk complete (141 PNG) - 3h
|
||||
4. **TOTAL: 435 PNG in 9h** (full day)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 RECOMMENDED PLAN FOR TODAY
|
||||
|
||||
**Session 1 (Morning - 2h):**
|
||||
- [ ] Generate Kai Phase 1 (72 PNG)
|
||||
- [ ] Background removal
|
||||
|
||||
**Session 2 (Afternoon - 2h):**
|
||||
- [ ] Generate Ana Phase 1 (56 PNG)
|
||||
- [ ] Generate Gronk Phase 1 (72 PNG)
|
||||
|
||||
**RESULT**: ✅ **200 PNG - All 3 characters playable!**
|
||||
|
||||
---
|
||||
|
||||
**Created**: 1.1.2026 @ 12:51
|
||||
**Status**: 📋 **PLAN READY - AWAITING EXECUTION**
|
||||
**Next Step**: Start Phase 1 generation OR adjust plan based on feedback
|
||||
86
COMFYUI_SETUP_TODAY.md
Normal file
86
COMFYUI_SETUP_TODAY.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# 🎯 COMFYUI SETUP - DANES!
|
||||
|
||||
**Datum**: 1.1.2026
|
||||
**Status**: ComfyUI app found ✅
|
||||
**Cilj**: Generate slike kot včeraj!
|
||||
|
||||
---
|
||||
|
||||
## ✅ **KAJ SEM NAŠEL:**
|
||||
|
||||
Včeraj si uporabljal **ComfyUI.app**!
|
||||
|
||||
Scripts ki so delali:
|
||||
- `test_hybrid_comfyui.py`
|
||||
- `generate_assets_local.py`
|
||||
- `generate_v63_stardew.py`
|
||||
|
||||
Vsi kličejo:
|
||||
- `http://127.0.0.1:8188` (ComfyUI server)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 **KAJ MORAŠ NAREDITI (3 KORAKI):**
|
||||
|
||||
### **KORAK 1: Zaženi ComfyUI app**
|
||||
|
||||
**Ročno odpri:**
|
||||
1. Pojdi v Finder
|
||||
2. Applications folder
|
||||
3. Dvojni klik na **ComfyUI.app**
|
||||
4. Počakaj da se zažene (1-2min)
|
||||
5. Odpre se browser window na `http://127.0.0.1:8188`
|
||||
|
||||
**ALI iz terminala:**
|
||||
```bash
|
||||
open /Applications/ComfyUI.app
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### **KORAK 2: Preveri da teče**
|
||||
|
||||
Ko se ComfyUI odpre v browser-ju, v terminalu testiraj:
|
||||
|
||||
```bash
|
||||
curl -s http://127.0.0.1:8188/system_stats
|
||||
```
|
||||
|
||||
**Če dela → vidiš JSON z "comfyui_version"**
|
||||
**Če NE dela → počakaj še malo (app se še zaganja)**
|
||||
|
||||
---
|
||||
|
||||
### **KORAK 3: Poženi generation script**
|
||||
|
||||
Ko ComfyUI teče, poženi:
|
||||
|
||||
```bash
|
||||
cd /Users/davidkotnik/repos/novafarma
|
||||
python3 scripts/test_hybrid_comfyui.py
|
||||
```
|
||||
|
||||
**To bo generiralo test slike!**
|
||||
|
||||
---
|
||||
|
||||
## 📝 **POTEM:**
|
||||
|
||||
Ko test dela, lahko poganjamo **full character generation** script ki uporablja ComfyUI!
|
||||
|
||||
Naredim ti script ki generira vse 58 essential frames preko ComfyUI (kot včeraj).
|
||||
|
||||
---
|
||||
|
||||
## ⚡ **QUICKSTART:**
|
||||
|
||||
1. **Odpri ComfyUI.app** (dvojni klik v Applications)
|
||||
2. **Počakaj** da se zažene (1-2 min)
|
||||
3. **Povej mi** ko se odpre browser window
|
||||
4. **Poženem** generation script!
|
||||
|
||||
---
|
||||
|
||||
**STATUS**: Ready! ComfyUI app je instaliran, samo zagnati ga moraš! 🚀
|
||||
|
||||
**Pošlji mi screenshot ko se ComfyUI odpre!**
|
||||
587
TASKS_01_01_2026.md
Normal file
587
TASKS_01_01_2026.md
Normal file
@@ -0,0 +1,587 @@
|
||||
# 🎯 TASKS - 1.1.2026 (SREČNO NOVO LETO!)
|
||||
|
||||
**Datum**: 1.1.2026
|
||||
**Status**: API Kvota RESET @ 01:00 CET ✅
|
||||
**Cilj**: Masovna produkcija asset-ov + System Integration
|
||||
|
||||
---
|
||||
|
||||
## 🚀 PRIORITETA 1: ASSET GENERATION (GLAVNA PRIORITETA!)
|
||||
|
||||
### ✅ Status Check
|
||||
- [x] Dino Valley fauna (32/32 PNG) - **COMPLETE!** ✅
|
||||
- [x] API kvota reset - **READY!** ✅
|
||||
- [x] Scripts pripravļjeni - **READY!** ✅
|
||||
|
||||
### 🎨 Task 1.1: Generate Anomalous Zone Fauna (96 PNG)
|
||||
**Čas**: 90 min
|
||||
**Prioriteta**: 🔥 CRITICAL
|
||||
**Script**: `scripts/generate_anomalous_fauna.py`
|
||||
|
||||
**8 Zon za generirati**:
|
||||
1. Mythical Highlands (12 PNG) - unicorns, dragons, griffins
|
||||
2. Endless Forest (12 PNG) - bigfoot, wendigo, forest spirits
|
||||
3. Loch Ness (12 PNG) - Nessie, leprechauns, kelpies
|
||||
4. Egyptian Desert (12 PNG) - mummies, scarabs, anubis
|
||||
5. Amazonas (12 PNG) - jaguars, anacondas, piranhas
|
||||
6. Atlantis (12 PNG) - mermaids, sea serpents, dolphins
|
||||
7. Chernobyl (12 PNG) - radioactive mutants, troll king
|
||||
8. Catacombs (12 PNG) - skeletons, ghosts, lich
|
||||
|
||||
**Action**:
|
||||
```bash
|
||||
cd /Users/davidkotnik/repos/novafarma
|
||||
python scripts/generate_anomalous_fauna.py
|
||||
```
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Poženi script
|
||||
- [ ] Preveri da vse slike generira (96 PNG)
|
||||
- [ ] Run background removal
|
||||
- [ ] Preveri kvaliteto
|
||||
- [ ] Commit to git
|
||||
|
||||
---
|
||||
|
||||
### 👤 Task 1.2: Generate Character Animations (120 PNG)
|
||||
**Čas**: 2h
|
||||
**Prioriteta**: 🔥 CRITICAL
|
||||
**Script**: `scripts/generate_character_animations.py`
|
||||
|
||||
**Characters**:
|
||||
- Kai (40 PNG) - walk cycle 8-way, idle, attack, dig, plant
|
||||
- Ana (40 PNG) - walk cycle 8-way, idle, research, heal
|
||||
- Gronk (40 PNG) - walk cycle 8-way, idle, vape, smash
|
||||
|
||||
**Action**:
|
||||
```bash
|
||||
cd /Users/davidkotnik/repos/novafarma
|
||||
python scripts/generate_character_animations.py
|
||||
```
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Poženi script
|
||||
- [ ] Preveri animacije (smooth transitions)
|
||||
- [ ] Background removal batch
|
||||
- [ ] Organize v `assets/slike/kai/`, `ana/`, `gronk/`
|
||||
- [ ] Commit to git
|
||||
|
||||
---
|
||||
|
||||
### 🌍 Task 1.3: Complete 2-3 Biome Asset Packs (Optional)
|
||||
**Čas**: 3-4h
|
||||
**Prioriteta**: 🔶 HIGH
|
||||
**Script**: Adapt existing scripts
|
||||
|
||||
**Priority Biomes**:
|
||||
1. **Mexican Cenotes** - axolotls, cave crystals, mayan gear
|
||||
2. **Witch Forest** - witches, potions, dark magic items
|
||||
3. **Mythical Highlands** - expand from fauna task
|
||||
|
||||
**Per Biome** (~100 PNG each):
|
||||
- Fauna (12) - from Task 1.1
|
||||
- Clothing (15) - theme-specific outfits
|
||||
- Weapons (10) - unique to biome
|
||||
- Food (10) - regional cuisine
|
||||
- Materials (15) - crafting resources
|
||||
- Terrain (10) - ground tiles
|
||||
- Vegetation (15) - plants/trees
|
||||
- Props (10) - decorations
|
||||
- Buildings (3) - structures
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Choose 2-3 biomes
|
||||
- [ ] Create/adapt generation script
|
||||
- [ ] Generate all assets
|
||||
- [ ] Background removal
|
||||
- [ ] Organize v `assets/slike/[biome_name]/`
|
||||
- [ ] Commit to git
|
||||
|
||||
---
|
||||
|
||||
### 🎯 Task 1.4: Background Removal Batch Processing
|
||||
**Čas**: 30 min
|
||||
**Prioriteta**: 🔶 HIGH
|
||||
**Script**: `scripts/remove_bg_advanced.py`
|
||||
|
||||
**Action**:
|
||||
```bash
|
||||
cd /Users/davidkotnik/repos/novafarma
|
||||
python scripts/remove_bg_advanced.py
|
||||
```
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Run na vse novo generirane PNG
|
||||
- [ ] Preveri alpha channels
|
||||
- [ ] Resize na game-ready dimensions
|
||||
- [ ] Create previews
|
||||
|
||||
---
|
||||
|
||||
## 🔧 PRIORITETA 2: SYSTEM INTEGRATION
|
||||
|
||||
### 🧪 Task 2.1: Basic Smoke Test
|
||||
**Čas**: 10 min
|
||||
**Prioriteta**: 🔥 CRITICAL (FIRST!)
|
||||
**File**: Trenutna igra
|
||||
|
||||
**Test Checklist**:
|
||||
- [ ] Odpri igro (npm start)
|
||||
- [ ] Preveri Console za errors
|
||||
- [ ] Player spawna?
|
||||
- [ ] WASD movement dela?
|
||||
- [ ] Inventory (I key) dela?
|
||||
- [ ] Crafting (C key) dela?
|
||||
- [ ] Save system (F5) dela?
|
||||
|
||||
**Če vse dela → nadaljuj Task 2.2**
|
||||
**Če NE dela → FIX najprej!**
|
||||
|
||||
---
|
||||
|
||||
### ⚙️ Task 2.2: Initialize New Systems in GameScene
|
||||
**Čas**: 1h
|
||||
**Prioriteta**: 🔥 CRITICAL
|
||||
**File**: `src/scenes/GameScene.js`
|
||||
|
||||
**Action**: Dodaj v `create()` function (po line ~800):
|
||||
|
||||
```javascript
|
||||
// ========================================================
|
||||
// 🆕 NEW SYSTEMS (P16-P30) - 1.1.2026
|
||||
// ========================================================
|
||||
console.log('🆕 Initializing New Systems (P16-P30)...');
|
||||
|
||||
// P16: Mining System
|
||||
console.log('⛏️ Initializing Mining System...');
|
||||
this.miningSystem = new MiningSystem(this);
|
||||
|
||||
// P17: Character Customization
|
||||
console.log('👤 Initializing Character Customization...');
|
||||
this.characterCustomization = new CharacterCustomizationSystem(this);
|
||||
|
||||
// P19: Town Restoration
|
||||
console.log('🏘️ Initializing Town Restoration...');
|
||||
this.townRestoration = new TownRestorationSystem(this);
|
||||
|
||||
// P20: Portal Repair
|
||||
console.log('🌀 Initializing Portal Repair...');
|
||||
this.portalRepair = new PortalRepairSystem(this);
|
||||
|
||||
// P22: Smart Zombies
|
||||
console.log('🧠 Initializing Smart Zombies...');
|
||||
this.smartZombies = new SmartZombieSystem(this);
|
||||
|
||||
// P23: Tool System
|
||||
console.log('🔧 Initializing Tool System...');
|
||||
this.toolSystem = new ToolSystem(this);
|
||||
|
||||
// P25: Ana's Clues
|
||||
console.log('💜 Initializing Ana Clues...');
|
||||
this.anaClues = new AnaClueSystem(this);
|
||||
|
||||
// P26: Pyramids
|
||||
console.log('🏜️ Initializing Pyramid System...');
|
||||
this.pyramids = new PyramidSystem(this);
|
||||
|
||||
// P27: Slimes & Dogs
|
||||
console.log('🟢🐶 Initializing Slimes & Dogs...');
|
||||
this.slimesDogs = new SlimesDogsSystem(this);
|
||||
|
||||
// P28: Animals & Seeds
|
||||
console.log('🐄🌱 Initializing Animals & Seeds...');
|
||||
this.animalsSeeds = new AnimalsSeedsSystem(this);
|
||||
|
||||
// P29: Automation
|
||||
console.log('⚙️ Initializing Automation...');
|
||||
this.automation = new AutomationSystem(this);
|
||||
|
||||
// P30: Inventory Expanded
|
||||
console.log('🎒 Initializing Inventory Expansion...');
|
||||
this.inventoryExpanded = new InventorySystemExpanded(this, this.inventorySystem);
|
||||
|
||||
console.log('✅ All New Systems Initialized!');
|
||||
```
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Odpri `src/scenes/GameScene.js`
|
||||
- [ ] Najdi `create()` function
|
||||
- [ ] Dodaj kodo
|
||||
- [ ] Shrani
|
||||
- [ ] Test reload (preveri Console za "✅ All New Systems Initialized!")
|
||||
|
||||
---
|
||||
|
||||
### 🔄 Task 2.3: Add System Updates to update() Loop
|
||||
**Čas**: 30 min
|
||||
**Prioriteta**: 🔥 CRITICAL
|
||||
**File**: `src/scenes/GameScene.js`
|
||||
|
||||
**Action**: Dodaj v `update(time, delta)` function:
|
||||
|
||||
```javascript
|
||||
update(time, delta) {
|
||||
// ... existing update code ...
|
||||
|
||||
// 🆕 NEW: Daily automation
|
||||
if (this.automation) {
|
||||
const currentDay = Math.floor(time / 86400000); // ms to days
|
||||
if (currentDay !== this.lastDay) {
|
||||
this.automation.runDailyAutomation();
|
||||
this.lastDay = currentDay;
|
||||
}
|
||||
}
|
||||
|
||||
// 🆕 NEW: Animal updates
|
||||
if (this.animalsSeeds) {
|
||||
this.animalsSeeds.updateLivestock();
|
||||
}
|
||||
|
||||
// 🆕 NEW: Smart zombie updates
|
||||
if (this.smartZombies) {
|
||||
this.smartZombies.updateZombies(delta);
|
||||
}
|
||||
|
||||
// 🆕 NEW: Town construction
|
||||
if (this.townRestoration) {
|
||||
this.townRestoration.updateConstruction(delta);
|
||||
}
|
||||
|
||||
// 🆕 NEW: Portal construction
|
||||
if (this.portalRepair) {
|
||||
this.portalRepair.updateConstruction(delta);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Najdi `update(time, delta)` function
|
||||
- [ ] Dodaj kodo
|
||||
- [ ] Shrani
|
||||
- [ ] Test: preveri da sistemi tečejo (Console logs)
|
||||
|
||||
---
|
||||
|
||||
### 🔗 Task 2.4: Connect System Communications
|
||||
**Čas**: 1h
|
||||
**Prioriteta**: 🔶 HIGH
|
||||
**File**: `src/scenes/GameScene.js`
|
||||
|
||||
**Action**: Dodaj v `create()` function (PO inicializaciji sistemov):
|
||||
|
||||
```javascript
|
||||
// ========================================================
|
||||
// 🔗 SYSTEM CONNECTIONS
|
||||
// ========================================================
|
||||
console.log('🔗 Connecting Systems...');
|
||||
|
||||
// A. SmartZombies ↔ ZombieSystem
|
||||
if (this.smartZombies && this.zombieSystem) {
|
||||
this.smartZombies.baseZombieSystem = this.zombieSystem;
|
||||
}
|
||||
|
||||
// B. ToolSystem ↔ InventorySystem
|
||||
if (this.toolSystem && this.inventorySystem) {
|
||||
this.toolSystem.inventorySystem = this.inventorySystem;
|
||||
}
|
||||
|
||||
// C. AnaClues ↔ TwinBondSystem
|
||||
if (this.anaClues && this.twinBondSystem) {
|
||||
this.anaClues.onClueFound = (clueId) => {
|
||||
this.twinBondSystem.triggerMemory(clueId);
|
||||
};
|
||||
}
|
||||
|
||||
// D. Automation ↔ Multiple Systems
|
||||
if (this.automation) {
|
||||
this.automation.farmingSystem = this.farmingSystem;
|
||||
this.automation.smartZombies = this.smartZombies;
|
||||
this.automation.inventoryExpanded = this.inventoryExpanded;
|
||||
}
|
||||
|
||||
console.log('✅ Systems Connected!');
|
||||
```
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Dodaj kodo
|
||||
- [ ] Shrani
|
||||
- [ ] Test: preveri da sistemi komunicirajo
|
||||
|
||||
---
|
||||
|
||||
### 🧪 Task 2.5: Full Integration Test
|
||||
**Čas**: 30 min
|
||||
**Prioriteta**: 🔶 HIGH
|
||||
|
||||
**Test Checklist**:
|
||||
- [ ] Igra se zažene brez napak
|
||||
- [ ] Vsi 46 sistemov inicializirani (Console check)
|
||||
- [ ] Player movement dela
|
||||
- [ ] Inventory dela
|
||||
- [ ] Crafting dela
|
||||
- [ ] Mining works (zberi resource)
|
||||
- [ ] Tool durability dela
|
||||
- [ ] Save/Load dela
|
||||
- [ ] No memory leaks (check after 5 min gameplay)
|
||||
- [ ] 60 FPS maintained
|
||||
|
||||
---
|
||||
|
||||
## 🎨 PRIORITETA 3: UI CREATION (OPTIONAL)
|
||||
|
||||
### 👤 Task 3.1: Character Creation Scene (Critical)
|
||||
**Čas**: 2h
|
||||
**Prioriteta**: 🔶 HIGH
|
||||
**File**: `src/scenes/CharacterCreationScene.js` (CREATE NEW)
|
||||
|
||||
**Features Needed**:
|
||||
- Gender selection (Kai/Ana radio buttons)
|
||||
- Hair color picker (RGB sliders)
|
||||
- Body customization (sliders)
|
||||
- Outfit selection (grid of icons)
|
||||
- Preview window (live update)
|
||||
- "Start Game" button
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Create file
|
||||
- [ ] Implement UI layout
|
||||
- [ ] Wire up to CharacterCustomizationSystem
|
||||
- [ ] Add to index.html
|
||||
- [ ] Test flow (creation → game start)
|
||||
|
||||
---
|
||||
|
||||
### 🧟 Task 3.2: Smart Zombie Command UI
|
||||
**Čas**: 1h
|
||||
**Prioriteta**: 🔷 MEDIUM
|
||||
**File**: `src/ui/SmartZombieUI.js` (CREATE NEW)
|
||||
|
||||
**Features Needed**:
|
||||
- Zombie list (scrollable)
|
||||
- Command buttons: Stop, Help, Attack, Home
|
||||
- Follower count display
|
||||
- XP/Level display per zombie
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Create file
|
||||
- [ ] Implement UI
|
||||
- [ ] Wire up to SmartZombieSystem
|
||||
- [ ] Add to index.html
|
||||
- [ ] Test commands
|
||||
|
||||
---
|
||||
|
||||
### 💜 Task 3.3: Ana's Clue Collection UI
|
||||
**Čas**: 1h
|
||||
**Prioriteta**: 🔷 MEDIUM
|
||||
**File**: `src/ui/AnaClueUI.js` (CREATE NEW)
|
||||
|
||||
**Features Needed**:
|
||||
- Progress tracker (15/12/23 clues)
|
||||
- Gallery view (grid of clues)
|
||||
- Story milestone indicators
|
||||
- Clue descriptions on hover/click
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Create file
|
||||
- [ ] Implement gallery layout
|
||||
- [ ] Wire up to AnaClueSystem
|
||||
- [ ] Add to index.html
|
||||
- [ ] Test clue discovery flow
|
||||
|
||||
---
|
||||
|
||||
### 🎒 Task 3.4: Inventory Upgrade UI
|
||||
**Čas**: 45 min
|
||||
**Prioriteta**: 🔷 MEDIUM
|
||||
**File**: `src/ui/InventoryUpgradeUI.js` (CREATE NEW)
|
||||
|
||||
**Features Needed**:
|
||||
- Tier upgrade menu (Tier 1 → Tier 5)
|
||||
- Tool Belt unlock button
|
||||
- Dog Backpack unlock button
|
||||
- Quick Sort/Stack/Deposit buttons
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Create file
|
||||
- [ ] Implement upgrade interface
|
||||
- [ ] Wire up to InventorySystemExpanded
|
||||
- [ ] Add to index.html
|
||||
- [ ] Test upgrades
|
||||
|
||||
---
|
||||
|
||||
## 🗺️ PRIORITETA 4: TILED MAPS (OPTIONAL)
|
||||
|
||||
### 📥 Task 4.1: Import Tilesets to Tiled
|
||||
**Čas**: 15 min
|
||||
**Prioriteta**: 🔷 MEDIUM
|
||||
|
||||
**Action**:
|
||||
1. Odpri Tiled Map Editor
|
||||
2. Map → Add External Tileset
|
||||
3. Browse → `assets/tilesets/*.tsx`
|
||||
4. Import vseh 61 TSX files
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Tiled installed
|
||||
- [ ] Import all TSX
|
||||
- [ ] Preview tilesets (check visibility)
|
||||
|
||||
---
|
||||
|
||||
### 🗺️ Task 4.2: Create Starter Map (16x16)
|
||||
**Čas**: 30 min
|
||||
**Prioriteta**: 🔷 MEDIUM
|
||||
|
||||
**Action**:
|
||||
1. New Map → 16x16 tiles, 32x32 tile size
|
||||
2. Add layers:
|
||||
- Ground (base terrain)
|
||||
- Decoration (trees, rocks)
|
||||
- Collision (invisible)
|
||||
- Objects (player spawn point)
|
||||
3. Paint basic starter area
|
||||
4. Add player spawn object (x:8, y:8)
|
||||
5. Save as `starter_farm_16x16.tmx`
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Create map
|
||||
- [ ] Add layers
|
||||
- [ ] Paint terrain
|
||||
- [ ] Add spawn point
|
||||
- [ ] Save TMX
|
||||
|
||||
---
|
||||
|
||||
### 📤 Task 4.3: Export Map to JSON
|
||||
**Čas**: 5 min
|
||||
**Prioriteta**: 🔷 MEDIUM
|
||||
|
||||
**Action**:
|
||||
1. File → Export As → JSON
|
||||
2. Save v `assets/maps/starter_farm_16x16.json`
|
||||
3. Test load v igri (TiledTestScene.js)
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Export to JSON
|
||||
- [ ] Preveri JSON syntax
|
||||
- [ ] Test load v igri
|
||||
|
||||
---
|
||||
|
||||
## 🐛 PRIORITETA 5: BUG REVIEW (OPTIONAL)
|
||||
|
||||
### 🔍 Task 5.1: Code Audit
|
||||
**Čas**: 1h
|
||||
**Prioriteta**: 🔵 LOW
|
||||
|
||||
**Action**: Review kode za:
|
||||
- Console errors
|
||||
- Performance bottlenecks
|
||||
- Memory leaks
|
||||
- 303 TODO comments (iz bug audit-a)
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Run game for 10 min
|
||||
- [ ] Monitor Console
|
||||
- [ ] Monitor Performance (F3)
|
||||
- [ ] List critical bugs
|
||||
- [ ] Document v `BUG_REPORT_01_01_2026.md`
|
||||
|
||||
---
|
||||
|
||||
### 🔧 Task 5.2: Fix Critical Bugs
|
||||
**Čas**: 2-4h
|
||||
**Prioriteta**: 🔵 LOW (only if found)
|
||||
|
||||
**Action**: Fix top 3-5 critical bugs found in Task 5.1
|
||||
|
||||
**Checklist**:
|
||||
- [ ] Identify critical bugs
|
||||
- [ ] Fix them
|
||||
- [ ] Test fixes
|
||||
- [ ] Commit
|
||||
|
||||
---
|
||||
|
||||
## 📊 SESSION TRACKING
|
||||
|
||||
### Čas Potreben (Estimate):
|
||||
- **Asset Generation**: 3-6h
|
||||
- **System Integration**: 3-4h
|
||||
- **UI Creation**: 4-6h (optional)
|
||||
- **Tiled Maps**: 1h (optional)
|
||||
- **Bug Review**: 2-4h (optional)
|
||||
|
||||
**TOTAL**: 6-10h (core) | 13-20h (with optional)
|
||||
|
||||
---
|
||||
|
||||
## ✅ COMPLETION CHECKLIST
|
||||
|
||||
### End of Day Goals:
|
||||
- [ ] **Asset Count**: +200-400 PNG (min)
|
||||
- [ ] **Systems**: All 46 initialized and connected
|
||||
- [ ] **Game Status**: Fully playable with new systems
|
||||
- [ ] **UI**: At least Character Creation working
|
||||
- [ ] **Maps**: Starter map created (optional)
|
||||
- [ ] **Bugs**: No critical errors
|
||||
|
||||
---
|
||||
|
||||
## 🎯 RECOMMENDED WORKFLOW
|
||||
|
||||
### **Session 1 (2h): Morning Kickoff**
|
||||
1. ✅ Task 2.1: Smoke Test (10 min)
|
||||
2. 🎨 Task 1.1: Generate Fauna (90 min)
|
||||
3. 🔧 Task 1.4: Background Removal (30 min)
|
||||
|
||||
### **Session 2 (3h): System Integration**
|
||||
1. ⚙️ Task 2.2: Initialize Systems (1h)
|
||||
2. 🔄 Task 2.3: Add Updates (30 min)
|
||||
3. 🔗 Task 2.4: Connect Systems (1h)
|
||||
4. 🧪 Task 2.5: Integration Test (30 min)
|
||||
|
||||
### **Session 3 (2h): Character Animations**
|
||||
1. 👤 Task 1.2: Generate Animations (2h)
|
||||
|
||||
### **Session 4 (2h): UI or Biomes**
|
||||
**Option A**: UI Focus
|
||||
- 👤 Task 3.1: Character Creation (2h)
|
||||
|
||||
**Option B**: Asset Focus
|
||||
- 🌍 Task 1.3: Complete 1 Biome (2h)
|
||||
|
||||
### **Session 5 (1-2h): Polish**
|
||||
- Additional UI screens OR
|
||||
- Map creation OR
|
||||
- Bug fixes
|
||||
|
||||
---
|
||||
|
||||
## 📝 NOTES
|
||||
|
||||
**Asset Priority**:
|
||||
1. Character animations (CORE gameplay)
|
||||
2. Anomalous fauna (variety)
|
||||
3. Complete biomes (showcase)
|
||||
|
||||
**Code Priority**:
|
||||
1. Smoke test (check current state)
|
||||
2. System integration (get 46 systems working)
|
||||
3. UI (playability)
|
||||
|
||||
**Don't Forget**:
|
||||
- ✅ Commit often (after each major task)
|
||||
- ✅ Test frequently
|
||||
- ✅ Take breaks (every 2h)
|
||||
- ✅ API rate limiting (15s delay between calls)
|
||||
|
||||
---
|
||||
|
||||
**Created**: 1.1.2026 12:42
|
||||
**Status**: 🚀 READY TO EXECUTE!
|
||||
**Next Step**: Start with Task 2.1 (Smoke Test) OR Task 1.1 (Fauna Generation)
|
||||
|
||||
🎆 **SREČNO NOVO LETO! LET'S BUILD THIS GAME!** 🎆
|
||||
90
docs/game_design/FULL_STORY_OVERVIEW.md
Normal file
90
docs/game_design/FULL_STORY_OVERVIEW.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# DolinaSmrti: Krvava Žetev (Bloody Harvest) - Complete Narrative Overview
|
||||
|
||||
## 📖 The Core Premise
|
||||
**DolinaSmrti** is a 2.5D Isometric Survival RPG set in a stylized, hand-drawn post-apocalyptic Slovenia (2085). It tells the emotional story of two teenage twins, **Kai** and **Ana Marković**, separated by a tragic event, and their journey to find each other in a world overrun by the undead.
|
||||
|
||||
---
|
||||
|
||||
## 🎭 The Characters
|
||||
|
||||
### 1. Kai Marković (The Protagonist)
|
||||
- **Role**: The Survivor / "The Zombie Whisperer".
|
||||
- **Visuals**: Green & Pink dreadlocks, tactical gear.
|
||||
- **Ability**: Infected with a rare strain (Alpha Hybrid) that didn't turn him into a zombie but gave him the power to **telepathically control them**. He uses zombies as workforce for his farm.
|
||||
- **Motivation**: To find his twin sister, Ana, at any cost.
|
||||
|
||||
### 2. Ana Marković (The Lost Twin)
|
||||
- **Role**: The Key / The Biologist.
|
||||
- **Visuals**: Matches Kai's style (Pink dreads), often seen in visions/flashbacks.
|
||||
- **Status**: Kidnapped. She holds the secret to the true cure within her blood/research.
|
||||
- **Location**: Unknown (initially), later revealed to be held in a high-security Bio-Lab.
|
||||
|
||||
### 3. Gronk (The Companion)
|
||||
- **Role**: The Heart / Comic Relief.
|
||||
- **Species**: Peaceful Troll.
|
||||
- **Visuals**: Large green troll, pink hair, piercings, vapes regularly.
|
||||
- **Backstory**: Cousin to the main antagonist (The Giant Troll King). Rejected his violent family to live a "Zen" life. Helps Kai manage the farm and provides moral support.
|
||||
|
||||
### 4. Dr. Viktor Krnić (The Antagonist)
|
||||
- **Role**: The Mad Scientist.
|
||||
- **Goal**: To weaponize the virus and create a "Super Race" using Ana's unique biology.
|
||||
- **Base**: Chernobyl Reactor Core (The ultimate destination).
|
||||
|
||||
### 5. The Giant Troll King (The Enforcer)
|
||||
- **Role**: Gronk's evil cousin.
|
||||
- **Deed**: The one who physically snatched Ana during the outbreak.
|
||||
|
||||
---
|
||||
|
||||
## 📜 The Story Arc
|
||||
|
||||
### 🎬 Prologue: The Separation (2084)
|
||||
In the chaos of the initial outbreak at **Nova Lab**, Kai and Ana's parents sacrifice themselves to save their children.
|
||||
- **The Incident**: A massive breach occurs.
|
||||
- **The Event**: Kai is bitten/infected but transforms into a Hybrid instead of turning.
|
||||
- **The Tragedy**: In the confusion, The Giant Troll King smashes through the defenses and grabs Ana, taking her away into the darkness. Kai passes out from the infection.
|
||||
|
||||
### 🌾 Act 1: The Awakening & The Farm (2085)
|
||||
**Location**: The Valley of Death (Dolina Smrti).
|
||||
- Kai wakes up a year later, alone.
|
||||
- He realizes his power: The zombies don't attack him; they listen to him.
|
||||
- **Objective**: Survival. Kai establishes a **Micro Farm**.
|
||||
- **Meeting Gronk**: Kai saves Gronk from a trap. Gronk pledges loyalty and explains that Ana is still alive, leaving "signs" for Kai.
|
||||
- **The Plan**: Build a base, gather resources, and find the **50 Clues** Ana left behind.
|
||||
|
||||
### 🗺️ Act 2: The Journey (Biomes 1-18)
|
||||
Kai travels through 18 distinct biomes (Forests, Swamps, Deserts, Ruins), restoring civilization town by town.
|
||||
- **Mechanic**: Kai clears areas, rebuilds towns, and sets up "Zombie Workforce" automation.
|
||||
- **The Clues**: He finds pages of Ana's diary, torn fabric, and encoded messages. Each clue reveals she is being moved closer to the "Old Zone" (Chernobyl).
|
||||
- **Bosses**: Kai defeats regional guardians (Mutant King, Zombie Horde Leader, Ancient Tree) who guard the path forward.
|
||||
|
||||
### 🔬 Act 3: The Revelation (The Bio-Lab)
|
||||
Kai gathers enough clues to locate Krnić's secret forward base.
|
||||
- **Infiltration**: He storms the lab.
|
||||
- **The Twist**: He finds Ana's cell... empty. A video log reveals Krnić has moved her to **Chernobyl** for the "Final Stage" of his experiment.
|
||||
- **The Stakes**: Krnić plans to release a Super Virus that will wipe out all non-hybrids.
|
||||
|
||||
### ☢️ Act 4: The Reactor (Chernobyl)
|
||||
The Finale. Kai and Gronk travel to the irradiated ruins of Pripyat.
|
||||
- **Final Battle**: Kai faces the **Giant Troll King** (Gronk's Cousin) in a massive showdown.
|
||||
- **The Confrontation**: Kai confronts Dr. Krnić at the Reactor Core.
|
||||
|
||||
---
|
||||
|
||||
## 🏁 The Endings (Based on Player Choice)
|
||||
|
||||
1. **🌟 Together Forever (True Ending)**
|
||||
* **Condition**: All 50 Clues found, Cure synthesized.
|
||||
* **Outcome**: Kai rescues Ana. They defeat Krnić and use the cure to stabilize the world. Humans and Hybrids live in peace.
|
||||
|
||||
2. **💔 The Sacrifice**
|
||||
* **Condition**: Kai saves Ana but takes a fatal blow.
|
||||
* **Outcome**: Kai dies a hero's death. Ana survives to lead the new world, building a statue in his honor.
|
||||
|
||||
3. **😢 The Hermit (Bad Ending)**
|
||||
* **Condition**: Ana dies during the rescue.
|
||||
* **Outcome**: Kai is broken. He returns to his farm, isolates himself, and lives out his days in silence with only his zombie workers.
|
||||
|
||||
4. **💀 The Tyrant (Evil Ending)**
|
||||
* **Condition**: Kai embraces the darkness/power.
|
||||
* **Outcome**: Kai kills Krnić but takes his place. He rules the wasteland as the "Zombie King," with Ana leading the resistance against him.
|
||||
500
preview_animations.html
Normal file
500
preview_animations.html
Normal file
@@ -0,0 +1,500 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="sl">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>DolinaSmrti - Character Animation Preview</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
||||
color: #fff;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
padding: 40px 20px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 15px;
|
||||
margin-bottom: 40px;
|
||||
border: 2px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 3em;
|
||||
margin-bottom: 10px;
|
||||
background: linear-gradient(45deg, #00ff88, #00ddff);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.header p {
|
||||
font-size: 1.2em;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.stats {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 30px;
|
||||
margin: 20px 0;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.stat-box {
|
||||
background: rgba(0, 255, 136, 0.1);
|
||||
padding: 15px 30px;
|
||||
border-radius: 10px;
|
||||
border: 2px solid rgba(0, 255, 136, 0.3);
|
||||
}
|
||||
|
||||
.stat-box .number {
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
color: #00ff88;
|
||||
}
|
||||
|
||||
.stat-box .label {
|
||||
font-size: 0.9em;
|
||||
color: #aaa;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.controls {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 30px;
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 12px 24px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 1em;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(45deg, #00ff88, #00ddff);
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 20px rgba(0, 255, 136, 0.4);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: #fff;
|
||||
border: 2px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.character-section {
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
.character-header {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
padding: 20px 30px;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 20px;
|
||||
border-left: 5px solid;
|
||||
}
|
||||
|
||||
.character-header.kai {
|
||||
border-color: #00ff88;
|
||||
}
|
||||
|
||||
.character-header.ana {
|
||||
border-color: #ff00ff;
|
||||
}
|
||||
|
||||
.character-header.gronk {
|
||||
border-color: #00ddff;
|
||||
}
|
||||
|
||||
.character-header h2 {
|
||||
font-size: 2em;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.character-header .info {
|
||||
color: #aaa;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.animation-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.animation-card {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 12px;
|
||||
padding: 15px;
|
||||
border: 2px solid rgba(255, 255, 255, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.animation-card:hover {
|
||||
transform: translateY(-5px);
|
||||
border-color: rgba(0, 255, 136, 0.5);
|
||||
box-shadow: 0 10px 30px rgba(0, 255, 136, 0.2);
|
||||
}
|
||||
|
||||
.animation-card h3 {
|
||||
font-size: 1.2em;
|
||||
margin-bottom: 10px;
|
||||
color: #00ff88;
|
||||
}
|
||||
|
||||
.frames-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
|
||||
gap: 10px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.frame-box {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.frame-box img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 5px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.frame-box img:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.frame-box .frame-label {
|
||||
font-size: 0.8em;
|
||||
color: #aaa;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
font-size: 1.5em;
|
||||
color: #00ff88;
|
||||
}
|
||||
|
||||
.loading::after {
|
||||
content: '...';
|
||||
animation: dots 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes dots {
|
||||
|
||||
0%,
|
||||
20% {
|
||||
content: '.';
|
||||
}
|
||||
|
||||
40% {
|
||||
content: '..';
|
||||
}
|
||||
|
||||
60%,
|
||||
100% {
|
||||
content: '...';
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
z-index: 1000;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal.active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
}
|
||||
|
||||
.modal-content img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.close-modal {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 40px;
|
||||
font-size: 3em;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
z-index: 1001;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>🎮 DolinaSmrti - Character Animations</h1>
|
||||
<p>Complete Animation Preview - Bloody Harvest</p>
|
||||
|
||||
<div class="stats">
|
||||
<div class="stat-box">
|
||||
<div class="number" id="total-animations">0</div>
|
||||
<div class="label">Animations</div>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<div class="number" id="total-frames">0</div>
|
||||
<div class="label">Frames</div>
|
||||
</div>
|
||||
<div class="stat-box">
|
||||
<div class="number" id="total-files">0</div>
|
||||
<div class="label">Files</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<button class="btn btn-primary" onclick="loadAllAnimations()">🔄 Refresh Gallery</button>
|
||||
<button class="btn btn-secondary" onclick="filterCharacter('all')">All Characters</button>
|
||||
<button class="btn btn-secondary" onclick="filterCharacter('kai')">Kai Only</button>
|
||||
<button class="btn btn-secondary" onclick="filterCharacter('ana')">Ana Only</button>
|
||||
<button class="btn btn-secondary" onclick="filterCharacter('gronk')">Gronk Only</button>
|
||||
<button class="btn btn-secondary" onclick="togglePreviewSize()">Toggle Size</button>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<div class="loading">Loading animations</div>
|
||||
</div>
|
||||
|
||||
<div class="modal" id="modal" onclick="closeModal()">
|
||||
<span class="close-modal">×</span>
|
||||
<div class="modal-content">
|
||||
<img id="modal-img" src="" alt="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const CHARACTERS = {
|
||||
'kai': {
|
||||
name: 'Kai Marković',
|
||||
color: '#00ff88',
|
||||
desc: 'Zombie Whisperer - Age 17'
|
||||
},
|
||||
'ana': {
|
||||
name: 'Ana Marković',
|
||||
color: '#ff00ff',
|
||||
desc: 'Twin Sister - Scientist - Age 17'
|
||||
},
|
||||
'gronk': {
|
||||
name: 'Gronk',
|
||||
color: '#00ddff',
|
||||
desc: 'Zen Troll Companion'
|
||||
}
|
||||
};
|
||||
|
||||
let currentFilter = 'all';
|
||||
let previewSize = 'preview';
|
||||
|
||||
async function loadAllAnimations() {
|
||||
const content = document.getElementById('content');
|
||||
content.innerHTML = '<div class="loading">Loading animations</div>';
|
||||
|
||||
let totalAnimations = 0;
|
||||
let totalFrames = 0;
|
||||
let totalFiles = 0;
|
||||
|
||||
let html = '';
|
||||
|
||||
for (const [charKey, charData] of Object.entries(CHARACTERS)) {
|
||||
try {
|
||||
const response = await fetch(`../assets/slike/${charKey}/`);
|
||||
const text = await response.text();
|
||||
|
||||
// Parse directory listing for PNG files
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(text, 'text/html');
|
||||
const links = doc.querySelectorAll('a');
|
||||
|
||||
const animations = {};
|
||||
|
||||
// Group files by animation name
|
||||
links.forEach(link => {
|
||||
const filename = link.textContent;
|
||||
if (filename.includes('_preview_256x256.png')) {
|
||||
const match = filename.match(/(.+)_frame(\d+)_preview/);
|
||||
if (match) {
|
||||
const animName = match[1].replace(`${charKey}_`, '');
|
||||
const frameNum = parseInt(match[2]);
|
||||
|
||||
if (!animations[animName]) {
|
||||
animations[animName] = [];
|
||||
}
|
||||
animations[animName].push({
|
||||
frame: frameNum,
|
||||
preview: filename,
|
||||
original: filename.replace('_preview_256x256.png', '_1024x1024.png')
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Sort frames
|
||||
Object.keys(animations).forEach(animName => {
|
||||
animations[animName].sort((a, b) => a.frame - b.frame);
|
||||
});
|
||||
|
||||
totalAnimations += Object.keys(animations).length;
|
||||
|
||||
// Generate HTML for this character
|
||||
html += `
|
||||
<div class="character-section" data-character="${charKey}">
|
||||
<div class="character-header ${charKey}">
|
||||
<h2>${charData.name}</h2>
|
||||
<div class="info">${charData.desc} - ${Object.keys(animations).length} animations</div>
|
||||
</div>
|
||||
<div class="animation-grid">
|
||||
`;
|
||||
|
||||
Object.entries(animations).forEach(([animName, frames]) => {
|
||||
totalFrames += frames.length;
|
||||
totalFiles += frames.length * 2; // preview + original
|
||||
|
||||
html += `
|
||||
<div class="animation-card">
|
||||
<h3>${animName}</h3>
|
||||
<div class="frames-container">
|
||||
`;
|
||||
|
||||
frames.forEach(frame => {
|
||||
html += `
|
||||
<div class="frame-box">
|
||||
<img src="../assets/slike/${charKey}/${frame.preview}"
|
||||
alt="${animName} frame ${frame.frame}"
|
||||
onclick="openModal('../assets/slike/${charKey}/${frame.original}')">
|
||||
<div class="frame-label">Frame ${frame.frame}</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
html += `
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
html += `
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
} catch (error) {
|
||||
console.error(`Error loading ${charKey}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
content.innerHTML = html || '<div class="loading">No animations found. Run generation script first!</div>';
|
||||
|
||||
// Update stats
|
||||
document.getElementById('total-animations').textContent = totalAnimations;
|
||||
document.getElementById('total-frames').textContent = totalFrames;
|
||||
document.getElementById('total-files').textContent = totalFiles;
|
||||
}
|
||||
|
||||
function filterCharacter(filter) {
|
||||
currentFilter = filter;
|
||||
const sections = document.querySelectorAll('.character-section');
|
||||
|
||||
sections.forEach(section => {
|
||||
if (filter === 'all' || section.dataset.character === filter) {
|
||||
section.style.display = 'block';
|
||||
} else {
|
||||
section.style.display = 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function togglePreviewSize() {
|
||||
const images = document.querySelectorAll('.frame-box img');
|
||||
|
||||
if (previewSize === 'preview') {
|
||||
previewSize = 'large';
|
||||
images.forEach(img => {
|
||||
img.src = img.src.replace('_preview_256x256.png', '_1024x1024.png');
|
||||
});
|
||||
} else {
|
||||
previewSize = 'preview';
|
||||
images.forEach(img => {
|
||||
img.src = img.src.replace('_1024x1024.png', '_preview_256x256.png');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function openModal(imageSrc) {
|
||||
const modal = document.getElementById('modal');
|
||||
const modalImg = document.getElementById('modal-img');
|
||||
|
||||
modalImg.src = imageSrc;
|
||||
modal.classList.add('active');
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
const modal = document.getElementById('modal');
|
||||
modal.classList.remove('active');
|
||||
}
|
||||
|
||||
// Auto-load on page load
|
||||
window.addEventListener('load', () => {
|
||||
loadAllAnimations();
|
||||
|
||||
// Auto-refresh every 30 seconds during generation
|
||||
setInterval(() => {
|
||||
if (document.visibilityState === 'visible') {
|
||||
loadAllAnimations();
|
||||
}
|
||||
}, 30000);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
393
scripts/generate_all_characters_complete.py
Normal file
393
scripts/generate_all_characters_complete.py
Normal file
@@ -0,0 +1,393 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
COMPLETE CHARACTER ANIMATION GENERATOR
|
||||
Generates ALL animations for Kai, Ana, and Gronk (435 PNG total)
|
||||
Date: 1.1.2026
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
from pathlib import Path
|
||||
import google.generativeai as genai
|
||||
from PIL import Image
|
||||
import io
|
||||
|
||||
# ==================== CONFIGURATION ====================
|
||||
# Try both environment variable names
|
||||
API_KEY = os.getenv('GEMINI_API_KEY') or os.getenv('GOOGLE_API_KEY')
|
||||
if not API_KEY:
|
||||
print("❌ ERROR: API key not found!")
|
||||
print("Please set one of:")
|
||||
print(" export GEMINI_API_KEY='your-key-here'")
|
||||
print(" export GOOGLE_API_KEY='your-key-here'")
|
||||
raise ValueError("API key not set!")
|
||||
|
||||
# NOTE: Using deprecated google.generativeai for compatibility
|
||||
# TODO: Migrate to google.genai in future
|
||||
import warnings
|
||||
warnings.filterwarnings('ignore', category=FutureWarning)
|
||||
|
||||
genai.configure(api_key=API_KEY)
|
||||
print(f"✅ API Key configured (first 10 chars): {API_KEY[:10]}...")
|
||||
|
||||
OUTPUT_DIR = Path("assets/slike")
|
||||
DELAY_BETWEEN_CALLS = 15 # seconds (safe rate limiting)
|
||||
|
||||
# Art Style Constants
|
||||
STYLE_BASE = """
|
||||
Dark Hand-Drawn 2D Stylized Indie Game Art.
|
||||
CRITICAL REQUIREMENTS:
|
||||
- THICK bold black outlines (3-4px)
|
||||
- Exaggerated proportions, warped perspective
|
||||
- High-contrast noir elements
|
||||
- Centered subject with 10px transparent margin
|
||||
- 32-bit PNG with alpha channel
|
||||
- Clean background (pure transparency)
|
||||
"""
|
||||
|
||||
# ==================== CHARACTER DEFINITIONS ====================
|
||||
|
||||
KAI_BASE = """
|
||||
Character: KAI MARKOVIĆ (Age 17, Male Protagonist)
|
||||
- Green & Pink dreadlocks (distinctive!)
|
||||
- Tactical survivor outfit (torn, weathered)
|
||||
- Lean athletic build
|
||||
- Determined expression
|
||||
- REFERENCE: Check konsistentno/kai_master_styleA_reference.png
|
||||
"""
|
||||
|
||||
ANA_BASE = """
|
||||
Character: ANA MARKOVIĆ (Age 17, Female Twin)
|
||||
- Pink dreadlocks (matches Kai's style but all pink)
|
||||
- Explorer vest, cargo pants
|
||||
- Slender athletic build
|
||||
- Intelligent, caring expression
|
||||
- REFERENCE: Check konsistentno/ana_master_styleA_reference.png
|
||||
"""
|
||||
|
||||
GRONK_BASE = """
|
||||
Character: GRONK (Zen Troll Companion)
|
||||
- Large green troll, 7ft tall
|
||||
- Pink mohawk hair
|
||||
- Multiple piercings (ears, nose)
|
||||
- Vape pen accessory (signature item!)
|
||||
- Baggy pants, no shirt
|
||||
- Chill, relaxed expression
|
||||
- REFERENCE: Check konsistentno/gronk_master_styleA_reference.png
|
||||
"""
|
||||
|
||||
# ==================== ANIMATION DEFINITIONS ====================
|
||||
|
||||
KAI_ANIMATIONS = {
|
||||
# PHASE 1: Core Gameplay (72 PNG)
|
||||
"walk_north": {"frames": 4, "desc": "walking away from camera, back view"},
|
||||
"walk_northeast": {"frames": 4, "desc": "walking diagonal up-right"},
|
||||
"walk_east": {"frames": 4, "desc": "walking right, side view (right profile)"},
|
||||
"walk_southeast": {"frames": 4, "desc": "walking diagonal down-right"},
|
||||
"walk_south": {"frames": 4, "desc": "walking toward camera, front view"},
|
||||
"walk_southwest": {"frames": 4, "desc": "walking diagonal down-left"},
|
||||
"walk_west": {"frames": 4, "desc": "walking left, side view (left profile)"},
|
||||
"walk_northwest": {"frames": 4, "desc": "walking diagonal up-left"},
|
||||
|
||||
"idle_front": {"frames": 4, "desc": "idle standing, front view, breathing animation"},
|
||||
"idle_side": {"frames": 4, "desc": "idle standing, side profile, breathing animation"},
|
||||
|
||||
"attack_north": {"frames": 4, "desc": "sword swing upward (attacking north)"},
|
||||
"attack_east": {"frames": 4, "desc": "sword swing right (attacking east)"},
|
||||
"attack_south": {"frames": 4, "desc": "sword swing downward (attacking south)"},
|
||||
"attack_west": {"frames": 4, "desc": "sword swing left (attacking west)"},
|
||||
|
||||
"dig_north": {"frames": 4, "desc": "digging with shovel upward"},
|
||||
"dig_east": {"frames": 4, "desc": "digging with shovel to the right"},
|
||||
"dig_south": {"frames": 4, "desc": "digging with shovel downward"},
|
||||
"dig_west": {"frames": 4, "desc": "digging with shovel to the left"},
|
||||
|
||||
# PHASE 2: Expanded (47 PNG)
|
||||
"run_north": {"frames": 4, "desc": "running away, back view, faster pace"},
|
||||
"run_northeast": {"frames": 4, "desc": "running diagonal up-right"},
|
||||
"run_east": {"frames": 4, "desc": "running right, side view"},
|
||||
"run_southeast": {"frames": 4, "desc": "running diagonal down-right"},
|
||||
"run_south": {"frames": 4, "desc": "running toward camera, front view"},
|
||||
"run_southwest": {"frames": 4, "desc": "running diagonal down-left"},
|
||||
"run_west": {"frames": 4, "desc": "running left, side view"},
|
||||
"run_northwest": {"frames": 4, "desc": "running diagonal up-left"},
|
||||
|
||||
"plant_front": {"frames": 3, "desc": "planting seeds, kneeling, front view"},
|
||||
"plant_side": {"frames": 3, "desc": "planting seeds, kneeling, side view"},
|
||||
|
||||
"harvest_front": {"frames": 3, "desc": "harvesting crops, bending down, front view"},
|
||||
"harvest_side": {"frames": 3, "desc": "harvesting crops, bending down, side view"},
|
||||
|
||||
"hurt": {"frames": 3, "desc": "taking damage, recoiling, pain expression"},
|
||||
|
||||
# PHASE 3: Polish (27 PNG)
|
||||
"sad": {"frames": 4, "desc": "crying, hands on face, emotional"},
|
||||
"happy": {"frames": 4, "desc": "celebrating, arms raised, joyful"},
|
||||
"thinking": {"frames": 3, "desc": "hand on chin, pondering"},
|
||||
"shocked": {"frames": 2, "desc": "surprised, eyes wide, mouth open"},
|
||||
|
||||
"use_item_front": {"frames": 3, "desc": "using item from inventory, front view"},
|
||||
"use_item_side": {"frames": 3, "desc": "using item from inventory, side view"},
|
||||
|
||||
"eat": {"frames": 3, "desc": "eating food, bringing to mouth"},
|
||||
|
||||
"death": {"frames": 5, "desc": "death animation, collapsing to ground"},
|
||||
|
||||
# PHASE 4: Advanced (10 PNG)
|
||||
"zombie_command": {"frames": 4, "desc": "telepathic gesture, hand raised, concentration"},
|
||||
"telepathy_effect": {"frames": 6, "desc": "psychic energy emanating, glowing effect"},
|
||||
}
|
||||
|
||||
ANA_ANIMATIONS = {
|
||||
# PHASE 1: Core (56 PNG)
|
||||
"walk_north": {"frames": 4, "desc": "walking away, back view"},
|
||||
"walk_northeast": {"frames": 4, "desc": "walking diagonal up-right"},
|
||||
"walk_east": {"frames": 4, "desc": "walking right, side view"},
|
||||
"walk_southeast": {"frames": 4, "desc": "walking diagonal down-right"},
|
||||
"walk_south": {"frames": 4, "desc": "walking toward camera, front view"},
|
||||
"walk_southwest": {"frames": 4, "desc": "walking diagonal down-left"},
|
||||
"walk_west": {"frames": 4, "desc": "walking left, side view"},
|
||||
"walk_northwest": {"frames": 4, "desc": "walking diagonal up-left"},
|
||||
|
||||
"idle_front": {"frames": 4, "desc": "idle standing, front view"},
|
||||
"idle_side": {"frames": 4, "desc": "idle standing, side profile"},
|
||||
|
||||
"research_front": {"frames": 4, "desc": "writing in notebook, studying"},
|
||||
"research_side": {"frames": 4, "desc": "writing in notebook, side view"},
|
||||
|
||||
"heal_front": {"frames": 4, "desc": "applying bandage, medical care"},
|
||||
"heal_side": {"frames": 4, "desc": "applying bandage, side view"},
|
||||
|
||||
# PHASE 2: Expanded (46 PNG)
|
||||
"run_north": {"frames": 4, "desc": "running away, back view"},
|
||||
"run_northeast": {"frames": 4, "desc": "running diagonal up-right"},
|
||||
"run_east": {"frames": 4, "desc": "running right"},
|
||||
"run_southeast": {"frames": 4, "desc": "running diagonal down-right"},
|
||||
"run_south": {"frames": 4, "desc": "running toward camera"},
|
||||
"run_southwest": {"frames": 4, "desc": "running diagonal down-left"},
|
||||
"run_west": {"frames": 4, "desc": "running left"},
|
||||
"run_northwest": {"frames": 4, "desc": "running diagonal up-left"},
|
||||
|
||||
"examine_front": {"frames": 3, "desc": "examining with magnifying glass"},
|
||||
"examine_side": {"frames": 3, "desc": "examining, side view"},
|
||||
|
||||
"mix_potion": {"frames": 4, "desc": "mixing ingredients in flask"},
|
||||
|
||||
"worried": {"frames": 4, "desc": "worried expression, hand to head"},
|
||||
|
||||
# PHASE 3: Polish (18 PNG)
|
||||
"relief": {"frames": 4, "desc": "relief, exhaling, relaxed"},
|
||||
"twin_bond_glow": {"frames": 6, "desc": "glowing psychic connection effect"},
|
||||
"flashback_pose": {"frames": 3, "desc": "memory pose, ethereal"},
|
||||
"death": {"frames": 5, "desc": "death animation, collapsing"},
|
||||
|
||||
# PHASE 4: Advanced (18 PNG)
|
||||
"collect_sample_front": {"frames": 3, "desc": "collecting sample with vial"},
|
||||
"collect_sample_side": {"frames": 3, "desc": "collecting sample, side view"},
|
||||
|
||||
"defend": {"frames": 4, "desc": "defensive stance with staff"},
|
||||
"cure_cast": {"frames": 5, "desc": "casting cure spell, magical gesture"},
|
||||
"hurt": {"frames": 3, "desc": "taking damage, recoiling"},
|
||||
}
|
||||
|
||||
GRONK_ANIMATIONS = {
|
||||
# PHASE 1: Core (72 PNG)
|
||||
"walk_north": {"frames": 4, "desc": "heavy lumbering walk, back view"},
|
||||
"walk_northeast": {"frames": 4, "desc": "heavy walk diagonal up-right"},
|
||||
"walk_east": {"frames": 4, "desc": "heavy walk right, side view"},
|
||||
"walk_southeast": {"frames": 4, "desc": "heavy walk diagonal down-right"},
|
||||
"walk_south": {"frames": 4, "desc": "heavy walk toward camera, front view"},
|
||||
"walk_southwest": {"frames": 4, "desc": "heavy walk diagonal down-left"},
|
||||
"walk_west": {"frames": 4, "desc": "heavy walk left, side view"},
|
||||
"walk_northwest": {"frames": 4, "desc": "heavy walk diagonal up-left"},
|
||||
|
||||
"idle_front": {"frames": 4, "desc": "idle, chill stance, front view"},
|
||||
"idle_side": {"frames": 4, "desc": "idle, chill stance, side view"},
|
||||
|
||||
"vape_front": {"frames": 6, "desc": "vaping, exhaling smoke cloud, front view"},
|
||||
"vape_side": {"frames": 6, "desc": "vaping, exhaling smoke, side view"},
|
||||
|
||||
"smash_north": {"frames": 5, "desc": "club smash upward"},
|
||||
"smash_east": {"frames": 5, "desc": "club smash right"},
|
||||
"smash_south": {"frames": 5, "desc": "club smash downward"},
|
||||
"smash_west": {"frames": 5, "desc": "club smash left"},
|
||||
|
||||
# PHASE 2: Expanded (47 PNG)
|
||||
"run_north": {"frames": 4, "desc": "slow lumbering run, back view"},
|
||||
"run_northeast": {"frames": 4, "desc": "lumbering run diagonal up-right"},
|
||||
"run_east": {"frames": 4, "desc": "lumbering run right"},
|
||||
"run_southeast": {"frames": 4, "desc": "lumbering run diagonal down-right"},
|
||||
"run_south": {"frames": 4, "desc": "lumbering run toward camera"},
|
||||
"run_southwest": {"frames": 4, "desc": "lumbering run diagonal down-left"},
|
||||
"run_west": {"frames": 4, "desc": "lumbering run left"},
|
||||
"run_northwest": {"frames": 4, "desc": "lumbering run diagonal up-left"},
|
||||
|
||||
"lift_heavy_front": {"frames": 4, "desc": "lifting heavy object, straining"},
|
||||
"lift_heavy_side": {"frames": 4, "desc": "lifting heavy object, side view"},
|
||||
|
||||
"laugh": {"frames": 4, "desc": "laughing, belly laugh, jovial"},
|
||||
"hurt": {"frames": 3, "desc": "taking damage, grimacing"},
|
||||
|
||||
# PHASE 3: Polish (16 PNG)
|
||||
"meditate": {"frames": 4, "desc": "zen meditation pose, sitting, serene"},
|
||||
"confused": {"frames": 3, "desc": "confused, scratching head"},
|
||||
"chill": {"frames": 3, "desc": "ultra relaxed, peace sign"},
|
||||
|
||||
"death": {"frames": 5, "desc": "death animation, collapsing heavily"},
|
||||
|
||||
# PHASE 4: Advanced (6 PNG)
|
||||
"block": {"frames": 3, "desc": "blocking with raised arms"},
|
||||
"taunt": {"frames": 4, "desc": "taunting enemies, beckoning"},
|
||||
}
|
||||
|
||||
# ==================== GENERATION FUNCTIONS ====================
|
||||
|
||||
def generate_animation_frame(character_name, character_base, animation_name, frame_num, animation_desc, style=STYLE_BASE):
|
||||
"""Generate a single animation frame"""
|
||||
|
||||
prompt = f"""
|
||||
{style}
|
||||
|
||||
{character_base}
|
||||
|
||||
ANIMATION: {animation_name} - Frame {frame_num}
|
||||
Description: {animation_desc}
|
||||
|
||||
Frame {frame_num} timing notes:
|
||||
- Frame 1: Start pose
|
||||
- Frame 2: Mid-motion
|
||||
- Frame 3: Peak/impact
|
||||
- Frame 4: Follow-through/return
|
||||
|
||||
Generate this specific frame showing clear progression in the animation cycle.
|
||||
Maintain character consistency (check reference in konsistentno/ folder).
|
||||
"""
|
||||
|
||||
try:
|
||||
print(f" 🎨 Generating {character_name} - {animation_name} - Frame {frame_num}...")
|
||||
|
||||
model = genai.GenerativeModel('gemini-2.0-flash-exp')
|
||||
response = model.generate_content([prompt])
|
||||
|
||||
if response.parts and len(response.parts) > 0:
|
||||
image_data = response.parts[0].inline_data.data
|
||||
image = Image.open(io.BytesIO(image_data))
|
||||
return image
|
||||
else:
|
||||
print(f" ❌ No image generated for {animation_name} frame {frame_num}")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
print(f" ❌ Error generating {animation_name} frame {frame_num}: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def generate_character_animations(character_name, character_base, animations_dict):
|
||||
"""Generate all animations for a character"""
|
||||
|
||||
char_dir = OUTPUT_DIR / character_name.lower()
|
||||
char_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
total_frames = sum(anim["frames"] for anim in animations_dict.values())
|
||||
current_frame = 0
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f"🎬 GENERATING {character_name.upper()} ANIMATIONS")
|
||||
print(f"{'='*60}")
|
||||
print(f"Total animations: {len(animations_dict)}")
|
||||
print(f"Total frames: {total_frames}")
|
||||
print(f"Output directory: {char_dir}")
|
||||
print()
|
||||
|
||||
for anim_name, anim_data in animations_dict.items():
|
||||
frames_count = anim_data["frames"]
|
||||
desc = anim_data["desc"]
|
||||
|
||||
print(f"\n📹 Animation: {anim_name} ({frames_count} frames)")
|
||||
|
||||
for frame_num in range(1, frames_count + 1):
|
||||
current_frame += 1
|
||||
|
||||
# Generate frame
|
||||
image = generate_animation_frame(
|
||||
character_name,
|
||||
character_base,
|
||||
anim_name,
|
||||
frame_num,
|
||||
desc
|
||||
)
|
||||
|
||||
if image:
|
||||
# Save original
|
||||
filename = f"{character_name.lower()}_{anim_name}_frame{frame_num}_1024x1024.png"
|
||||
filepath = char_dir / filename
|
||||
image.save(filepath, "PNG")
|
||||
print(f" ✅ Saved: {filename}")
|
||||
|
||||
# Create preview (256x256)
|
||||
preview = image.resize((256, 256), Image.Resampling.LANCZOS)
|
||||
preview_filename = f"{character_name.lower()}_{anim_name}_frame{frame_num}_preview_256x256.png"
|
||||
preview_filepath = char_dir / preview_filename
|
||||
preview.save(preview_filepath, "PNG")
|
||||
print(f" ✅ Saved preview: {preview_filename}")
|
||||
|
||||
# Progress
|
||||
progress = (current_frame / total_frames) * 100
|
||||
print(f" 📊 Progress: {current_frame}/{total_frames} ({progress:.1f}%)")
|
||||
|
||||
# Rate limiting
|
||||
print(f" ⏳ Waiting {DELAY_BETWEEN_CALLS}s...")
|
||||
time.sleep(DELAY_BETWEEN_CALLS)
|
||||
|
||||
print(f"\n✅ {character_name.upper()} COMPLETE! Generated {total_frames} frames ({total_frames * 2} files with previews)")
|
||||
return total_frames
|
||||
|
||||
|
||||
# ==================== MAIN EXECUTION ====================
|
||||
|
||||
def main():
|
||||
"""Generate all character animations"""
|
||||
|
||||
print("=" * 80)
|
||||
print("🎮 DOLINASMRTI - COMPLETE CHARACTER ANIMATION GENERATOR")
|
||||
print("=" * 80)
|
||||
print(f"Date: 2026-01-01")
|
||||
print(f"Target: 435 PNG (all 3 characters, all animations)")
|
||||
print(f"API Delay: {DELAY_BETWEEN_CALLS}s between calls")
|
||||
print()
|
||||
|
||||
start_time = time.time()
|
||||
total_generated = 0
|
||||
|
||||
# Generate Kai
|
||||
kai_frames = generate_character_animations("Kai", KAI_BASE, KAI_ANIMATIONS)
|
||||
total_generated += kai_frames
|
||||
|
||||
# Generate Ana
|
||||
ana_frames = generate_character_animations("Ana", ANA_BASE, ANA_ANIMATIONS)
|
||||
total_generated += ana_frames
|
||||
|
||||
# Generate Gronk
|
||||
gronk_frames = generate_character_animations("Gronk", GRONK_BASE, GRONK_ANIMATIONS)
|
||||
total_generated += gronk_frames
|
||||
|
||||
# Summary
|
||||
elapsed = time.time() - start_time
|
||||
hours = int(elapsed // 3600)
|
||||
minutes = int((elapsed % 3600) // 60)
|
||||
|
||||
print("\n" + "=" * 80)
|
||||
print("🎆 GENERATION COMPLETE!")
|
||||
print("=" * 80)
|
||||
print(f"Total frames generated: {total_generated}")
|
||||
print(f"Total files created: {total_generated * 2} (with previews)")
|
||||
print(f"Time elapsed: {hours}h {minutes}min")
|
||||
print(f"\nCharacter breakdown:")
|
||||
print(f" - Kai: {kai_frames} frames")
|
||||
print(f" - Ana: {ana_frames} frames")
|
||||
print(f" - Gronk: {gronk_frames} frames")
|
||||
print("\n✅ All character animations ready for game integration!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
259
scripts/generate_characters_working.py
Normal file
259
scripts/generate_characters_working.py
Normal file
@@ -0,0 +1,259 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
CHARACTER ANIMATION GENERATOR - WORKING VERSION
|
||||
Uses direct REST API instead of deprecated SDK
|
||||
Generates animations for Kai, Ana, Gronk
|
||||
Date: 1.1.2026
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
import json
|
||||
import base64
|
||||
from pathlib import Path
|
||||
import requests
|
||||
from PIL import Image
|
||||
import io
|
||||
|
||||
# ==================== CONFIGURATION ====================
|
||||
API_KEY = os.getenv('GEMINI_API_KEY') or os.getenv('GOOGLE_API_KEY')
|
||||
if not API_KEY:
|
||||
print("❌ ERROR: API key not found!")
|
||||
print("Please set: export GEMINI_API_KEY='your-key-here'")
|
||||
exit(1)
|
||||
|
||||
print(f"✅ API Key found: {API_KEY[:10]}...")
|
||||
|
||||
OUTPUT_DIR = Path("assets/slike")
|
||||
DELAY_BETWEEN_CALLS = 15 # seconds
|
||||
API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent"
|
||||
|
||||
# ==================== STYLE CONSTANTS ====================
|
||||
STYLE_BASE = """Dark Hand-Drawn 2D Stylized Indie Game Art.
|
||||
CRITICAL: Thick bold black outlines (3-4px), exaggerated proportions, warped perspective.
|
||||
High-contrast noir elements. Centered subject with 10px transparent margin.
|
||||
32-bit PNG with alpha channel. Clean background (pure transparency)."""
|
||||
|
||||
KAI_BASE = """Character: KAI MARKOVIĆ (Age 17, Male Protagonist)
|
||||
- Green & Pink dreadlocks (distinctive!)
|
||||
- Tactical survivor outfit (torn, weathered)
|
||||
- Lean athletic build, determined expression"""
|
||||
|
||||
ANA_BASE = """Character: ANA MARKOVIĆ (Age 17, Female Twin)
|
||||
- Pink dreadlocks (all pink, matches Kai's style)
|
||||
- Explorer vest, cargo pants
|
||||
- Slender athletic build, intelligent caring expression"""
|
||||
|
||||
GRONK_BASE = """Character: GRONK (Zen Troll Companion)
|
||||
- Large green troll, 7ft tall
|
||||
- Pink mohawk hair, multiple piercings
|
||||
- Vape pen accessory (signature!)
|
||||
- Baggy pants, no shirt, chill relaxed expression"""
|
||||
|
||||
# ==================== SIMPLIFIED ANIMATION SET ====================
|
||||
# Start with essentials only to test the system
|
||||
|
||||
KAI_ANIMATIONS = {
|
||||
"walk_south": {"frames": 4, "desc": "walking toward camera, front view"},
|
||||
"walk_east": {"frames": 4, "desc": "walking right, side view"},
|
||||
"idle_front": {"frames": 4, "desc": "idle standing, front view, breathing"},
|
||||
"attack_south": {"frames": 4, "desc": "sword swing downward"},
|
||||
}
|
||||
|
||||
ANA_ANIMATIONS = {
|
||||
"walk_south": {"frames": 4, "desc": "walking toward camera, front view"},
|
||||
"walk_east": {"frames": 4, "desc": "walking right, side view"},
|
||||
"idle_front": {"frames": 4, "desc": "idle standing, front view"},
|
||||
"research_front": {"frames": 4, "desc": "writing in notebook"},
|
||||
}
|
||||
|
||||
GRONK_ANIMATIONS = {
|
||||
"walk_south": {"frames": 4, "desc": "heavy lumbering walk, front view"},
|
||||
"walk_east": {"frames": 4, "desc": "heavy walk right, side view"},
|
||||
"idle_front": {"frames": 4, "desc": "idle, chill stance, front view"},
|
||||
"vape_front": {"frames": 6, "desc": "vaping, exhaling smoke cloud"},
|
||||
}
|
||||
|
||||
# ==================== GENERATION FUNCTIONS ====================
|
||||
|
||||
def generate_image_rest_api(prompt):
|
||||
"""Generate image using REST API"""
|
||||
|
||||
payload = {
|
||||
"contents": [{
|
||||
"parts": [{
|
||||
"text": prompt
|
||||
}]
|
||||
}],
|
||||
"generationConfig": {
|
||||
"temperature": 0.4,
|
||||
"topK": 32,
|
||||
"topP": 1,
|
||||
"maxOutputTokens": 4096,
|
||||
}
|
||||
}
|
||||
|
||||
headers = {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
url = f"{API_URL}?key={API_KEY}"
|
||||
|
||||
try:
|
||||
response = requests.post(url, headers=headers, json=payload, timeout=60)
|
||||
response.raise_for_status()
|
||||
|
||||
data = response.json()
|
||||
|
||||
# Extract image from response
|
||||
if 'candidates' in data and len(data['candidates']) > 0:
|
||||
candidate = data['candidates'][0]
|
||||
if 'content' in candidate and 'parts' in candidate['content']:
|
||||
for part in candidate['content']['parts']:
|
||||
if 'inlineData' in part:
|
||||
image_b64 = part['inlineData']['data']
|
||||
image_bytes = base64.b64decode(image_b64)
|
||||
image = Image.open(io.BytesIO(image_bytes))
|
||||
return image
|
||||
|
||||
print(f" ❌ No image in response")
|
||||
return None
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f" ❌ API Error: {e}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f" ❌ Error: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def generate_animation_frame(character_name, character_base, animation_name, frame_num, animation_desc):
|
||||
"""Generate a single animation frame"""
|
||||
|
||||
prompt = f"""{STYLE_BASE}
|
||||
|
||||
{character_base}
|
||||
|
||||
ANIMATION: {animation_name} - Frame {frame_num}/4
|
||||
Description: {animation_desc}
|
||||
|
||||
Frame timing:
|
||||
- Frame 1: Start pose
|
||||
- Frame 2: Mid-motion
|
||||
- Frame 3: Peak/impact
|
||||
- Frame 4: Follow-through
|
||||
|
||||
Generate this specific frame showing clear progression.
|
||||
Maintain character consistency."""
|
||||
|
||||
print(f" 🎨 {character_name} - {animation_name} - Frame {frame_num}...")
|
||||
|
||||
image = generate_image_rest_api(prompt)
|
||||
return image
|
||||
|
||||
|
||||
def generate_character_animations(character_name, character_base, animations_dict):
|
||||
"""Generate all animations for a character"""
|
||||
|
||||
char_dir = OUTPUT_DIR / character_name.lower()
|
||||
char_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
total_frames = sum(anim["frames"] for anim in animations_dict.values())
|
||||
current_frame = 0
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f"🎬 GENERATING {character_name.upper()}")
|
||||
print(f"{'='*60}")
|
||||
print(f"Animations: {len(animations_dict)}")
|
||||
print(f"Total frames: {total_frames}")
|
||||
print(f"Output: {char_dir}\n")
|
||||
|
||||
for anim_name, anim_data in animations_dict.items():
|
||||
frames_count = anim_data["frames"]
|
||||
desc = anim_data["desc"]
|
||||
|
||||
print(f"\n📹 {anim_name} ({frames_count} frames)")
|
||||
|
||||
for frame_num in range(1, frames_count + 1):
|
||||
current_frame += 1
|
||||
|
||||
image = generate_animation_frame(
|
||||
character_name,
|
||||
character_base,
|
||||
anim_name,
|
||||
frame_num,
|
||||
desc
|
||||
)
|
||||
|
||||
if image:
|
||||
# Save original
|
||||
filename = f"{character_name.lower()}_{anim_name}_frame{frame_num}_1024x1024.png"
|
||||
filepath = char_dir / filename
|
||||
image.save(filepath, "PNG")
|
||||
print(f" ✅ Saved: {filename}")
|
||||
|
||||
# Create preview
|
||||
preview = image.resize((256, 256), Image.Resampling.LANCZOS)
|
||||
preview_filename = f"{character_name.lower()}_{anim_name}_frame{frame_num}_preview_256x256.png"
|
||||
preview_filepath = char_dir / preview_filename
|
||||
preview.save(preview_filepath, "PNG")
|
||||
print(f" ✅ Preview: {preview_filename}")
|
||||
|
||||
# Progress
|
||||
progress = (current_frame / total_frames) * 100
|
||||
print(f" 📊 Progress: {current_frame}/{total_frames} ({progress:.1f}%)")
|
||||
|
||||
# Rate limiting
|
||||
if current_frame < total_frames:
|
||||
print(f" ⏳ Waiting {DELAY_BETWEEN_CALLS}s...")
|
||||
time.sleep(DELAY_BETWEEN_CALLS)
|
||||
|
||||
print(f"\n✅ {character_name.upper()} COMPLETE!")
|
||||
print(f"Generated: {total_frames} frames ({total_frames * 2} files)\n")
|
||||
return total_frames
|
||||
|
||||
|
||||
# ==================== MAIN ====================
|
||||
|
||||
def main():
|
||||
print("=" * 80)
|
||||
print("🎮 DOLINASMRTI - CHARACTER ANIMATION GENERATOR")
|
||||
print("=" * 80)
|
||||
print("Date: 2026-01- 01")
|
||||
print("Mode: ESSENTIAL ANIMATIONS TEST")
|
||||
print(f"API Delay: {DELAY_BETWEEN_CALLS}s\n")
|
||||
|
||||
start_time = time.time()
|
||||
total_generated = 0
|
||||
|
||||
# Generate essentials for each character
|
||||
kai_frames = generate_character_animations("Kai", KAI_BASE, KAI_ANIMATIONS)
|
||||
total_generated += kai_frames
|
||||
|
||||
ana_frames = generate_character_animations("Ana", ANA_BASE, ANA_ANIMATIONS)
|
||||
total_generated += ana_frames
|
||||
|
||||
gronk_frames = generate_character_animations("Gronk", GRONK_BASE, GRONK_ANIMATIONS)
|
||||
total_generated += gronk_frames
|
||||
|
||||
# Summary
|
||||
elapsed = time.time() - start_time
|
||||
hours = int(elapsed // 3600)
|
||||
minutes = int((elapsed % 3600) // 60)
|
||||
|
||||
print("\n" + "=" * 80)
|
||||
print("🎆 GENERATION COMPLETE!")
|
||||
print("=" * 80)
|
||||
print(f"Total frames: {total_generated}")
|
||||
print(f"Total files: {total_generated * 2}")
|
||||
print(f"Time: {hours}h {minutes}min")
|
||||
print(f"\nBreakdown:")
|
||||
print(f" - Kai: {kai_frames} frames")
|
||||
print(f" - Ana: {ana_frames} frames")
|
||||
print(f" - Gronk: {gronk_frames} frames")
|
||||
print("\n✅ Ready for game integration!")
|
||||
print("\n💡 View in Chrome: open preview_animations.html")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
68
scripts/test_imagen.py
Normal file
68
scripts/test_imagen.py
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
TEST - Imagen 3 API (Image Generation)
|
||||
"""
|
||||
import os
|
||||
import requests
|
||||
import base64
|
||||
from PIL import Image
|
||||
import io
|
||||
|
||||
API_KEY = os.getenv('GEMINI_API_KEY')
|
||||
print(f"✅ API Key: {API_KEY[:15]}...")
|
||||
|
||||
# Use Imagen 3 endpoint
|
||||
API_URL = "https://generativelanguage.googleapis.com/v1beta/models/imagen-3.0-generate-001:predict"
|
||||
|
||||
prompt = "Dark hand-drawn 2D stylized indie game art. Character KAI - male, age 17, green and pink dreadlocks, tactical survivor outfit. Walking toward camera, front view. Bold black outlines, centered, transparent background."
|
||||
|
||||
print(f"\n🎨 Generating with Imagen 3...")
|
||||
print(f"Prompt: {prompt[:80]}...\n")
|
||||
|
||||
payload = {
|
||||
"instances": [{
|
||||
"prompt": prompt
|
||||
}],
|
||||
"parameters": {
|
||||
"sampleCount": 1,
|
||||
"aspectRatio": "1:1",
|
||||
"mode": "generateImages"
|
||||
}
|
||||
}
|
||||
|
||||
headers = {"Content-Type": "application/json"}
|
||||
url = f"{API_URL}?key={API_KEY}"
|
||||
|
||||
print(f"📡 Calling Imagen API...")
|
||||
try:
|
||||
response = requests.post(url, headers=headers, json=payload, timeout=60)
|
||||
print(f"Status: {response.status_code}")
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print(f"✅ Response received!")
|
||||
print(f"Response keys: {list(data.keys())}")
|
||||
|
||||
if 'predictions' in data and len(data['predictions']) > 0:
|
||||
pred = data['predictions'][0]
|
||||
print(f"Prediction keys: {list(pred.keys())}")
|
||||
|
||||
if 'bytesBase64Encoded' in pred:
|
||||
print(f"✅ Found image data!")
|
||||
image_b64 = pred['bytesBase64Encoded']
|
||||
image_bytes = base64.b64decode(image_b64)
|
||||
image = Image.open(io.BytesIO(image_bytes))
|
||||
|
||||
output_path = "assets/slike/TEST_kai_imagen.png"
|
||||
image.save(output_path, "PNG")
|
||||
print(f"✅✅ SAVED: {output_path}")
|
||||
print(f"Image size: {image.size}")
|
||||
else:
|
||||
print(f"Response data: {data}")
|
||||
else:
|
||||
print(f"❌ Error {response.status_code}: {response.text}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Exception: {e}")
|
||||
|
||||
print("\n✅ Test complete!")
|
||||
68
scripts/test_minimal.py
Normal file
68
scripts/test_minimal.py
Normal file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
MINIMAL TEST - Generate ONE image
|
||||
"""
|
||||
import os
|
||||
import requests
|
||||
import json
|
||||
import base64
|
||||
from PIL import Image
|
||||
import io
|
||||
|
||||
API_KEY = os.getenv('GEMINI_API_KEY')
|
||||
print(f"✅ API Key: {API_KEY[:15]}...")
|
||||
|
||||
API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent"
|
||||
|
||||
prompt = """Dark Hand-Drawn 2D Stylized Indie Game Art.
|
||||
Character: KAI - Green & Pink dreadlocks, tactical outfit, age 17.
|
||||
Animation: Walking toward camera, frame 1 of 4, front view.
|
||||
Bold black outlines, centered, transparent background."""
|
||||
|
||||
print(f"\n🎨 Generating test image...")
|
||||
print(f"Prompt: {prompt[:80]}...\n")
|
||||
|
||||
payload = {
|
||||
"contents": [{
|
||||
"parts": [{
|
||||
"text": prompt
|
||||
}]
|
||||
}]
|
||||
}
|
||||
|
||||
headers = {"Content-Type": "application/json"}
|
||||
url = f"{API_URL}?key={API_KEY}"
|
||||
|
||||
print(f"📡 Calling API...")
|
||||
response = requests.post(url, headers=headers, json=payload, timeout=60)
|
||||
|
||||
print(f"Status: {response.status_code}")
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print(f"✅ Response received!")
|
||||
print(f"Keys: {list(data.keys())}")
|
||||
|
||||
if 'candidates' in data:
|
||||
print(f"Candidates: {len(data['candidates'])}")
|
||||
|
||||
for i, cand in enumerate(data['candidates']):
|
||||
print(f"\nCandidate {i}:")
|
||||
if 'content' in cand:
|
||||
print(f" Content keys: {list(cand['content'].keys())}")
|
||||
if 'parts' in cand['content']:
|
||||
print(f" Parts: {len(cand['content']['parts'])}")
|
||||
for j, part in enumerate(cand['content']['parts']):
|
||||
print(f" Part {j} keys: {list(part.keys())}")
|
||||
if 'inlineData' in part:
|
||||
print(f" ✅ Found image data!")
|
||||
image_b64 = part['inlineData']['data']
|
||||
image_bytes = base64.b64decode(image_b64)
|
||||
image = Image.open(io.BytesIO(image_bytes))
|
||||
|
||||
output_path = "assets/slike/TEST_kai_walk_frame1.png"
|
||||
image.save(output_path, "PNG")
|
||||
print(f" ✅✅ Saved to: {output_path}")
|
||||
else:
|
||||
print(f"❌ Error: {response.text}")
|
||||
print("\n✅ Test complete!")
|
||||
Reference in New Issue
Block a user