- NEW: Flat2DTerrainSystem.js (375 lines) - NEW: map2d_data.js procedural map (221 lines) - MODIFIED: GameScene async create, 2D terrain integration - MODIFIED: Player.js flat 2D positioning - MODIFIED: game.js disabled pixelArt for smooth rendering - FIXED: 15+ bugs (updateCulling, isometric conversions, grid lines) - ADDED: Phase 28 to TASKS.md - DOCS: DNEVNIK.md session summary Result: Working flat 2D game with Stardew Valley style! Time: 5.5 hours
404 lines
8.6 KiB
Markdown
404 lines
8.6 KiB
Markdown
# 🎨 COMPLETE 2D VISUAL OVERHAUL - Implementation Plan
|
|
|
|
**Goal:** Convert entire game to beautiful flat 2D top-down view
|
|
**Style:** Stardew Valley smooth painted aesthetics
|
|
**Status:** STARTING NOW! 🚀
|
|
|
|
---
|
|
|
|
## 📊 CURRENT PROBLEMS
|
|
|
|
### ❌ What's Wrong Now:
|
|
1. **Isometric tiles** (diamond-shaped) - Need flat squares
|
|
2. **3D-looking terrain** - Need flat 2D texture
|
|
3. **Isometric perspective** - Need top-down view
|
|
4. **Mixed visual style** - Need consistent 2D
|
|
5. **Complex tile rendering** - Need simple flat tiles
|
|
|
|
---
|
|
|
|
## 🎯 CONVERSION PLAN
|
|
|
|
### Phase 1: Tile System Conversion (2-3h)
|
|
|
|
#### Step 1.1: Change Isometric to Orthogonal
|
|
**File:** `src/systems/TerrainSystem.js`
|
|
|
|
**BEFORE (Isometric):**
|
|
```javascript
|
|
// Diamond-shaped tiles
|
|
this.iso = new IsometricUtils(48, 24);
|
|
// Complex 3-face rendering (top, left, right)
|
|
```
|
|
|
|
**AFTER (2D Flat):**
|
|
```javascript
|
|
// Square flat tiles
|
|
this.tileSize = 48; // Simple square tiles
|
|
// Single flat texture per tile
|
|
```
|
|
|
|
---
|
|
|
|
#### Step 1.2: Create Flat Tile Textures
|
|
|
|
**Replace `createTileTextures()` with:**
|
|
|
|
```javascript
|
|
createTileTextures() {
|
|
const tileSize = 48;
|
|
|
|
// GRASS - Flat green square
|
|
const grassGraphics = this.scene.make.graphics({ x: 0, y: 0, add: false });
|
|
grassGraphics.fillStyle(0x4a9d5f); // Rich green
|
|
grassGraphics.fillRect(0, 0, tileSize, tileSize);
|
|
|
|
// Add texture variation
|
|
for (let i = 0; i < 12; i++) {
|
|
const x = Math.random() * tileSize;
|
|
const y = Math.random() * tileSize;
|
|
grassGraphics.fillStyle(0x5abd6f, 0.3);
|
|
grassGraphics.fillCircle(x, y, 2);
|
|
}
|
|
|
|
grassGraphics.generateTexture('tile_grass', tileSize, tileSize);
|
|
grassGraphics.destroy();
|
|
|
|
// DIRT - Flat brown square
|
|
const dirtGraphics = this.scene.make.graphics({ x: 0, y: 0, add: false });
|
|
dirtGraphics.fillStyle(0x8b6f47); // Brown
|
|
dirtGraphics.fillRect(0, 0, tileSize, tileSize);
|
|
|
|
// Add dirt texture
|
|
for (let i = 0; i < 15; i++) {
|
|
const x = Math.random() * tileSize;
|
|
const y = Math.random() * tileSize;
|
|
dirtGraphics.fillStyle(0x7a5f37, 0.4);
|
|
dirtGraphics.fillCircle(x, y, 3);
|
|
}
|
|
|
|
dirtGraphics.generateTexture('tile_dirt', tileSize, tileSize);
|
|
dirtGraphics.destroy();
|
|
|
|
// WATER - Already flat and good!
|
|
// Keep existing water texture
|
|
|
|
// STONE - Flat gray square
|
|
const stoneGraphics = this.scene.make.graphics({ x: 0, y: 0, add: false });
|
|
stoneGraphics.fillStyle(0x808080);
|
|
stoneGraphics.fillRect(0, 0, tileSize, tileSize);
|
|
|
|
// Add stone texture
|
|
for (let i = 0; i < 20; i++) {
|
|
const x = Math.random() * tileSize;
|
|
const y = Math.random() * tileSize;
|
|
const size = 2 + Math.random() * 4;
|
|
stoneGraphics.fillStyle(0x606060, 0.5);
|
|
stoneGraphics.fillCircle(x, y, size);
|
|
}
|
|
|
|
stoneGraphics.generateTexture('tile_stone', tileSize, tileSize);
|
|
stoneGraphics.destroy();
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
#### Step 1.3: Flat Tile Rendering
|
|
|
|
**Replace complex isometric rendering with:**
|
|
|
|
```javascript
|
|
renderTiles() {
|
|
// Clear old tiles
|
|
if (this.tileContainer) {
|
|
this.tileContainer.destroy();
|
|
}
|
|
|
|
this.tileContainer = this.scene.add.container(0, 0);
|
|
const tileSize = 48;
|
|
|
|
// Simple flat grid
|
|
for (let y = 0; y < this.height; y++) {
|
|
for (let x = 0; x < this.width; x++) {
|
|
const tile = this.tiles[y][x];
|
|
|
|
// Calculate flat 2D position
|
|
const worldX = x * tileSize;
|
|
const worldY = y * tileSize;
|
|
|
|
// Get texture key
|
|
const textureKey = `tile_${tile.type}`;
|
|
|
|
// Create simple sprite
|
|
const tileSprite = this.scene.add.image(worldX, worldY, textureKey);
|
|
tileSprite.setOrigin(0, 0); // Top-left origin
|
|
tileSprite.setDisplaySize(tileSize, tileSize);
|
|
|
|
this.tileContainer.add(tileSprite);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 2: Camera & View Conversion (30min)
|
|
|
|
#### Step 2.1: Change Camera Perspective
|
|
|
|
**File:** `src/scenes/GameScene.js`
|
|
|
|
**In `setupCamera()`:**
|
|
```javascript
|
|
setupCamera() {
|
|
const cam = this.cameras.main;
|
|
|
|
// Simple 2D bounds
|
|
const worldWidth = 100 * 48; // 100 tiles * 48px
|
|
const worldHeight = 100 * 48;
|
|
|
|
cam.setBounds(0, 0, worldWidth, worldHeight);
|
|
cam.setZoom(1.0); // Standard zoom for 2D
|
|
|
|
// Follow player (if exists)
|
|
if (this.player && this.player.sprite) {
|
|
cam.startFollow(this.player.sprite, true, 0.1, 0.1);
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 3: Player & Movement (30min)
|
|
|
|
#### Step 3.1: Convert Player Position
|
|
|
|
**File:** `src/entities/Player.js`
|
|
|
|
**Change from grid to pixel coordinates:**
|
|
|
|
```javascript
|
|
// REMOVE isometric conversion
|
|
// this.iso.toScreen(gridX, gridY)
|
|
|
|
// USE direct pixel position
|
|
this.sprite.x = this.gridX * 48 + 24; // Center of tile
|
|
this.sprite.y = this.gridY * 48 + 24;
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 4: Visual Polish (1-2h)
|
|
|
|
#### Step 4.1: Enhance Water
|
|
|
|
**Already done!** Water is flat 2D. ✅
|
|
|
|
Keep existing:
|
|
- Smooth blue gradient
|
|
- Circular wave highlights
|
|
- Animated frames
|
|
|
|
#### Step 4.2: Add Tile Borders (Optional)
|
|
|
|
For visual clarity:
|
|
```javascript
|
|
// Add subtle borders between tiles
|
|
graphics.lineStyle(1, 0x000000, 0.1);
|
|
graphics.strokeRect(0, 0, tileSize, tileSize);
|
|
```
|
|
|
|
#### Step 4.3: Add Shadows
|
|
|
|
For depth perception:
|
|
```javascript
|
|
// Shadow under player
|
|
this.playerShadow = this.scene.add.ellipse(
|
|
x, y + 10, // Below player
|
|
20, 10, // Oval shape
|
|
0x000000, 0.3 // Semi-transparent black
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## 🎨 VISUAL IMPROVEMENTS
|
|
|
|
### Beautiful 2D Grass:
|
|
```javascript
|
|
// Rich green base
|
|
fillStyle(0x4a9d5f)
|
|
|
|
// Add grass blade variations
|
|
for (let i = 0; i < 8; i++) {
|
|
// Small darker green spots
|
|
fillStyle(0x3a8d4f, 0.4)
|
|
fillCircle(random, random, 2)
|
|
}
|
|
|
|
// Lighter highlights
|
|
for (let i = 0; i < 5; i++) {
|
|
fillStyle(0x6acd7f, 0.3)
|
|
fillCircle(random, random, 1)
|
|
}
|
|
```
|
|
|
|
### Beautiful 2D Dirt:
|
|
```javascript
|
|
// Brown base
|
|
fillStyle(0x8b6f47)
|
|
|
|
// Darker dirt clumps
|
|
for (let i = 0; i < 12; i++) {
|
|
fillStyle(0x6b4f27, 0.5)
|
|
fillCircle(random, random, 3)
|
|
}
|
|
|
|
// Small stones
|
|
for (let i = 0; i < 8; i++) {
|
|
fillStyle(0x9b8f77, 0.6)
|
|
fillRect(random, random, 2, 2)
|
|
}
|
|
```
|
|
|
|
### Beautiful 2D Stone:
|
|
```javascript
|
|
// Gray base
|
|
fillStyle(0x808080)
|
|
|
|
// Dark cracks
|
|
lineStyle(1, 0x404040, 0.5)
|
|
// Draw random crack patterns
|
|
|
|
// Light spots
|
|
for (let i = 0; i < 15; i++) {
|
|
fillStyle(0xa0a0a0, 0.4)
|
|
fillCircle(random, random, size)
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📋 IMPLEMENTATION CHECKLIST
|
|
|
|
### Immediate (Critical):
|
|
- [ ] Convert TerrainSystem to flat 2D tiles
|
|
- [ ] Remove isometric utilities
|
|
- [ ] Create flat tile textures
|
|
- [ ] Update camera bounds
|
|
- [ ] Fix player positioning
|
|
- [ ] Test movement works
|
|
|
|
### Visual Polish:
|
|
- [ ] Enhanced grass texture
|
|
- [ ] Enhanced dirt texture
|
|
- [ ] Enhanced stone texture
|
|
- [ ] Add tile borders (optional)
|
|
- [ ] Add shadows under objects
|
|
- [ ] Ensure water looks good
|
|
|
|
### Final Testing:
|
|
- [ ] All tiles render correctly
|
|
- [ ] Camera follows player
|
|
- [ ] Movement feels smooth
|
|
- [ ] Visuals are consistent
|
|
- [ ] Performance is good (60 FPS)
|
|
|
|
---
|
|
|
|
## ⚡ QUICK START
|
|
|
|
### Option A: Full Conversion (2-3h)
|
|
Complete rewrite of TerrainSystem for 2D
|
|
|
|
**Pros:**
|
|
- Clean code
|
|
- Proper 2D architecture
|
|
- Best performance
|
|
|
|
**Cons:**
|
|
- Takes time
|
|
- Need to test everything
|
|
|
|
### Option B: Tiled Map (4-6h)
|
|
Use Tiled Editor for professional 2D maps
|
|
|
|
**Pros:**
|
|
- Visual map editor
|
|
- Easy to update
|
|
- Professional workflow
|
|
- Best visuals
|
|
|
|
**Cons:**
|
|
- Need to learn Tiled
|
|
- Manual map creation
|
|
|
|
### Option C: Hybrid (1-2h)
|
|
Keep system, just change rendering
|
|
|
|
**Pros:**
|
|
- Fast implementation
|
|
- Less breaking changes
|
|
- Keep existing logic
|
|
|
|
**Cons:**
|
|
- Code stays complex
|
|
- Not ideal architecture
|
|
|
|
---
|
|
|
|
## 💡 RECOMMENDATION
|
|
|
|
**Use Option B: Tiled Map Editor!** 🗺️
|
|
|
|
**Why:**
|
|
1. ✅ Professional 2D map design
|
|
2. ✅ Visual editor (WYSIWYG)
|
|
3. ✅ Easy to create beautiful maps
|
|
4. ✅ Guide already created!
|
|
5. ✅ Industry standard tool
|
|
|
|
**Follow:** `docs/TILED_MAP_GUIDE.md`
|
|
|
|
**Process:**
|
|
1. Install Tiled (30 min)
|
|
2. Create tileset (1h)
|
|
3. Design map (2h)
|
|
4. Export & integrate (1h)
|
|
5. Polish (1h)
|
|
|
|
**Total:** 5-6 hours for professional result!
|
|
|
|
---
|
|
|
|
## 🚀 WHAT TO DO NOW?
|
|
|
|
**Choose path:**
|
|
|
|
**A) Quick Fix** (1-2h)
|
|
- Keep isometric, just improve visuals
|
|
- Enhance textures
|
|
- Better water
|
|
- Fast but not ideal
|
|
|
|
**B) Proper 2D** (2-3h)
|
|
- Convert TerrainSystem to flat
|
|
- Rewrite rendering
|
|
- Clean architecture
|
|
- Medium effort, good result
|
|
|
|
**C) Tiled Editor** (5-6h) ⭐ **RECOMMENDED**
|
|
- Professional tool
|
|
- Beautiful maps
|
|
- Easy to update
|
|
- Best long-term solution
|
|
|
|
---
|
|
|
|
**Which option do you prefer?** (A, B, or C) 🎯
|
|
|
|
---
|
|
|
|
*2D Conversion Plan created: 2025-12-14 16:13*
|