farma orodje in dnevnik

This commit is contained in:
2025-12-08 01:55:39 +01:00
parent e49f567831
commit 860a10a5c3
2 changed files with 222 additions and 126 deletions

75
DNEVNIK.md Normal file
View File

@@ -0,0 +1,75 @@
# 📔 DNEVNIK RAZVOJA: KRVAVA ŽETEV (NOVA FARMA)
## 📅 Začetek Projekta
**Datum začetka:** 5. December 2025
**Lokacija:** Nova Farma (c:\novafarma)
**Engine:** Phaser 3 + Custom Antigravity Engine
**Stil:** 2.5D Izometrični Pixel Art / Voxel
---
## 🧟‍♂️ Koncept Igre & Zgodba
### Naslov: Krvava Žetev (Zombie Roots)
**Zgodba:**
Svet, kakršnega smo poznali, je propadel. Nisi vojak, nisi heroj si kmet. Tvoja naloga ni zgolj preživeti, ampak ponovno pognati korenine civilizacije. Prebudiš se na zapuščeni kmetiji sredi opustošene dežele. Čez dan je svet varljiv: sonce sije na ruševine, trava raste in narava si jemlje nazaj, kar je njeno.
A ko pade noč, pridejo oni. **Prekleti.**
Tvoj cilj je obnoviti kmetijo, pridelati hrano (ki je zdaj najvrednejša valuta) in zgraditi obrambo. Trgovali boste z redkimi preživelimi trgovci, ki si upajo potovati med naselbinami.
**Ključne Mehanike:**
* **Farming (Kmetovanje):** Realistična rast pridelkov (koruza, pšenica, itd.). Vsaka rastlina ima svoj cikel.
* **Survival (Preživetje):** Lakota, žeja in spanje.
* **Combat (Boj):** Brani svojo letino pred nočnimi napadi zombijev.
* **Economy (Ekonomija):** Prodajaj pridelke za zlato, kupuj boljša orodja in semena.
---
## 🛠️ Dosedanji Napredek (Feature Log)
### Faza 1: Temelji (5. - 6. Dec 2025)
- [x] Vzpostavitev projekta (Node.js, Electron).
- [x] Implementacija **Antigravity Engine** (modularni sistem).
- [x] **Proceduralno Generiranje Sveta:** Uporaba Perlin Noise za ustvarjanje neskončnega, razgibanega terena (trava, voda, pesek).
- [x] Izometrična kamera in gibanje igralca.
### Faza 2: Sistemi Igre (6. - 7. Dec 2025)
- [x] **Farming System:**
- Oranje zemlje z motiko.
- Sajenje semen.
- Faze rasti (seme -> kalček -> rastlina -> zrelo).
- Žetev pridelkov.
- [x] **Inventory System:**
- Delujoč inventar z zlaganjem (stacking).
- Drag & Drop (še v delu) / Slot selection.
- [x] **Time & Weather System:**
- Cikel dan/noč z vizualno zatemnitvijo.
- Dež (zvočni in vizualni efekti), ki namaka zemljo.
### Faza 3: Poliranje in Realizem (8. Dec 2025 - Danes)
- [x] **Statistika in XP:**
- Dodan sistem izkušenj (XP). Igralec dobiva XP za sekanje dreves, rudarjenje in pobiranje pridelkov.
- Prikaz Levela in XP vrstice v HUD-u.
- [x] **Novi Pridelki:**
- **Pšenica:** Standardni pridelek, raste srednje hitro.
- **Koruza:** Visoka rast, počasnejša, a večji donos.
- Unikatne teksture za vsako fazo rasti.
- [x] **3D Voxel Orodja:**
- Proceduralno generirana orodja v 3D "Minecraft" stilu.
- Sekira, Kramp, Motika, Meč, Zalivalka - vsa imajo volumen in senčenje.
- [x] **Zvok:**
- Proceduralno generirani zvočni effekti (kopanje, sekanje, koraki).
- Popravek manjkajočih zvokov (`playDig`).
---
## 🔮 Vizija za Naprej (TODO)
1. **Napredni NPC-ji:** Trgovci, ki pridejo le ob določenih dnevih.
2. **Gradnja Baze:** Postavljanje ograj in stolpov za obrambo.
3. **Razširitev Sveta:** Dodajanje novih biomov (gozd, puščava).
4. **Save System:** Shranjevanje napredka v datoteko.
---
*Zadnja posodobitev: 8. December 2025 ob 01:55*

