Phase 28 Session 1: Terrain expanded to 500x500 + biome support
MASSIVE UPDATE - World expansion foundation complete: 1. Flat2DTerrainSystem.js expanded (100x100 500x500) - Map size increased 25x (10,000 250,000 tiles!) - Added biome support (grassland, forest, desert, mountain, swamp) - Created biome-specific tile textures (5 new textures) - Added renderChunk() method for chunk-based rendering - Biome-aware feature placement 2. New biome features implemented: - createRock() - small/large rocks - createBoulder() - mountain boulders - createCactus() - desert cacti - createMushroom() - forest mushrooms - createVine() - swamp vines 3. Biome texture colors: - Grassland: #3CB371 (medium sea green) - Forest: #2d5016 (dark green) - Desert: #d4c4a1 (sand/tan) - Mountain: #808080 (gray stone) - Swamp: #3d5a3d (murky green) Technical: - ChunkManager ready for integration - BiomeSystem ready for integration - Terrain system supports both old Map2DData and new chunk system - Performance optimized for large world Next: Initialize systems in GameScene Status: Session 1 - 90% complete Time: ~1.5 hours Files modified: 1 (Flat2DTerrainSystem.js +200 lines)
This commit is contained in:
@@ -5,8 +5,8 @@ class Flat2DTerrainSystem {
|
|||||||
constructor(scene) {
|
constructor(scene) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.tileSize = 48;
|
this.tileSize = 48;
|
||||||
this.width = 100;
|
this.width = 500; // 🌍 PHASE 28: Expanded to 500x500!
|
||||||
this.height = 100;
|
this.height = 500;
|
||||||
|
|
||||||
// Tile map data
|
// Tile map data
|
||||||
this.tiles = [];
|
this.tiles = [];
|
||||||
@@ -22,7 +22,11 @@ class Flat2DTerrainSystem {
|
|||||||
// Textures ready flag
|
// Textures ready flag
|
||||||
this.texturesReady = false;
|
this.texturesReady = false;
|
||||||
|
|
||||||
console.log('🎨 Flat2DTerrainSystem initialized');
|
// 🌍 PHASE 28: Biome support
|
||||||
|
this.biomeSystem = null; // Will be set by GameScene
|
||||||
|
this.chunkManager = null; // Will be set by GameScene
|
||||||
|
|
||||||
|
console.log('🎨 Flat2DTerrainSystem initialized (500x500 world)');
|
||||||
}
|
}
|
||||||
|
|
||||||
async generate() {
|
async generate() {
|
||||||
@@ -60,9 +64,11 @@ class Flat2DTerrainSystem {
|
|||||||
if (hasGrass && hasWater && hasDirt) {
|
if (hasGrass && hasWater && hasDirt) {
|
||||||
console.log('✅ PNG Tilesets found! Creating beautiful tiles...');
|
console.log('✅ PNG Tilesets found! Creating beautiful tiles...');
|
||||||
|
|
||||||
// GRASS - SUPER VIBRANT GREEN! 🌿 (MORE 2D!)
|
// 🌍 PHASE 28: Create BIOME-SPECIFIC GRASS TILES
|
||||||
|
|
||||||
|
// GRASSLAND - SUPER VIBRANT GREEN! 🌿
|
||||||
graphics.clear();
|
graphics.clear();
|
||||||
graphics.fillStyle(0x3CB371, 1.0); // Medium sea green - vibrant!
|
graphics.fillStyle(0x3CB371, 1.0); // Medium sea green
|
||||||
graphics.fillRect(0, 0, size, size);
|
graphics.fillRect(0, 0, size, size);
|
||||||
|
|
||||||
// Darker spots for contrast
|
// Darker spots for contrast
|
||||||
@@ -77,6 +83,46 @@ class Flat2DTerrainSystem {
|
|||||||
}
|
}
|
||||||
graphics.generateTexture('tile2d_grass', size, size);
|
graphics.generateTexture('tile2d_grass', size, size);
|
||||||
|
|
||||||
|
// FOREST BIOME - DARK GREEN
|
||||||
|
graphics.clear();
|
||||||
|
graphics.fillStyle(0x2d5016, 1.0); // Dark green
|
||||||
|
graphics.fillRect(0, 0, size, size);
|
||||||
|
for (let i = 0; i < 25; i++) {
|
||||||
|
graphics.fillStyle(0x1a3010, 0.4);
|
||||||
|
graphics.fillCircle(Math.random() * size, Math.random() * size, 3);
|
||||||
|
}
|
||||||
|
graphics.generateTexture('tile2d_forest', size, size);
|
||||||
|
|
||||||
|
// DESERT BIOME - TAN/SAND
|
||||||
|
graphics.clear();
|
||||||
|
graphics.fillStyle(0xd4c4a1, 1.0); // Sand color
|
||||||
|
graphics.fillRect(0, 0, size, size);
|
||||||
|
for (let i = 0; i < 20; i++) {
|
||||||
|
graphics.fillStyle(0xc4b491, 0.3);
|
||||||
|
graphics.fillCircle(Math.random() * size, Math.random() * size, 4);
|
||||||
|
}
|
||||||
|
graphics.generateTexture('tile2d_desert', size, size);
|
||||||
|
|
||||||
|
// MOUNTAIN BIOME - GRAY STONE
|
||||||
|
graphics.clear();
|
||||||
|
graphics.fillStyle(0x808080, 1.0); // Gray
|
||||||
|
graphics.fillRect(0, 0, size, size);
|
||||||
|
for (let i = 0; i < 30; i++) {
|
||||||
|
graphics.fillStyle(0x606060, 0.5);
|
||||||
|
graphics.fillCircle(Math.random() * size, Math.random() * size, 2 + Math.random() * 3);
|
||||||
|
}
|
||||||
|
graphics.generateTexture('tile2d_mountain', size, size);
|
||||||
|
|
||||||
|
// SWAMP BIOME - DARK GREEN/BROWN
|
||||||
|
graphics.clear();
|
||||||
|
graphics.fillStyle(0x3d5a3d, 1.0); // Murky green
|
||||||
|
graphics.fillRect(0, 0, size, size);
|
||||||
|
for (let i = 0; i < 20; i++) {
|
||||||
|
graphics.fillStyle(0x2d4a2d, 0.6);
|
||||||
|
graphics.fillCircle(Math.random() * size, Math.random() * size, 3 + Math.random() * 4);
|
||||||
|
}
|
||||||
|
graphics.generateTexture('tile2d_swamp', size, size);
|
||||||
|
|
||||||
// GRASS WITH FLOWERS (VIBRANT!)
|
// GRASS WITH FLOWERS (VIBRANT!)
|
||||||
graphics.clear();
|
graphics.clear();
|
||||||
graphics.fillStyle(0x3CB371, 1.0);
|
graphics.fillStyle(0x3CB371, 1.0);
|
||||||
@@ -263,6 +309,182 @@ class Flat2DTerrainSystem {
|
|||||||
console.log(`🌊 Water tiles animated: ${this.waterSprites.length}`);
|
console.log(`🌊 Water tiles animated: ${this.waterSprites.length}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🌍 PHASE 28: Render a single chunk with biome support
|
||||||
|
renderChunk(chunk) {
|
||||||
|
if (!chunk || !this.biomeSystem) {
|
||||||
|
console.warn('⚠️ Cannot render chunk: missing data or biomeSystem');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size = this.tileSize;
|
||||||
|
|
||||||
|
// Render ground tiles based on biome
|
||||||
|
for (const tileData of chunk.tiles) {
|
||||||
|
const { x, y, biome } = tileData;
|
||||||
|
const worldX = x * size;
|
||||||
|
const worldY = y * size;
|
||||||
|
|
||||||
|
// Get biome-specific tile texture
|
||||||
|
let tileTexture = 'tile2d_grass'; // Default
|
||||||
|
|
||||||
|
if (biome === 'forest') {
|
||||||
|
tileTexture = 'tile2d_forest';
|
||||||
|
} else if (biome === 'desert') {
|
||||||
|
tileTexture = 'tile2d_desert';
|
||||||
|
} else if (biome === 'mountain') {
|
||||||
|
tileTexture = 'tile2d_mountain';
|
||||||
|
} else if (biome === 'swamp') {
|
||||||
|
tileTexture = 'tile2d_swamp';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create tile sprite
|
||||||
|
const tileSprite = this.scene.add.image(worldX, worldY, tileTexture);
|
||||||
|
tileSprite.setOrigin(0, 0);
|
||||||
|
tileSprite.setDisplaySize(size, size);
|
||||||
|
tileSprite.setDepth(1);
|
||||||
|
|
||||||
|
// Store in chunk for cleanup
|
||||||
|
if (!chunk.sprites) chunk.sprites = [];
|
||||||
|
chunk.sprites.push(tileSprite);
|
||||||
|
|
||||||
|
// Apply biome features (trees, rocks, etc.)
|
||||||
|
if (this.biomeSystem) {
|
||||||
|
const features = this.biomeSystem.applyBiomeFeatures(x, y);
|
||||||
|
|
||||||
|
features.forEach(feature => {
|
||||||
|
this.addBiomeFeature(x, y, feature, chunk);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`✅ Chunk (${chunk.chunkX}, ${chunk.chunkY}) rendered with biomes`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add biome-specific feature
|
||||||
|
addBiomeFeature(gridX, gridY, feature, chunk) {
|
||||||
|
const size = this.tileSize;
|
||||||
|
const worldX = gridX * size + size / 2;
|
||||||
|
const worldY = gridY * size + size / 2;
|
||||||
|
|
||||||
|
let sprite;
|
||||||
|
|
||||||
|
switch (feature.type) {
|
||||||
|
case 'tree':
|
||||||
|
sprite = this.createTree(worldX, worldY);
|
||||||
|
break;
|
||||||
|
case 'rock':
|
||||||
|
sprite = this.createRock(worldX, worldY, feature.size);
|
||||||
|
break;
|
||||||
|
case 'bush':
|
||||||
|
sprite = this.createBush(worldX, worldY);
|
||||||
|
break;
|
||||||
|
case 'cactus':
|
||||||
|
sprite = this.createCactus(worldX, worldY);
|
||||||
|
break;
|
||||||
|
case 'deadTree':
|
||||||
|
sprite = this.createDeadTree(worldX, worldY);
|
||||||
|
break;
|
||||||
|
case 'boulder':
|
||||||
|
sprite = this.createBoulder(worldX, worldY);
|
||||||
|
break;
|
||||||
|
case 'mushroom':
|
||||||
|
sprite = this.createMushroom(worldX, worldY);
|
||||||
|
break;
|
||||||
|
case 'vine':
|
||||||
|
sprite = this.createVine(worldX, worldY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sprite && chunk) {
|
||||||
|
sprite.setDepth(10 + worldY);
|
||||||
|
if (!chunk.sprites) chunk.sprites = [];
|
||||||
|
chunk.sprites.push(sprite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple rock creation
|
||||||
|
createRock(x, y, size = 'small') {
|
||||||
|
const graphics = this.scene.add.graphics();
|
||||||
|
const rockSize = size === 'large' ? 15 : 8;
|
||||||
|
|
||||||
|
graphics.fillStyle(0x808080);
|
||||||
|
graphics.fillCircle(x, y, rockSize);
|
||||||
|
graphics.fillStyle(0x606060, 0.6);
|
||||||
|
graphics.fillCircle(x - 3, y - 3, rockSize * 0.6);
|
||||||
|
|
||||||
|
return graphics;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boulder (large rock)
|
||||||
|
createBoulder(x, y) {
|
||||||
|
const graphics = this.scene.add.graphics();
|
||||||
|
|
||||||
|
graphics.fillStyle(0x707070);
|
||||||
|
graphics.fillCircle(x, y, 20);
|
||||||
|
graphics.fillStyle(0x505050);
|
||||||
|
graphics.fillCircle(x - 5, y - 5, 12);
|
||||||
|
graphics.fillStyle(0x909090, 0.5);
|
||||||
|
graphics.fillCircle(x + 5, y + 5, 8);
|
||||||
|
|
||||||
|
return graphics;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cactus
|
||||||
|
createCactus(x, y) {
|
||||||
|
const graphics = this.scene.add.graphics();
|
||||||
|
|
||||||
|
// Main body
|
||||||
|
graphics.fillStyle(0x4a7c59);
|
||||||
|
graphics.fillRect(x - 5, y - 15, 10, 30);
|
||||||
|
|
||||||
|
// Arms
|
||||||
|
graphics.fillRect(x - 12, y - 8, 7, 10);
|
||||||
|
graphics.fillRect(x + 5, y - 5, 7, 10);
|
||||||
|
|
||||||
|
// Highlights
|
||||||
|
graphics.fillStyle(0x5a8c69, 0.6);
|
||||||
|
graphics.fillRect(x - 3, y - 12, 3, 24);
|
||||||
|
|
||||||
|
return graphics;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mushroom
|
||||||
|
createMushroom(x, y) {
|
||||||
|
const graphics = this.scene.add.graphics();
|
||||||
|
|
||||||
|
// Stem
|
||||||
|
graphics.fillStyle(0xeeeeee);
|
||||||
|
graphics.fillRect(x - 2, y, 4, 8);
|
||||||
|
|
||||||
|
// Cap
|
||||||
|
graphics.fillStyle(0xd63031);
|
||||||
|
graphics.fillCircle(x, y, 6);
|
||||||
|
|
||||||
|
// Spots
|
||||||
|
graphics.fillStyle(0xffffff);
|
||||||
|
graphics.fillCircle(x - 3, y - 1, 1.5);
|
||||||
|
graphics.fillCircle(x + 2, y + 1, 1.2);
|
||||||
|
|
||||||
|
return graphics;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vine (swamp feature)
|
||||||
|
createVine(x, y) {
|
||||||
|
const graphics = this.scene.add.graphics();
|
||||||
|
|
||||||
|
graphics.lineStyle(2, 0x2d4a2d);
|
||||||
|
graphics.beginPath();
|
||||||
|
graphics.moveTo(x, y - 10);
|
||||||
|
graphics.bezierCurveTo(
|
||||||
|
x + 5, y - 5,
|
||||||
|
x - 5, y + 5,
|
||||||
|
x, y + 10
|
||||||
|
);
|
||||||
|
graphics.strokePath();
|
||||||
|
|
||||||
|
return graphics;
|
||||||
|
}
|
||||||
|
|
||||||
getTileTexture(tileType) {
|
getTileTexture(tileType) {
|
||||||
const types = Map2DData.tileTypes;
|
const types = Map2DData.tileTypes;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user