223 lines
8.2 KiB
JavaScript
223 lines
8.2 KiB
JavaScript
// Input handling functions
|
|
let isDrawing = false;
|
|
let isDragging = false;
|
|
let lastMouseX, lastMouseY;
|
|
let currentMouseX, currentMouseY;
|
|
let currentTool = SAND;
|
|
// RABBIT is already defined in constants.js as 15
|
|
|
|
function setTool(tool) {
|
|
currentTool = tool;
|
|
document.querySelectorAll('.tools button').forEach(btn => btn.classList.remove('active'));
|
|
|
|
if (tool === SAND) {
|
|
document.getElementById('sand-btn').classList.add('active');
|
|
} else if (tool === WATER) {
|
|
document.getElementById('water-btn').classList.add('active');
|
|
} else if (tool === DIRT) {
|
|
document.getElementById('dirt-btn').classList.add('active');
|
|
} else if (tool === STONE) {
|
|
document.getElementById('stone-btn').classList.add('active');
|
|
} else if (tool === GRASS) {
|
|
document.getElementById('grass-btn').classList.add('active');
|
|
} else if (tool === WOOD) {
|
|
document.getElementById('wood-btn').classList.add('active');
|
|
} else if (tool === SEED) {
|
|
document.getElementById('seed-btn').classList.add('active');
|
|
} else if (tool === TREE_SEED) {
|
|
document.getElementById('tree-seed-btn').classList.add('active');
|
|
} else if (tool === FIRE) {
|
|
document.getElementById('fire-btn').classList.add('active');
|
|
} else if (tool === LAVA) {
|
|
document.getElementById('lava-btn').classList.add('active');
|
|
} else if (tool === RABBIT) {
|
|
document.getElementById('rabbit-btn').classList.add('active');
|
|
} else if (tool === EMPTY) {
|
|
document.getElementById('eraser-btn').classList.add('active');
|
|
}
|
|
}
|
|
|
|
function handleMouseDown(e) {
|
|
const rect = canvas.getBoundingClientRect();
|
|
const x = e.clientX - rect.left;
|
|
const y = e.clientY - rect.top;
|
|
|
|
// Right mouse button for dragging the world
|
|
if (e.button === 2 || e.ctrlKey || e.shiftKey) {
|
|
isDragging = true;
|
|
lastMouseX = x;
|
|
lastMouseY = y;
|
|
worldOffsetXBeforeDrag = worldOffsetX;
|
|
worldOffsetYBeforeDrag = worldOffsetY;
|
|
} else {
|
|
// Left mouse button for drawing
|
|
isDrawing = true;
|
|
draw(x, y);
|
|
}
|
|
}
|
|
|
|
function handleMouseMove(e) {
|
|
const rect = canvas.getBoundingClientRect();
|
|
const x = e.clientX - rect.left;
|
|
const y = e.clientY - rect.top;
|
|
|
|
// Always update current mouse position
|
|
currentMouseX = x;
|
|
currentMouseY = y;
|
|
|
|
if (isDragging) {
|
|
// Calculate how much the mouse has moved
|
|
const dx = x - lastMouseX;
|
|
const dy = y - lastMouseY;
|
|
|
|
// Move the world in the opposite direction (divide by pixel size to convert to world coordinates)
|
|
moveWorld(-dx / PIXEL_SIZE, -dy / PIXEL_SIZE);
|
|
|
|
// Update the last mouse position
|
|
lastMouseX = x;
|
|
lastMouseY = y;
|
|
} else if (isDrawing) {
|
|
draw(x, y);
|
|
}
|
|
}
|
|
|
|
function handleMouseUp(e) {
|
|
isDrawing = false;
|
|
if (isDragging) {
|
|
// Calculate the total movement during this drag
|
|
const totalDragX = worldOffsetX - worldOffsetXBeforeDrag;
|
|
const totalDragY = worldOffsetY - worldOffsetYBeforeDrag;
|
|
|
|
if (debugMode) {
|
|
console.log(`Drag completed: ${totalDragX}, ${totalDragY}`);
|
|
}
|
|
}
|
|
isDragging = false;
|
|
}
|
|
|
|
function draw(x, y) {
|
|
if (!isDrawing) return;
|
|
|
|
// Convert screen coordinates to world coordinates
|
|
const worldX = Math.floor(x / PIXEL_SIZE) + worldOffsetX;
|
|
const worldY = Math.floor(y / PIXEL_SIZE) + worldOffsetY;
|
|
|
|
// Draw a small brush (3x3)
|
|
for (let dy = -1; dy <= 1; dy++) {
|
|
for (let dx = -1; dx <= 1; dx++) {
|
|
const pixelX = worldX + dx;
|
|
const pixelY = worldY + dy;
|
|
|
|
// Special handling for fire - only set fire to flammable materials
|
|
if (currentTool === FIRE) {
|
|
const currentPixel = getPixel(pixelX, pixelY);
|
|
if (FLAMMABLE_MATERIALS.includes(currentPixel)) {
|
|
setPixel(pixelX, pixelY, FIRE);
|
|
setMetadata(pixelX, pixelY, {
|
|
lifetime: 100 + Math.floor(Math.random() * 100),
|
|
colorIndex: Math.floor(Math.random() * FIRE_COLORS.length)
|
|
});
|
|
}
|
|
}
|
|
// Special handling for rabbits - only spawn on empty spaces
|
|
else if (currentTool === RABBIT) {
|
|
if (getPixel(pixelX, pixelY) === EMPTY) {
|
|
setPixel(pixelX, pixelY, RABBIT);
|
|
// Initialize rabbit metadata
|
|
setMetadata(pixelX, pixelY, {
|
|
initialized: true,
|
|
jumpCooldown: 0,
|
|
direction: Math.random() > 0.5 ? 1 : -1, // 1 for right, -1 for left
|
|
jumpHeight: 0,
|
|
colorIndex: Math.floor(Math.random() * RABBIT_COLORS.length)
|
|
});
|
|
}
|
|
} else {
|
|
setPixel(pixelX, pixelY, currentTool);
|
|
|
|
// Add metadata for special types
|
|
if (currentTool === SEED) {
|
|
setMetadata(pixelX, pixelY, { type: 'regular' });
|
|
} else if (currentTool === FLOWER) {
|
|
setMetadata(pixelX, pixelY, {
|
|
type: 'flower',
|
|
color: FLOWER_COLORS[Math.floor(Math.random() * FLOWER_COLORS.length)],
|
|
age: 0,
|
|
height: 1
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function handleTouchStart(e) {
|
|
e.preventDefault();
|
|
|
|
// Check if we have multiple touch points (for dragging)
|
|
if (e.touches.length > 1) {
|
|
isDragging = true;
|
|
lastMouseX = e.touches[0].clientX;
|
|
lastMouseY = e.touches[0].clientY;
|
|
worldOffsetXBeforeDrag = worldOffsetX;
|
|
worldOffsetYBeforeDrag = worldOffsetY;
|
|
} else {
|
|
// Single touch for drawing
|
|
isDrawing = true;
|
|
const rect = canvas.getBoundingClientRect();
|
|
const x = e.touches[0].clientX - rect.left;
|
|
const y = e.touches[0].clientY - rect.top;
|
|
currentMouseX = x;
|
|
currentMouseY = y;
|
|
draw(x, y);
|
|
}
|
|
}
|
|
|
|
function handleTouchMove(e) {
|
|
e.preventDefault();
|
|
|
|
const rect = canvas.getBoundingClientRect();
|
|
|
|
if (isDragging && e.touches.length > 1) {
|
|
// Calculate how much the touch has moved
|
|
const x = e.touches[0].clientX;
|
|
const y = e.touches[0].clientY;
|
|
const dx = x - lastMouseX;
|
|
const dy = y - lastMouseY;
|
|
|
|
// Move the world in the opposite direction
|
|
moveWorld(-dx / PIXEL_SIZE, -dy / PIXEL_SIZE);
|
|
|
|
// Update the last touch position
|
|
lastMouseX = x;
|
|
lastMouseY = y;
|
|
} else if (isDrawing) {
|
|
const x = e.touches[0].clientX - rect.left;
|
|
const y = e.touches[0].clientY - rect.top;
|
|
currentMouseX = x;
|
|
currentMouseY = y;
|
|
draw(x, y);
|
|
}
|
|
}
|
|
|
|
|
|
// Set up event listeners
|
|
window.addEventListener('load', function() {
|
|
canvas.addEventListener('mousedown', handleMouseDown);
|
|
canvas.addEventListener('mousemove', handleMouseMove);
|
|
window.addEventListener('mouseup', handleMouseUp);
|
|
canvas.addEventListener('touchstart', handleTouchStart, { passive: false });
|
|
canvas.addEventListener('touchmove', handleTouchMove, { passive: false });
|
|
window.addEventListener('touchend', handleMouseUp);
|
|
|
|
// Navigation buttons
|
|
document.getElementById('move-left').addEventListener('click', () => moveWorld(-10, 0));
|
|
document.getElementById('move-right').addEventListener('click', () => moveWorld(10, 0));
|
|
document.getElementById('move-up').addEventListener('click', () => moveWorld(0, -10));
|
|
document.getElementById('move-down').addEventListener('click', () => moveWorld(0, 10));
|
|
document.getElementById('debug-btn').addEventListener('click', toggleDebug);
|
|
|
|
// Add rabbit button event listener
|
|
document.getElementById('rabbit-btn').addEventListener('click', () => setTool(RABBIT));
|
|
});
|