Enhance Object Interaction System: Refactor input handling to centralize object interaction logic in the main scene, allowing for more efficient detection of interactable objects. Introduce a new helper function to find objects at clicked positions and prevent player movement during interactions. Update room object click handlers to utilize the new system, improving gameplay dynamics and maintainability.

This commit is contained in:
Z. Cliffe Schreuders
2025-10-13 12:04:23 +01:00
parent aa53ce53ea
commit fd33160114
4 changed files with 105 additions and 70 deletions

View File

@@ -516,15 +516,48 @@ export function create() {
// Set up input handling
this.input.on('pointerdown', (pointer) => {
// Convert screen coordinates to world coordinates
const worldX = this.cameras.main.scrollX + pointer.x;
const worldY = this.cameras.main.scrollY + pointer.y;
// Check for objects at the clicked position first
const objectsAtPosition = findObjectsAtPosition(worldX, worldY);
if (objectsAtPosition.length > 0) {
// Check if any of the objects are interactable and player is in range
const player = window.player;
if (player) {
const INTERACTION_RANGE_SQ = 64 * 64; // 64 pixels squared
for (const obj of objectsAtPosition) {
if (obj.interactable) {
const dx = player.x - obj.x;
const dy = player.y - obj.y;
const distanceSq = dx * dx + dy * dy;
if (distanceSq <= INTERACTION_RANGE_SQ) {
// Player is in range - prevent movement and trigger interaction
window.preventPlayerMovement = true;
if (window.handleObjectInteraction) {
window.handleObjectInteraction(obj);
}
// Reset flag after a short delay
setTimeout(() => {
window.preventPlayerMovement = false;
}, 100);
return; // Exit early after handling the first valid interaction
}
}
}
}
}
// Check if player movement should be prevented (e.g., clicking on interactable items)
if (window.preventPlayerMovement) {
return;
}
// Convert screen coordinates to world coordinates
const worldX = this.cameras.main.scrollX + pointer.x;
const worldY = this.cameras.main.scrollY + pointer.y;
// No interactable objects found or player out of range - allow movement
movePlayerToPoint(worldX, worldY);
});
@@ -584,6 +617,36 @@ export function update() {
// Helper functions
// Find all objects at a given world position
function findObjectsAtPosition(worldX, worldY) {
const objectsAtPosition = [];
// Check all rooms for objects at the given position
Object.entries(window.rooms).forEach(([roomId, room]) => {
if (room.objects) {
Object.values(room.objects).forEach(obj => {
if (obj && obj.active && obj.visible) {
// Check if the click is within the object's bounds
const objLeft = obj.x - obj.width * obj.originX;
const objRight = obj.x + obj.width * (1 - obj.originX);
const objTop = obj.y - obj.height * obj.originY;
const objBottom = obj.y + obj.height * (1 - obj.originY);
if (worldX >= objLeft && worldX <= objRight &&
worldY >= objTop && worldY <= objBottom) {
objectsAtPosition.push(obj);
}
}
});
}
});
// Sort by depth (highest depth first, so topmost objects are checked first)
objectsAtPosition.sort((a, b) => (b.depth || 0) - (a.depth || 0));
return objectsAtPosition;
}
// Hide a room
function hideRoom(roomId) {
if (window.rooms[roomId]) {

View File

@@ -805,37 +805,8 @@ export function createRoom(roomId, roomData, position) {
// Store the object
rooms[roomId].objects[sprite.objectId] = sprite;
// Add click handler
sprite.on('pointerdown', (pointer, localX, localY, event) => {
// Check if player is in range for interaction
const player = window.player;
if (player) {
const dx = player.x - sprite.x;
const dy = player.y - sprite.y;
const distanceSq = dx * dx + dy * dy;
const INTERACTION_RANGE_SQ = 64 * 64; // 64 pixels squared
if (distanceSq <= INTERACTION_RANGE_SQ) {
// Player is in range - prevent movement and trigger interaction
if (event && event.preventDefault) {
event.preventDefault();
}
// Set flag to prevent player movement
window.preventPlayerMovement = true;
if (window.handleObjectInteraction) {
window.handleObjectInteraction(sprite);
}
// Reset flag after a short delay
setTimeout(() => {
window.preventPlayerMovement = false;
}, 100);
} else {
// Player is out of range - allow movement to the item
console.log('Scenario item out of range, allowing player movement');
// Don't prevent movement - let the player move to the item
}
}
});
// Note: Click handling is now done by the main scene's pointerdown handler
// which checks for all objects at the clicked position
});
// Re-sort table groups after adding scenario items to maintain north-to-south order
@@ -1217,39 +1188,8 @@ export function createRoom(roomId, roomData, position) {
console.log(`Applied default properties to ${type} ${imageName} -> ${cleanName}`);
}
// Add click handler
sprite.on('pointerdown', (pointer, localX, localY, event) => {
console.log('Tiled object clicked:', { name: imageName, id: sprite.objectId, interactable: sprite.interactable });
// Only trigger interaction for interactable items
if (sprite.interactable && window.handleObjectInteraction) {
// Check if player is in range for interaction
const player = window.player;
if (player) {
const dx = player.x - sprite.x;
const dy = player.y - sprite.y;
const distanceSq = dx * dx + dy * dy;
const INTERACTION_RANGE_SQ = 64 * 64; // 64 pixels squared
if (distanceSq <= INTERACTION_RANGE_SQ) {
// Player is in range - prevent movement and trigger interaction
if (event && event.preventDefault) {
event.preventDefault();
}
// Set flag to prevent player movement
window.preventPlayerMovement = true;
window.handleObjectInteraction(sprite);
// Reset flag after a short delay
setTimeout(() => {
window.preventPlayerMovement = false;
}, 100);
} else {
// Player is out of range - allow movement to the item
console.log('Regular item out of range, allowing player movement');
// Don't prevent movement - let the player move to the item
}
}
}
});
// Note: Click handling is now done by the main scene's pointerdown handler
// which checks for all objects at the clicked position
console.log(`Created Tiled object: ${sprite.objectId} at (${sprite.x}, ${sprite.y})`);

View File

@@ -93,5 +93,36 @@ export const MinigameFramework = {
registerScene(sceneType, SceneClass) {
this.registeredScenes[sceneType] = SceneClass;
console.log(`Registered minigame scene: ${sceneType}`);
},
// Force restart the current minigame
restartCurrentMinigame() {
if (this.currentMinigame) {
console.log('Force restarting current minigame');
const currentParams = this.currentMinigame.params;
const currentSceneType = this.currentMinigame.constructor.name.toLowerCase().replace('minigame', '');
// End the current minigame
this.endMinigame(false, null);
// Restart with the same parameters
if (currentParams) {
setTimeout(() => {
this.startMinigame(currentSceneType, null, currentParams);
}, 100); // Small delay to ensure cleanup is complete
}
} else {
console.log('No current minigame to restart');
}
},
// Force close any running minigame
forceCloseMinigame() {
if (this.currentMinigame) {
console.log('Force closing current minigame');
this.endMinigame(false, null);
} else {
console.log('No current minigame to close');
}
}
};

View File

@@ -112,8 +112,9 @@ export function handleObjectInteraction(sprite) {
// Handle the Notepad - open notes minigame
if (sprite.scenarioData.type === "notepad") {
if (window.startNotesMinigame) {
// Check if notes minigame is already running
if (window.MinigameFramework && window.MinigameFramework.currentMinigame) {
// Check if notes minigame is specifically already running
if (window.MinigameFramework && window.MinigameFramework.currentMinigame &&
window.MinigameFramework.currentMinigame.navigateToNoteIndex) {
console.log('Notes minigame already running, navigating to notepad note instead');
// If notes minigame is already running, just navigate to the notepad note
if (window.MinigameFramework.currentMinigame.navigateToNoteIndex) {