diff --git a/js/constants.js b/js/constants.js index c72ad61..821fc38 100644 --- a/js/constants.js +++ b/js/constants.js @@ -17,6 +17,7 @@ const FLOWER_COLORS = ['#FF0000', '#FFFF00', '#FF00FF', '#FFA500', '#FFFFFF', '# const LEAF_COLOR = '#228B22'; const FIRE_COLORS = ['#FF0000', '#FF3300', '#FF6600', '#FF9900', '#FFCC00', '#FFFF00']; const LAVA_COLORS = ['#FF0000', '#FF3300', '#FF4500', '#FF6600', '#FF8C00']; +const RABBIT_COLORS = ['#FFFFFF', '#E0E0E0', '#D3C8B4']; // White, Light Gray, Light Brown // Color variation functions function getRandomColorVariation(baseColor, range) { @@ -58,6 +59,7 @@ const TREE_SEED = 11; const LEAF = 12; const FIRE = 13; const LAVA = 14; +const RABBIT = 15; // Flammable materials const FLAMMABLE_MATERIALS = [GRASS, WOOD, SEED, GRASS_BLADE, FLOWER, TREE_SEED, LEAF]; diff --git a/js/elements/rabbit.js b/js/elements/rabbit.js new file mode 100644 index 0000000..2b590d3 --- /dev/null +++ b/js/elements/rabbit.js @@ -0,0 +1,110 @@ +// Rabbit element behaviors +function updateRabbit(x, y) { + const metadata = getMetadata(x, y) || {}; + + // Initialize rabbit metadata if it doesn't exist + if (!metadata.initialized) { + metadata.initialized = true; + metadata.jumpCooldown = 0; + metadata.direction = Math.random() > 0.5 ? 1 : -1; // 1 for right, -1 for left + metadata.jumpHeight = 0; + metadata.colorIndex = Math.floor(Math.random() * RABBIT_COLORS.length); + setMetadata(x, y, metadata); + return true; + } + + // Update metadata + metadata.jumpCooldown = Math.max(0, metadata.jumpCooldown - 1); + + // Check if rabbit is on solid ground + const onGround = getPixel(x, y + 1) !== EMPTY && getPixel(x, y + 1) !== WATER; + + // Rabbit falls if there's nothing below + if (!onGround && metadata.jumpHeight <= 0) { + if (getPixel(x, y + 1) === EMPTY) { + setPixel(x, y, EMPTY); + setPixel(x, y + 1, RABBIT); + moveMetadata(x, y, x, y + 1); + return true; + } + // Rabbit can swim but prefers not to + else if (getPixel(x, y + 1) === WATER) { + // 50% chance to swim down or stay in place + if (Math.random() < 0.5) { + setPixel(x, y, EMPTY); + setPixel(x, y + 1, RABBIT); + moveMetadata(x, y, x, y + 1); + return true; + } + // When in water, try to jump out + metadata.jumpCooldown = 0; + } + } + + // Rabbit jumps occasionally when on ground + if (onGround && metadata.jumpCooldown === 0) { + // Start a jump + metadata.jumpHeight = 3 + Math.floor(Math.random() * 2); // Jump 3-4 blocks high + metadata.jumpCooldown = 30 + Math.floor(Math.random() * 50); // Wait 30-80 frames before next jump + + // Randomly change direction sometimes + if (Math.random() < 0.3) { + metadata.direction = -metadata.direction; + } + + setMetadata(x, y, metadata); + } + + // Execute jump if jump height is positive + if (metadata.jumpHeight > 0) { + // Move up + if (getPixel(x, y - 1) === EMPTY) { + setPixel(x, y, EMPTY); + setPixel(x, y - 1, RABBIT); + moveMetadata(x, y, x, y - 1); + metadata.jumpHeight--; + setMetadata(x, y - 1, metadata); + return true; + } + // If can't move up, try moving diagonally up in current direction + else if (getPixel(x + metadata.direction, y - 1) === EMPTY) { + setPixel(x, y, EMPTY); + setPixel(x + metadata.direction, y - 1, RABBIT); + moveMetadata(x, y, x + metadata.direction, y - 1); + metadata.jumpHeight--; + setMetadata(x + metadata.direction, y - 1, metadata); + return true; + } + // If can't move diagonally up, try moving horizontally + else if (getPixel(x + metadata.direction, y) === EMPTY) { + setPixel(x, y, EMPTY); + setPixel(x + metadata.direction, y, RABBIT); + moveMetadata(x, y, x + metadata.direction, y); + metadata.jumpHeight = 0; // End jump if blocked + setMetadata(x + metadata.direction, y, metadata); + return true; + } + // If completely blocked, end jump + else { + metadata.jumpHeight = 0; + setMetadata(x, y, metadata); + } + } + // Move horizontally when not jumping + else if (metadata.jumpCooldown > 0 && metadata.jumpCooldown < 15 && onGround) { + // Hop horizontally between jumps + if (getPixel(x + metadata.direction, y) === EMPTY) { + setPixel(x, y, EMPTY); + setPixel(x + metadata.direction, y, RABBIT); + moveMetadata(x, y, x + metadata.direction, y); + return true; + } + // If blocked, try to change direction + else { + metadata.direction = -metadata.direction; + setMetadata(x, y, metadata); + } + } + + return false; +}