feat: Add mouse-based world navigation with drag and touch support
This commit is contained in:
parent
dbcf3a0e61
commit
eb9900478d
@ -6,7 +6,7 @@
|
||||
<title>Pixel Sand Simulation</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<body oncontextmenu="return false;">
|
||||
<div class="container">
|
||||
<div class="controls">
|
||||
<div class="tools">
|
||||
@ -23,6 +23,7 @@
|
||||
<div class="info">
|
||||
<span id="coords">Chunk: 0,0</span>
|
||||
<span id="fps">FPS: 0</span>
|
||||
<span class="help-text">Hold Shift/Ctrl or right-click to drag the world</span>
|
||||
</div>
|
||||
</div>
|
||||
<canvas id="simulation-canvas"></canvas>
|
||||
|
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) {
|
||||
|
@ -54,6 +54,10 @@ body {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.help-text {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
#simulation-canvas {
|
||||
flex-grow: 1;
|
||||
background-color: #000;
|
||||
|
Loading…
x
Reference in New Issue
Block a user