FAZA 0: Initial project setup - Electron + Phaser configuration
This commit is contained in:
25
.gitignore
vendored
Normal file
25
.gitignore
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Dependencies
|
||||
node_modules/
|
||||
package-lock.json
|
||||
|
||||
# Build output
|
||||
dist/
|
||||
build/
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Environment
|
||||
.env
|
||||
.env.local
|
||||
185
dev_plan.md
Normal file
185
dev_plan.md
Normal file
@@ -0,0 +1,185 @@
|
||||
# Začnemo nov projekt
|
||||
- Ne uporabi znanja iz prejšnjih projektov
|
||||
- Ustvari opravila (tasks)
|
||||
- Ustvari lokalni git za uporabnika hipodevil666@gmail.com
|
||||
|
||||
# Tehnologija
|
||||
- Uporabi Node.js (verzija 18+)
|
||||
- Uporabi Phaser.io (verzija 3.60+)
|
||||
- Za gradnjo igre za PC uporabi Electron.js (verzija 27+)
|
||||
|
||||
# Tehnične zahteve
|
||||
- Resolucija okna: 1280x720
|
||||
- Velikost sprite-a igralca: 32x32px
|
||||
- Velikost kocke terena: 48x48px (isometric)
|
||||
- Git repository: local
|
||||
|
||||
# Igra
|
||||
- Igra bo igra preživetja (survival game)
|
||||
- Igra bo 2.5D isometrični pogled mape, ki je videti 3D
|
||||
- Igralec in NPC-ji so 2D pixel art
|
||||
- Slog igre je pixelart
|
||||
|
||||
---
|
||||
|
||||
## FAZA 0: Projektni Setup
|
||||
**Status:** ⏳ V teku
|
||||
|
||||
### Opravila:
|
||||
- [ ] Inicializacija npm projekta
|
||||
- [ ] Setup Git repository
|
||||
- [ ] Kreiranje strukture map (src/, assets/, dist/)
|
||||
- [ ] Instalacija odvisnosti (Phaser, Electron)
|
||||
- [ ] Osnovna konfiguracija Electron + Phaser
|
||||
- [ ] Test run: prazno črno okno
|
||||
|
||||
### Testiranje (ročno):
|
||||
✅ **Naročnik potrdi:** Electron okno se odpre in prikaže prazno Phaser sceno
|
||||
|
||||
---
|
||||
|
||||
## FAZA 1: Generacija Terena
|
||||
**Status:** ⏸️ Čaka
|
||||
|
||||
### Opravila:
|
||||
- [ ] Implementacija proceduralnega generatorja terena (Perlin noise)
|
||||
- [ ] Definicija osnovnih tipov terena (trava, zemlja, kamen)
|
||||
- [ ] Testiranje na zemljevidu velikosti 100x100 kock 2.5D
|
||||
- [ ] Implementacija isometričnega pogleda
|
||||
- [ ] Osnovna kamera kontrola (zoom, pan)
|
||||
|
||||
### Tehnične specifikacije:
|
||||
- Velikost mape: 100x100 kock
|
||||
- Tip generacije: Perlin noise
|
||||
- Tipi terena: grass, dirt, stone
|
||||
- Isometric tile: 48x48px
|
||||
|
||||
### Testiranje (ročno):
|
||||
✅ **Naročnik potrdi:** Teren se generira, isometric view je pravilen, kamera deluje
|
||||
|
||||
---
|
||||
|
||||
## FAZA 2: Igralec in Gibanje
|
||||
**Status:** ⏸️ Čaka
|
||||
|
||||
### Opravila:
|
||||
- [ ] Dodaj igralca (2D pixel art sprite 32x32px)
|
||||
- [ ] Implementacija WASD gibanja
|
||||
- [ ] Depth sorting (z-index za isometric view)
|
||||
- [ ] Testiranje kolizije z robovi mape
|
||||
- [ ] Dodaj barvno shemo za teren (gradient, variacije)
|
||||
- [ ] Dodaj barvno shemo za igralca
|
||||
|
||||
### Tehnične specifikacije:
|
||||
- Hitrost gibanja: 150 px/s
|
||||
- Kontrole: WASD
|
||||
- Sprite: 32x32px pixel art
|
||||
- Depth sorting: po Y koordinati
|
||||
|
||||
### Testiranje (ročno):
|
||||
✅ **Naročnik potrdi:** Igralec se giblje, depth sorting deluje, kolizije pravilne
|
||||
|
||||
---
|
||||
|
||||
## FAZA 3: NPC-ji in Dekoracije
|
||||
**Status:** ⏸️ Čaka
|
||||
|
||||
### Opravila:
|
||||
- [ ] Dodaj NPC-je (3 na velikost 100x100)
|
||||
- [ ] Implementacija AI gibanja (random walk)
|
||||
- [ ] Dodaj okrasne elemente: rože, grmičevje
|
||||
- [ ] Dodaj parallax okrasne elemente: oblaki, ptice
|
||||
- [ ] Variacije okrasnih elementov (različne barve, velikosti)
|
||||
|
||||
### Tehnične specifikacije:
|
||||
- Število NPC: 3 na 100x100 mapo
|
||||
- AI: Random walk z pauzami
|
||||
- Okrasni elementi: 5-10 različnih variant
|
||||
- Parallax hitrost: 0.3x (oblaki), 0.5x (ptice)
|
||||
|
||||
### Testiranje (ročno):
|
||||
✅ **Naročnik potrdi:** NPC-ji se gibljejo, dekoracije prisotne, parallax učinek deluje
|
||||
|
||||
---
|
||||
|
||||
## FAZA 4: Optimizacija in Performance
|
||||
**Status:** ⏸️ Čaka
|
||||
|
||||
### Opravila:
|
||||
- [ ] Culling: renderiranje samo vidnih tiles
|
||||
- [ ] Object pooling za sprite-e
|
||||
- [ ] FPS monitor
|
||||
- [ ] Performance testing (60 FPS minimum)
|
||||
- [ ] Memory leak check
|
||||
|
||||
### Testiranje (ročno):
|
||||
✅ **Naročnik potrdi:** Igra teče pri 60 FPS, brez memory leakov
|
||||
|
||||
---
|
||||
|
||||
## FAZA 5: UI Elementi
|
||||
**Status:** ⏸️ Čaka
|
||||
|
||||
### Opravila:
|
||||
- [ ] Zdravje (HP bar)
|
||||
- [ ] Lakota/žeja merila
|
||||
- [ ] Mini mapa
|
||||
- [ ] Inventar (osnovni)
|
||||
|
||||
### Testiranje (ročno):
|
||||
✅ **Naročnik potrdi:** UI elementi so vidni in funkcionalni
|
||||
|
||||
---
|
||||
|
||||
## FAZA 6: Save/Load Sistem
|
||||
**Status:** ⏸️ Čaka
|
||||
|
||||
### Opravila:
|
||||
- [ ] Serializacija stanja igre
|
||||
- [ ] Shranjevanje v localStorage/file
|
||||
- [ ] Nalaganje shranjenega stanja
|
||||
- [ ] Auto-save funkcionalnost
|
||||
|
||||
### Testiranje (ročno):
|
||||
✅ **Naročnik potrdi:** Save/Load deluje, stanje se ohranja
|
||||
|
||||
---
|
||||
|
||||
## FAZA 7: Survival Mehanike
|
||||
**Status:** ⏸️ Čaka
|
||||
|
||||
### Opravila:
|
||||
- [ ] Dan/noč cikel
|
||||
- [ ] Sistem lakote in žeje
|
||||
- [ ] Zbiranje virov
|
||||
- [ ] Crafting osnove
|
||||
|
||||
### Testiranje (ročno):
|
||||
✅ **Naročnik potrdi:** Survival mehanike delujejo
|
||||
|
||||
---
|
||||
|
||||
## FAZA 8: Electron Build
|
||||
**Status:** ⏸️ Čaka
|
||||
|
||||
### Opravila:
|
||||
- [ ] Electron packaging
|
||||
- [ ] Windows .exe build
|
||||
- [ ] Ikone in metadata
|
||||
- [ ] Installer kreacija
|
||||
|
||||
### Testiranje (ročno):
|
||||
✅ **Naročnik potrdi:** .exe se zažene samostojno, installer deluje
|
||||
|
||||
---
|
||||
|
||||
## Navodila za testiranje
|
||||
**Vsaka faza zahteva ročno potrditev naročnika pred prehodom na naslednjo fazo.**
|
||||
|
||||
Format potrditve:
|
||||
```
|
||||
FAZA [N]: [STATUS]
|
||||
- Testirano: [DA/NE]
|
||||
- Opombe: [opombe naročnika]
|
||||
- Odobreno: [DA/NE]
|
||||
```
|
||||
41
index.html
Normal file
41
index.html
Normal file
@@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="sl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>NovaFarma - 2.5D Survival Game</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #000;
|
||||
overflow: hidden;
|
||||
font-family: 'Courier New', monospace;
|
||||
}
|
||||
|
||||
#game-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="game-container"></div>
|
||||
|
||||
<!-- Phaser 3 -->
|
||||
<script src="node_modules/phaser/dist/phaser.js"></script>
|
||||
|
||||
<!-- Game Files -->
|
||||
<script src="src/scenes/BootScene.js"></script>
|
||||
<script src="src/scenes/PreloadScene.js"></script>
|
||||
<script src="src/scenes/GameScene.js"></script>
|
||||
<script src="src/game.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
42
main.js
Normal file
42
main.js
Normal file
@@ -0,0 +1,42 @@
|
||||
const { app, BrowserWindow } = require('electron');
|
||||
const path = require('path');
|
||||
|
||||
let mainWindow;
|
||||
|
||||
function createWindow() {
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1280,
|
||||
height: 720,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false
|
||||
},
|
||||
backgroundColor: '#000000',
|
||||
title: 'NovaFarma - 2.5D Survival Game'
|
||||
});
|
||||
|
||||
mainWindow.loadFile('index.html');
|
||||
|
||||
// Odpri DevTools (za development)
|
||||
mainWindow.webContents.openDevTools();
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = null;
|
||||
});
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow();
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
20
package.json
Normal file
20
package.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "novafarma",
|
||||
"version": "1.0.0",
|
||||
"description": "NovaFarma - 2.5D Isometric Survival Game",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"start": "electron .",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"type": "commonjs",
|
||||
"dependencies": {
|
||||
"phaser": "^3.80.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "^33.2.1"
|
||||
}
|
||||
}
|
||||
34
src/game.js
Normal file
34
src/game.js
Normal file
@@ -0,0 +1,34 @@
|
||||
// Phaser Game Configuration
|
||||
const config = {
|
||||
type: Phaser.AUTO,
|
||||
width: 1280,
|
||||
height: 720,
|
||||
parent: 'game-container',
|
||||
backgroundColor: '#1a1a2e',
|
||||
pixelArt: true,
|
||||
antialias: false,
|
||||
roundPixels: true,
|
||||
physics: {
|
||||
default: 'arcade',
|
||||
arcade: {
|
||||
gravity: { y: 0 },
|
||||
debug: false
|
||||
}
|
||||
},
|
||||
scene: [BootScene, PreloadScene, GameScene],
|
||||
scale: {
|
||||
mode: Phaser.Scale.FIT,
|
||||
autoCenter: Phaser.Scale.CENTER_BOTH
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize game
|
||||
const game = new Phaser.Game(config);
|
||||
|
||||
// Global game state
|
||||
window.gameState = {
|
||||
currentScene: null,
|
||||
debugMode: true
|
||||
};
|
||||
|
||||
console.log('🎮 NovaFarma initialized!');
|
||||
48
src/scenes/BootScene.js
Normal file
48
src/scenes/BootScene.js
Normal file
@@ -0,0 +1,48 @@
|
||||
// Boot Scene - Inicializacija sistema
|
||||
class BootScene extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'BootScene' });
|
||||
}
|
||||
|
||||
preload() {
|
||||
console.log('🚀 BootScene: Initializing...');
|
||||
|
||||
// Loading bar setup
|
||||
const width = this.cameras.main.width;
|
||||
const height = this.cameras.main.height;
|
||||
|
||||
const progressBar = this.add.graphics();
|
||||
const progressBox = this.add.graphics();
|
||||
progressBox.fillStyle(0x222222, 0.8);
|
||||
progressBox.fillRect(width / 2 - 160, height / 2 - 25, 320, 50);
|
||||
|
||||
const loadingText = this.add.text(width / 2, height / 2 - 50, 'Loading...', {
|
||||
fontFamily: 'Courier New',
|
||||
fontSize: '20px',
|
||||
fill: '#ffffff'
|
||||
});
|
||||
loadingText.setOrigin(0.5, 0.5);
|
||||
|
||||
this.load.on('progress', (value) => {
|
||||
progressBar.clear();
|
||||
progressBar.fillStyle(0x00ff41, 1);
|
||||
progressBar.fillRect(width / 2 - 150, height / 2 - 15, 300 * value, 30);
|
||||
});
|
||||
|
||||
this.load.on('complete', () => {
|
||||
progressBar.destroy();
|
||||
progressBox.destroy();
|
||||
loadingText.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
create() {
|
||||
console.log('✅ BootScene: Complete!');
|
||||
window.gameState.currentScene = 'BootScene';
|
||||
|
||||
// Takoj po bootu gremo v PreloadScene
|
||||
this.time.delayedCall(100, () => {
|
||||
this.scene.start('PreloadScene');
|
||||
});
|
||||
}
|
||||
}
|
||||
48
src/scenes/GameScene.js
Normal file
48
src/scenes/GameScene.js
Normal file
@@ -0,0 +1,48 @@
|
||||
// Game Scene - Glavna igralna scena
|
||||
class GameScene extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'GameScene' });
|
||||
}
|
||||
|
||||
create() {
|
||||
console.log('🎮 GameScene: Initialized!');
|
||||
window.gameState.currentScene = 'GameScene';
|
||||
|
||||
const width = this.cameras.main.width;
|
||||
const height = this.cameras.main.height;
|
||||
|
||||
// Testno besedilo - potrditev da scena deluje
|
||||
const testText = this.add.text(width / 2, height / 2, 'FAZA 0: Setup Complete!\n\nGame Scene Active', {
|
||||
fontFamily: 'Courier New',
|
||||
fontSize: '32px',
|
||||
fill: '#00ff41',
|
||||
align: 'center'
|
||||
});
|
||||
testText.setOrigin(0.5);
|
||||
|
||||
// Debug info
|
||||
const debugText = this.add.text(10, 10, 'FAZA 0 TEST\nElectron + Phaser OK', {
|
||||
fontFamily: 'Courier New',
|
||||
fontSize: '14px',
|
||||
fill: '#ffffff',
|
||||
backgroundColor: '#000000',
|
||||
padding: { x: 10, y: 5 }
|
||||
});
|
||||
|
||||
// FPS counter
|
||||
this.fpsText = this.add.text(10, height - 30, 'FPS: 60', {
|
||||
fontFamily: 'Courier New',
|
||||
fontSize: '14px',
|
||||
fill: '#00ff41'
|
||||
});
|
||||
|
||||
console.log('✅ Faza 0 setup complete - ready for manual testing!');
|
||||
}
|
||||
|
||||
update() {
|
||||
// Update FPS
|
||||
if (this.fpsText) {
|
||||
this.fpsText.setText(`FPS: ${Math.round(this.game.loop.actualFps)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
59
src/scenes/PreloadScene.js
Normal file
59
src/scenes/PreloadScene.js
Normal file
@@ -0,0 +1,59 @@
|
||||
// Preload Scene - Nalaganje assetov
|
||||
class PreloadScene extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'PreloadScene' });
|
||||
}
|
||||
|
||||
preload() {
|
||||
console.log('📦 PreloadScene: Loading assets...');
|
||||
|
||||
// TODO: Tu bomo nalagali sprite-e, tile-e, audio, itd.
|
||||
// Za fazo 0 pustimo prazno - samo testiramo osnovni setup
|
||||
}
|
||||
|
||||
create() {
|
||||
console.log('✅ PreloadScene: Assets loaded!');
|
||||
window.gameState.currentScene = 'PreloadScene';
|
||||
|
||||
// Prikaz začetnega sporočila
|
||||
const width = this.cameras.main.width;
|
||||
const height = this.cameras.main.height;
|
||||
|
||||
const title = this.add.text(width / 2, height / 2 - 50, 'NOVAFARMA', {
|
||||
fontFamily: 'Courier New',
|
||||
fontSize: '48px',
|
||||
fill: '#00ff41',
|
||||
fontStyle: 'bold'
|
||||
});
|
||||
title.setOrigin(0.5);
|
||||
|
||||
const subtitle = this.add.text(width / 2, height / 2 + 10, '2.5D Isometric Survival Game', {
|
||||
fontFamily: 'Courier New',
|
||||
fontSize: '20px',
|
||||
fill: '#ffffff'
|
||||
});
|
||||
subtitle.setOrigin(0.5);
|
||||
|
||||
const instruction = this.add.text(width / 2, height / 2 + 60, 'Press SPACE to start', {
|
||||
fontFamily: 'Courier New',
|
||||
fontSize: '16px',
|
||||
fill: '#888888'
|
||||
});
|
||||
instruction.setOrigin(0.5);
|
||||
|
||||
// Blinking effect
|
||||
this.tweens.add({
|
||||
targets: instruction,
|
||||
alpha: 0.3,
|
||||
duration: 800,
|
||||
yoyo: true,
|
||||
repeat: -1
|
||||
});
|
||||
|
||||
// Pritisk SPACE za začetek igre
|
||||
this.input.keyboard.once('keydown-SPACE', () => {
|
||||
console.log('🎮 Starting GameScene...');
|
||||
this.scene.start('GameScene');
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user