This commit introduces a new rabbit element with the following features: - Jumping mechanics with variable height - Random direction changes - Falling and basic ground interaction - Color variations - Avoidance of water The changes include: - Added RABBIT constant to element types - Created rabbit.js with updateRabbit function - Added RABBIT_COLORS to constants - Implemented basic rabbit movement and behavior logic
111 lines
4.1 KiB
JavaScript
111 lines
4.1 KiB
JavaScript
// 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;
|
|
}
|