View File

@@ -136,23 +136,41 @@ class TextureGenerator {
}
static createCropSprite(scene, key, stage = 4) {
if (scene.textures.exists(key)) return;
if (scene.textures.exists(key)) scene.textures.remove(key); // FORCE REFRESH to see updates
const canvas = scene.textures.createCanvas(key, 32, 32);
const ctx = canvas.getContext();
ctx.clearRect(0, 0, 32, 32);
ctx.fillStyle = '#228B22'; // Stem
const h = stage * 5;
ctx.fillRect(14, 32 - h, 4, h);
// Improved Wheat Visuals
const startY = 32;
// 1. Stems (Green -> Yellowish)
ctx.fillStyle = (stage < 3) ? '#32CD32' : '#DAA520';
const h = stage * 6;
// Draw distinct stalks
ctx.fillRect(10, startY - h, 2, h); // Left stalk
ctx.fillRect(16, startY - h, 2, h); // Center stalk
ctx.fillRect(22, startY - h, 2, h); // Right stalk
// 2. Heads (Wheat ears) - Stage 3 & 4
if (stage >= 3) {
ctx.fillStyle = '#FFD700'; // Wheat head
ctx.beginPath(); ctx.arc(16, 32 - h, 6, 0, Math.PI * 2); ctx.fill();
ctx.fillStyle = '#FFD700'; // Gold
// Left head
ctx.beginPath(); ctx.ellipse(11, startY - h, 3, 5, -0.2, 0, Math.PI * 2); ctx.fill();
// Center head
ctx.beginPath(); ctx.ellipse(17, startY - h - 2, 3, 6, 0, 0, Math.PI * 2); ctx.fill();
// Right head
ctx.beginPath(); ctx.ellipse(23, startY - h, 3, 5, 0.2, 0, Math.PI * 2); ctx.fill();
}
if (stage === 5) { // Withered
// 3. Withered
if (stage === 5) {
ctx.fillStyle = '#8B4513';
ctx.fillRect(14, 20, 4, 12);
ctx.fillRect(10, 24, 14, 8); // Dead pile
}
canvas.refresh();
}
@@ -384,138 +402,104 @@ class TextureGenerator {
}
static createToolSprites(scene) {
// --- REALISTIC TOOLS (Procedural Generation) ---
// --- 3D VOXEL TOOLS ---
// 1. AXE (Sekira)
if (!scene.textures.exists('item_axe')) {
const c = scene.textures.createCanvas('item_axe', 32, 32);
const refresh = (key) => {
if (scene.textures.exists(key)) scene.textures.remove(key);
const c = scene.textures.createCanvas(key, 32, 32);
const ctx = c.getContext();
ctx.clearRect(0, 0, 32, 32);
return { c, ctx };
};
// Handle (Wood)
ctx.fillStyle = '#8B4513';
ctx.fillRect(14, 12, 4, 18);
// Head (Metal)
ctx.fillStyle = '#708090'; // SlateGray
ctx.beginPath();
ctx.moveTo(16, 12);
ctx.lineTo(24, 6); // Top edge
ctx.lineTo(24, 18); // Bottom edge
ctx.lineTo(16, 14); // Back to handle
ctx.fill();
// Edge (Sharp)
ctx.fillStyle = '#C0C0C0'; // Silver
ctx.fillRect(23, 6, 2, 12);
c.refresh();
}
// 2. PICKAXE (Kramp)
if (!scene.textures.exists('item_pickaxe')) {
const c = scene.textures.createCanvas('item_pickaxe', 32, 32);
const ctx = c.getContext();
ctx.clearRect(0, 0, 32, 32);
// Helper: Draw 3D Pixel/Block
const drawBlock = (ctx, x, y, color) => {
ctx.fillStyle = color;
ctx.fillRect(x, y, 2, 2); // Front
ctx.fillStyle = 'rgba(0,0,0,0.3)'; // Side shadow
ctx.fillRect(x + 2, y, 1, 2);
ctx.fillRect(x, y + 2, 3, 1);
};
// 1. AXE (3D)
{
const { c, ctx } = refresh('item_axe');
// Handle
ctx.fillStyle = '#8B4513';
ctx.fillRect(14, 10, 4, 20);
// Head (Curved Metal)
ctx.fillStyle = '#696969'; // DimGray
ctx.beginPath();
ctx.moveTo(6, 14); // Left tip
ctx.quadraticCurveTo(16, 4, 26, 14); // Curve over handle
ctx.lineTo(26, 16);
ctx.quadraticCurveTo(16, 8, 6, 16);
ctx.fill();
// Tips
ctx.fillStyle = '#DCDCDC';
ctx.fillRect(5, 14, 2, 2);
ctx.fillRect(25, 14, 2, 2);
c.refresh();
}
// 3. HOE (Motika)
if (!scene.textures.exists('item_hoe')) {
const c = scene.textures.createCanvas('item_hoe', 32, 32);
const ctx = c.getContext();
ctx.clearRect(0, 0, 32, 32);
// Handle
ctx.fillStyle = '#8B4513';
ctx.fillRect(14, 6, 4, 24);
for (let i = 0; i < 8; i++) drawBlock(ctx, 12 + i, 20 - i * 2, '#8B4513');
// Head
ctx.fillStyle = '#778899'; // LightSlateGray
ctx.fillRect(12, 6, 10, 4); // Top bar
ctx.fillRect(12, 6, 4, 8); // Blade down
// Blade Edge
ctx.fillStyle = '#C0C0C0';
ctx.fillRect(12, 12, 4, 2);
for (let x = 0; x < 3; x++) {
for (let y = 0; y < 4; y++) {
drawBlock(ctx, 18 + x * 2, 6 + y * 2, '#708090'); // Gray Metal
}
}
drawBlock(ctx, 24, 8, '#C0C0C0'); // Edge
drawBlock(ctx, 24, 10, '#C0C0C0');
c.refresh();
}
// 4. SWORD (Meč)
if (!scene.textures.exists('item_sword')) {
const c = scene.textures.createCanvas('item_sword', 32, 32);
const ctx = c.getContext();
ctx.clearRect(0, 0, 32, 32);
// 2. PICKAXE (3D)
{
const { c, ctx } = refresh('item_pickaxe');
// Handle
ctx.fillStyle = '#8B4513';
ctx.fillRect(15, 24, 2, 6);
// Pommel
ctx.fillStyle = '#FFD700'; // Gold
ctx.fillRect(14, 29, 4, 2);
for (let i = 0; i < 8; i++) drawBlock(ctx, 14, 8 + i * 2, '#8B4513');
// Head (Arc)
drawBlock(ctx, 6, 10, '#696969');
drawBlock(ctx, 8, 8, '#696969');
drawBlock(ctx, 10, 6, '#696969');
drawBlock(ctx, 12, 6, '#696969');
drawBlock(ctx, 14, 6, '#696969'); // Center
drawBlock(ctx, 16, 6, '#696969');
drawBlock(ctx, 18, 6, '#696969');
drawBlock(ctx, 20, 8, '#696969');
drawBlock(ctx, 22, 10, '#696969');
c.refresh();
}
// 3. HOE (3D)
{
const { c, ctx } = refresh('item_hoe');
// Handle
for (let i = 0; i < 9; i++) drawBlock(ctx, 14 + i, 4 + i * 2, '#8B4513');
// Head
drawBlock(ctx, 12, 4, '#778899');
drawBlock(ctx, 14, 4, '#778899');
drawBlock(ctx, 16, 6, '#778899');
drawBlock(ctx, 16, 8, '#778899'); // Blade
c.refresh();
}
// 4. SWORD (3D)
{
const { c, ctx } = refresh('item_sword');
// Handle
drawBlock(ctx, 14, 24, '#8B4513');
drawBlock(ctx, 14, 26, '#8B4513');
// Guard
ctx.fillStyle = '#FFD700';
ctx.fillRect(11, 22, 10, 2);
drawBlock(ctx, 10, 22, '#FFD700');
drawBlock(ctx, 12, 22, '#FFD700');
drawBlock(ctx, 14, 22, '#FFD700');
drawBlock(ctx, 16, 22, '#FFD700');
drawBlock(ctx, 18, 22, '#FFD700');
// Blade
ctx.fillStyle = '#C0C0C0'; // Silver
ctx.fillRect(14, 4, 4, 18);
// Blood Groove / Shine
ctx.fillStyle = '#F0F8FF'; // AliceBlue
ctx.fillRect(15, 4, 2, 18);
for (let i = 0; i < 8; i++) drawBlock(ctx, 14, 6 + i * 2, '#C0C0C0');
c.refresh();
}
// 5. WATERING CAN (Zalivalka)
if (!scene.textures.exists('item_watering_can')) {
const c = scene.textures.createCanvas('item_watering_can', 32, 32);
const ctx = c.getContext();
ctx.clearRect(0, 0, 32, 32);
// Body
ctx.fillStyle = '#A9A9A9'; // DarkGray
ctx.fillRect(8, 12, 16, 14);
// Handle
ctx.strokeStyle = '#696969';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(8, 14);
ctx.quadraticCurveTo(4, 10, 8, 6);
ctx.lineTo(20, 6);
ctx.stroke();
// 5. WATERING CAN (3D)
{
const { c, ctx } = refresh('item_watering_can');
// Body 3x3 blocks
for (let x = 0; x < 4; x++)
for (let y = 0; y < 3; y++)
drawBlock(ctx, 10 + x * 2, 14 + y * 2, '#A9A9A9');
// Spout
ctx.fillStyle = '#A9A9A9';
ctx.beginPath();
ctx.moveTo(24, 16);
ctx.lineTo(30, 10);
ctx.lineTo(28, 20);
ctx.fill();
drawBlock(ctx, 18, 12, '#A9A9A9');
drawBlock(ctx, 20, 10, '#A9A9A9');
// Handle
drawBlock(ctx, 8, 12, '#696969');
drawBlock(ctx, 8, 10, '#696969');
drawBlock(ctx, 10, 8, '#696969');
c.refresh();
}
}
@@ -537,14 +521,51 @@ class TextureGenerator {
const it = typeof item === 'string' ? item : item.name;
const color = typeof item === 'string' ? 'gold' : item.color;
const k = (it.startsWith('item_')) ? it : 'item_' + it;
if (!scene.textures.exists(k)) {
if (scene.textures.exists(k)) scene.textures.remove(k); // FORCE REFRESH
const c = scene.textures.createCanvas(k, 32, 32);
const x = c.getContext();
x.clearRect(0, 0, 32, 32);
// SPECIAL ICONS
if (it === 'corn') {
// Corn Cob
x.fillStyle = '#228B22'; // Husk
x.beginPath(); x.ellipse(16, 16, 6, 12, 0, 0, Math.PI * 2); x.fill();
x.fillStyle = '#FFD700'; // Kernels
x.beginPath(); x.ellipse(16, 16, 3, 8, 0, 0, Math.PI * 2); x.fill();
}
else if (it === 'wheat') {
// Wheat Sheaf
x.strokeStyle = '#FFD700';
x.lineWidth = 2;
x.beginPath();
x.moveTo(12, 28); x.lineTo(20, 4); // Stalk 1
x.moveTo(16, 28); x.lineTo(16, 4); // Stalk 2
x.moveTo(20, 28); x.lineTo(12, 4); // Stalk 3
x.stroke();
// Tie
x.fillStyle = '#DAA520';
x.fillRect(13, 22, 6, 3);
}
else if (it.includes('seeds')) {
// Seed Bag
x.fillStyle = '#DEB887'; // Burlywood bag
x.beginPath();
x.moveTo(10, 8); x.lineTo(22, 8); // Top
x.lineTo(26, 26); x.lineTo(6, 26); // Bottom
x.fill();
// Label/Dots
x.fillStyle = color;
x.beginPath(); x.arc(16, 18, 4, 0, Math.PI * 2); x.fill();
}
else {
// Default Circle
x.fillStyle = color;
x.beginPath(); x.arc(16, 16, 10, 0, Math.PI * 2); x.fill();
c.refresh();
}
c.refresh();
});
}