feat: Add color variations for natural elements and dynamic water colors
This commit is contained in:
parent
a86acfff3a
commit
8ef18f52ab
@ -4,7 +4,7 @@ const PIXEL_SIZE = 4;
|
||||
const GRAVITY = 0.5;
|
||||
const WATER_SPREAD = 3;
|
||||
|
||||
// Colors
|
||||
// Base Colors
|
||||
const SAND_COLOR = '#e6c588';
|
||||
const WATER_COLOR = '#4a80f5';
|
||||
const WALL_COLOR = '#888888';
|
||||
@ -18,6 +18,30 @@ const LEAF_COLOR = '#228B22';
|
||||
const FIRE_COLORS = ['#FF0000', '#FF3300', '#FF6600', '#FF9900', '#FFCC00', '#FFFF00'];
|
||||
const LAVA_COLORS = ['#FF0000', '#FF3300', '#FF4500', '#FF6600', '#FF8C00'];
|
||||
|
||||
// Color variation functions
|
||||
function getRandomColorVariation(baseColor, range) {
|
||||
// Convert hex to RGB
|
||||
const r = parseInt(baseColor.slice(1, 3), 16);
|
||||
const g = parseInt(baseColor.slice(3, 5), 16);
|
||||
const b = parseInt(baseColor.slice(5, 7), 16);
|
||||
|
||||
// Add random variation
|
||||
const rVar = Math.max(0, Math.min(255, r + Math.floor(Math.random() * range * 2) - range));
|
||||
const gVar = Math.max(0, Math.min(255, g + Math.floor(Math.random() * range * 2) - range));
|
||||
const bVar = Math.max(0, Math.min(255, b + Math.floor(Math.random() * range * 2) - range));
|
||||
|
||||
// Convert back to hex
|
||||
return `#${rVar.toString(16).padStart(2, '0')}${gVar.toString(16).padStart(2, '0')}${bVar.toString(16).padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
// Generate color palettes for natural elements
|
||||
const DIRT_COLORS = Array(10).fill().map(() => getRandomColorVariation(DIRT_COLOR, 15));
|
||||
const GRASS_COLORS = Array(10).fill().map(() => getRandomColorVariation(GRASS_COLOR, 20));
|
||||
const STONE_COLORS = Array(10).fill().map(() => getRandomColorVariation(STONE_COLOR, 15));
|
||||
const WOOD_COLORS = Array(10).fill().map(() => getRandomColorVariation(WOOD_COLOR, 15));
|
||||
const LEAF_COLORS = Array(10).fill().map(() => getRandomColorVariation(LEAF_COLOR, 25));
|
||||
const WATER_COLORS = Array(10).fill().map(() => getRandomColorVariation(WATER_COLOR, 20));
|
||||
|
||||
// Element types
|
||||
const EMPTY = 0;
|
||||
const SAND = 1;
|
||||
|
@ -22,19 +22,40 @@ function updateSand(x, y) {
|
||||
}
|
||||
|
||||
function updateWater(x, y) {
|
||||
// Update water color dynamically
|
||||
const metadata = getMetadata(x, y);
|
||||
if (metadata) {
|
||||
if (metadata.waterColorTimer === undefined) {
|
||||
metadata.waterColorTimer = 0;
|
||||
}
|
||||
|
||||
metadata.waterColorTimer++;
|
||||
|
||||
// Change color occasionally
|
||||
if (metadata.waterColorTimer > 20 && Math.random() < 0.1) {
|
||||
metadata.colorIndex = Math.floor(Math.random() * 10);
|
||||
metadata.waterColorTimer = 0;
|
||||
}
|
||||
|
||||
setMetadata(x, y, metadata);
|
||||
}
|
||||
|
||||
// Try to move down
|
||||
if (getPixel(x, y + 1) === EMPTY) {
|
||||
setPixel(x, y, EMPTY);
|
||||
setPixel(x, y + 1, WATER);
|
||||
moveMetadata(x, y, x, y + 1);
|
||||
}
|
||||
// Try to move down-left or down-right
|
||||
else if (getPixel(x - 1, y + 1) === EMPTY) {
|
||||
setPixel(x, y, EMPTY);
|
||||
setPixel(x - 1, y + 1, WATER);
|
||||
moveMetadata(x, y, x - 1, y + 1);
|
||||
}
|
||||
else if (getPixel(x + 1, y + 1) === EMPTY) {
|
||||
setPixel(x, y, EMPTY);
|
||||
setPixel(x + 1, y + 1, WATER);
|
||||
moveMetadata(x, y, x + 1, y + 1);
|
||||
}
|
||||
// Try to spread horizontally
|
||||
else {
|
||||
|
@ -34,10 +34,16 @@ function growTree(x, y) {
|
||||
// Determine tree height (50-80 blocks, 10x bigger)
|
||||
const treeHeight = 50 + Math.floor(Math.random() * 31);
|
||||
|
||||
// Generate consistent wood color for this tree
|
||||
const woodColorIndex = Math.floor(Math.random() * 10);
|
||||
setMetadata(x, y, { colorIndex: woodColorIndex });
|
||||
|
||||
// Grow the trunk upward
|
||||
for (let i = 1; i < treeHeight; i++) {
|
||||
if (getPixel(x, y - i) === EMPTY) {
|
||||
setPixel(x, y - i, WOOD);
|
||||
// Use the same wood color for the entire trunk
|
||||
setMetadata(x, y - i, { colorIndex: woodColorIndex });
|
||||
} else {
|
||||
break; // Stop if we hit something
|
||||
}
|
||||
@ -85,6 +91,14 @@ function addBranches(x, y, treeHeight) {
|
||||
}
|
||||
|
||||
function addLeaves(x, y, radius) {
|
||||
// Generate a few leaf color variations for this tree
|
||||
const baseLeafColorIndex = Math.floor(Math.random() * 10);
|
||||
const leafColorIndices = [
|
||||
baseLeafColorIndex,
|
||||
(baseLeafColorIndex + 1) % 10,
|
||||
(baseLeafColorIndex + 2) % 10
|
||||
];
|
||||
|
||||
// Add a cluster of leaves around the point
|
||||
for (let dy = -radius; dy <= radius; dy++) {
|
||||
for (let dx = -radius; dx <= radius; dx++) {
|
||||
@ -100,6 +114,9 @@ function addLeaves(x, y, radius) {
|
||||
if (Math.random() < (1 - distance/radius/density)) {
|
||||
if (getPixel(x + dx, y + dy) === EMPTY) {
|
||||
setPixel(x + dx, y + dy, LEAF);
|
||||
// Assign one of the tree's leaf colors
|
||||
const colorIndex = leafColorIndices[Math.floor(Math.random() * leafColorIndices.length)];
|
||||
setMetadata(x + dx, y + dy, { colorIndex });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
35
js/render.js
35
js/render.js
@ -47,21 +47,39 @@ function render() {
|
||||
if (type === SAND) {
|
||||
ctx.fillStyle = SAND_COLOR;
|
||||
} else if (type === WATER) {
|
||||
ctx.fillStyle = WATER_COLOR;
|
||||
// Get water color from metadata with variation
|
||||
const metadata = getMetadata(chunkX * CHUNK_SIZE + x, chunkY * CHUNK_SIZE + y);
|
||||
const colorIndex = metadata && metadata.colorIndex !== undefined ? metadata.colorIndex : 0;
|
||||
ctx.fillStyle = WATER_COLORS[colorIndex];
|
||||
} else if (type === WALL) {
|
||||
ctx.fillStyle = WALL_COLOR;
|
||||
} else if (type === DIRT) {
|
||||
ctx.fillStyle = DIRT_COLOR;
|
||||
// Get dirt color from metadata with variation
|
||||
const metadata = getMetadata(chunkX * CHUNK_SIZE + x, chunkY * CHUNK_SIZE + y);
|
||||
const colorIndex = metadata && metadata.colorIndex !== undefined ? metadata.colorIndex : 0;
|
||||
ctx.fillStyle = DIRT_COLORS[colorIndex];
|
||||
} else if (type === STONE) {
|
||||
ctx.fillStyle = STONE_COLOR;
|
||||
// Get stone color from metadata with variation
|
||||
const metadata = getMetadata(chunkX * CHUNK_SIZE + x, chunkY * CHUNK_SIZE + y);
|
||||
const colorIndex = metadata && metadata.colorIndex !== undefined ? metadata.colorIndex : 0;
|
||||
ctx.fillStyle = STONE_COLORS[colorIndex];
|
||||
} else if (type === GRASS) {
|
||||
ctx.fillStyle = GRASS_COLOR;
|
||||
// Get grass color from metadata with variation
|
||||
const metadata = getMetadata(chunkX * CHUNK_SIZE + x, chunkY * CHUNK_SIZE + y);
|
||||
const colorIndex = metadata && metadata.colorIndex !== undefined ? metadata.colorIndex : 0;
|
||||
ctx.fillStyle = GRASS_COLORS[colorIndex];
|
||||
} else if (type === WOOD) {
|
||||
ctx.fillStyle = WOOD_COLOR;
|
||||
// Get wood color from metadata with variation
|
||||
const metadata = getMetadata(chunkX * CHUNK_SIZE + x, chunkY * CHUNK_SIZE + y);
|
||||
const colorIndex = metadata && metadata.colorIndex !== undefined ? metadata.colorIndex : 0;
|
||||
ctx.fillStyle = WOOD_COLORS[colorIndex];
|
||||
} else if (type === SEED) {
|
||||
ctx.fillStyle = SEED_COLOR;
|
||||
} else if (type === GRASS_BLADE) {
|
||||
ctx.fillStyle = GRASS_COLOR;
|
||||
// Use the same color variation as grass
|
||||
const metadata = getMetadata(chunkX * CHUNK_SIZE + x, chunkY * CHUNK_SIZE + y);
|
||||
const colorIndex = metadata && metadata.colorIndex !== undefined ? metadata.colorIndex : 0;
|
||||
ctx.fillStyle = GRASS_COLORS[colorIndex];
|
||||
} else if (type === FLOWER) {
|
||||
// Get flower color from metadata or use a default
|
||||
const metadata = getMetadata(chunkX * CHUNK_SIZE + x, chunkY * CHUNK_SIZE + y);
|
||||
@ -69,7 +87,10 @@ function render() {
|
||||
} else if (type === TREE_SEED) {
|
||||
ctx.fillStyle = SEED_COLOR;
|
||||
} else if (type === LEAF) {
|
||||
ctx.fillStyle = LEAF_COLOR;
|
||||
// Get leaf color from metadata with variation
|
||||
const metadata = getMetadata(chunkX * CHUNK_SIZE + x, chunkY * CHUNK_SIZE + y);
|
||||
const colorIndex = metadata && metadata.colorIndex !== undefined ? metadata.colorIndex : 0;
|
||||
ctx.fillStyle = LEAF_COLORS[colorIndex];
|
||||
} else if (type === FIRE) {
|
||||
// Get fire color from metadata
|
||||
const metadata = getMetadata(chunkX * CHUNK_SIZE + x, chunkY * CHUNK_SIZE + y);
|
||||
|
@ -83,14 +83,26 @@ function generateHills(chunkX, chunkY, chunkData, random) {
|
||||
// Top layer is grass
|
||||
if (depth === 0) {
|
||||
chunkData[index] = GRASS;
|
||||
// Set metadata with color index for grass
|
||||
const worldX = chunkX * CHUNK_SIZE + x;
|
||||
const worldY = chunkY * CHUNK_SIZE + y;
|
||||
setMetadata(worldX, worldY, { colorIndex: Math.floor(Math.random() * 10) });
|
||||
}
|
||||
// Next few layers are dirt
|
||||
else if (depth < 5) {
|
||||
chunkData[index] = DIRT;
|
||||
// Set metadata with color index for dirt
|
||||
const worldX = chunkX * CHUNK_SIZE + x;
|
||||
const worldY = chunkY * CHUNK_SIZE + y;
|
||||
setMetadata(worldX, worldY, { colorIndex: Math.floor(Math.random() * 10) });
|
||||
}
|
||||
// Deeper layers are stone
|
||||
else {
|
||||
chunkData[index] = STONE;
|
||||
// Set metadata with color index for stone
|
||||
const worldX = chunkX * CHUNK_SIZE + x;
|
||||
const worldY = chunkY * CHUNK_SIZE + y;
|
||||
setMetadata(worldX, worldY, { colorIndex: Math.floor(Math.random() * 10) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
js/world.js
10
js/world.js
@ -62,6 +62,16 @@ function setPixel(worldX, worldY, type) {
|
||||
const index = localY * CHUNK_SIZE + localX;
|
||||
|
||||
chunk[index] = type;
|
||||
|
||||
// Assign random color index for natural elements
|
||||
if (type === DIRT || type === GRASS || type === STONE || type === WOOD || type === LEAF) {
|
||||
const colorIndex = Math.floor(Math.random() * 10);
|
||||
setMetadata(worldX, worldY, { ...getMetadata(worldX, worldY) || {}, colorIndex });
|
||||
}
|
||||
else if (type === WATER) {
|
||||
const colorIndex = Math.floor(Math.random() * 10);
|
||||
setMetadata(worldX, worldY, { ...getMetadata(worldX, worldY) || {}, colorIndex, waterColorTimer: 0 });
|
||||
}
|
||||
}
|
||||
|
||||
function getPixel(worldX, worldY) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user