feat: Add mouse-based world navigation with drag and touch support
This commit is contained in:
108
script.js
108
script.js
@@ -17,6 +17,8 @@ const WALL = 3;
|
||||
let canvas, ctx;
|
||||
let currentTool = SAND;
|
||||
let isDrawing = false;
|
||||
let isDragging = false;
|
||||
let lastMouseX, lastMouseY;
|
||||
let lastFrameTime = 0;
|
||||
let fps = 0;
|
||||
let worldOffsetX = 0;
|
||||
@@ -44,15 +46,15 @@ window.onload = function() {
|
||||
document.getElementById('move-down').addEventListener('click', () => moveWorld(0, CHUNK_SIZE/2));
|
||||
|
||||
// Drawing events
|
||||
canvas.addEventListener('mousedown', startDrawing);
|
||||
canvas.addEventListener('mousemove', draw);
|
||||
canvas.addEventListener('mouseup', stopDrawing);
|
||||
canvas.addEventListener('mouseleave', stopDrawing);
|
||||
canvas.addEventListener('mousedown', handleMouseDown);
|
||||
canvas.addEventListener('mousemove', handleMouseMove);
|
||||
canvas.addEventListener('mouseup', handleMouseUp);
|
||||
canvas.addEventListener('mouseleave', handleMouseUp);
|
||||
|
||||
// Touch events for mobile
|
||||
canvas.addEventListener('touchstart', handleTouchStart);
|
||||
canvas.addEventListener('touchmove', handleTouchMove);
|
||||
canvas.addEventListener('touchend', stopDrawing);
|
||||
canvas.addEventListener('touchend', handleMouseUp);
|
||||
|
||||
// Initialize the first chunk
|
||||
getOrCreateChunk(0, 0);
|
||||
@@ -79,28 +81,51 @@ function setTool(tool) {
|
||||
}
|
||||
}
|
||||
|
||||
function startDrawing(e) {
|
||||
isDrawing = true;
|
||||
draw(e);
|
||||
}
|
||||
|
||||
function stopDrawing() {
|
||||
isDrawing = false;
|
||||
}
|
||||
|
||||
function draw(e) {
|
||||
if (!isDrawing) return;
|
||||
|
||||
function handleMouseDown(e) {
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
let x, y;
|
||||
const x = e.clientX - rect.left;
|
||||
const y = e.clientY - rect.top;
|
||||
|
||||
if (e.type.startsWith('touch')) {
|
||||
x = e.touches[0].clientX - rect.left;
|
||||
y = e.touches[0].clientY - rect.top;
|
||||
// Right mouse button for dragging the world
|
||||
if (e.button === 2 || e.ctrlKey || e.shiftKey) {
|
||||
isDragging = true;
|
||||
lastMouseX = x;
|
||||
lastMouseY = y;
|
||||
} else {
|
||||
x = e.clientX - rect.left;
|
||||
y = e.clientY - rect.top;
|
||||
// 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;
|
||||
|
||||
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;
|
||||
isDragging = false;
|
||||
}
|
||||
|
||||
function draw(x, y) {
|
||||
if (!isDrawing) return;
|
||||
|
||||
// Convert to world coordinates
|
||||
const worldX = Math.floor(x / PIXEL_SIZE) + worldOffsetX;
|
||||
@@ -116,12 +141,45 @@ function draw(e) {
|
||||
|
||||
function handleTouchStart(e) {
|
||||
e.preventDefault();
|
||||
startDrawing(e);
|
||||
|
||||
// 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;
|
||||
} 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;
|
||||
draw(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
function handleTouchMove(e) {
|
||||
e.preventDefault();
|
||||
draw(e);
|
||||
|
||||
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;
|
||||
draw(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
function moveWorld(dx, dy) {
|
||||
|
||||
Reference in New Issue
Block a user