122 lines
4.3 KiB
JavaScript
Raw Normal View History

2025-10-04 20:40:44 +02:00
export class InputHandler {
constructor(app) {
this.app = app;
this.canvas = null;
this.isRightMouseDown = false;
this.lastMouseX = 0;
this.lastMouseY = 0;
this.currentTileX = null;
this.currentTileY = null;
this.cursorUpdateThrottle = 100; // ms
this.lastCursorUpdate = 0;
}
init() {
this.canvas = document.getElementById('gameCanvas');
// Mouse events
this.canvas.addEventListener('mousedown', (e) => this.onMouseDown(e));
this.canvas.addEventListener('mouseup', (e) => this.onMouseUp(e));
this.canvas.addEventListener('mousemove', (e) => this.onMouseMove(e));
this.canvas.addEventListener('wheel', (e) => this.onWheel(e));
this.canvas.addEventListener('contextmenu', (e) => e.preventDefault());
// Keyboard events
document.addEventListener('keydown', (e) => this.onKeyDown(e));
}
onMouseDown(event) {
if (event.button === 2) { // Right mouse button
this.isRightMouseDown = true;
this.lastMouseX = event.clientX;
this.lastMouseY = event.clientY;
this.canvas.style.cursor = 'grabbing';
} else if (event.button === 0) { // Left mouse button
const tile = this.app.renderer.screenToWorld(event.clientX, event.clientY);
if (this.app.isPlacingBuilding && this.app.selectedBuildingType) {
// Place building
this.app.placeBuilding(tile.x, tile.y);
this.app.isPlacingBuilding = false;
this.app.selectedBuildingType = null;
}
}
}
onMouseUp(event) {
if (event.button === 2) { // Right mouse button
this.isRightMouseDown = false;
this.canvas.style.cursor = 'default';
// Check if click (not drag)
const dragThreshold = 5;
const dx = Math.abs(event.clientX - this.lastMouseX);
const dy = Math.abs(event.clientY - this.lastMouseY);
if (dx < dragThreshold && dy < dragThreshold) {
// Right click on tile - show context menu
const tile = this.app.renderer.screenToWorld(event.clientX, event.clientY);
const building = this.app.gameState.buildings[`${tile.x},${tile.y}`];
if (building && building.owner_id === this.app.player.player_id) {
this.app.uiManager.showContextMenu(
event.clientX,
event.clientY,
tile.x,
tile.y
);
}
}
}
}
onMouseMove(event) {
// Update tile position
const tile = this.app.renderer.screenToWorld(event.clientX, event.clientY);
if (tile.x !== this.currentTileX || tile.y !== this.currentTileY) {
this.currentTileX = tile.x;
this.currentTileY = tile.y;
// Highlight tile
this.app.renderer.highlightTile(tile.x, tile.y);
// Send cursor position to server (throttled)
const now = Date.now();
if (now - this.lastCursorUpdate > this.cursorUpdateThrottle) {
this.app.sendCursorPosition(tile.x, tile.y);
this.lastCursorUpdate = now;
}
}
// Handle camera panning
if (this.isRightMouseDown) {
const dx = (event.clientX - this.lastMouseX) * 0.1;
const dy = (event.clientY - this.lastMouseY) * 0.1;
this.app.renderer.moveCamera(-dx, dy);
this.lastMouseX = event.clientX;
this.lastMouseY = event.clientY;
}
}
onWheel(event) {
event.preventDefault();
const delta = event.deltaY > 0 ? -0.1 : 0.1;
this.app.renderer.zoomCamera(delta);
}
onKeyDown(event) {
// ESC to cancel building placement
if (event.key === 'Escape') {
this.app.isPlacingBuilding = false;
this.app.selectedBuildingType = null;
this.app.uiManager.hideContextMenu();
}
}
}