mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-20 13:50:46 +00:00
Enhance inventory system in index.html: add new inventory container with dynamic item handling, update styles for improved layout, and refactor item interaction logic for better user experience.
This commit is contained in:
324
index.html
324
index.html
@@ -54,8 +54,8 @@
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
top: 20px;
|
top: 20px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
width: 500px;
|
width: 600px;
|
||||||
max-width: 80%;
|
max-width: 90%;
|
||||||
z-index: 2000;
|
z-index: 2000;
|
||||||
font-family: 'Press Start 2P';
|
font-family: 'Press Start 2P';
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
@@ -136,6 +136,7 @@
|
|||||||
bottom: 80px;
|
bottom: 80px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
width: 500px;
|
width: 500px;
|
||||||
|
max-width: fit-content;
|
||||||
max-height: 500px;
|
max-height: 500px;
|
||||||
background-color: rgba(0, 0, 0, 0.9);
|
background-color: rgba(0, 0, 0, 0.9);
|
||||||
color: white;
|
color: white;
|
||||||
@@ -844,8 +845,8 @@
|
|||||||
/* Toggle Buttons Container */
|
/* Toggle Buttons Container */
|
||||||
#toggle-buttons-container {
|
#toggle-buttons-container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 20px;
|
bottom: 15px;
|
||||||
right: 20px;
|
right: 15px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
z-index: 1998;
|
z-index: 1998;
|
||||||
@@ -1144,6 +1145,74 @@
|
|||||||
font-size: 125%;
|
font-size: 125%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#inventory-container {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 80px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
/* overflow-x: auto; */
|
||||||
|
padding: 0 20px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#inventory-container::-webkit-scrollbar {
|
||||||
|
height: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#inventory-container::-webkit-scrollbar-track {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#inventory-container::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inventory-slot {
|
||||||
|
min-width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
margin: 0 5px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
background: rgba(0, 0, 0, 0.8);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.inventory-item {
|
||||||
|
max-width: 48px;
|
||||||
|
max-height: 48px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inventory-item:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.inventory-tooltip {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 100%;
|
||||||
|
left: -10px;
|
||||||
|
color: white;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
white-space: nowrap;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inventory-item:hover + .inventory-tooltip {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/phaser@3.60.0/dist/phaser.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/phaser@3.60.0/dist/phaser.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/easystarjs@0.4.4/bin/easystar-0.4.4.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/easystarjs@0.4.4/bin/easystar-0.4.4.js"></script>
|
||||||
@@ -1222,6 +1291,9 @@
|
|||||||
<div id="biometrics-content"></div>
|
<div id="biometrics-content"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Inventory Container -->
|
||||||
|
<div id="inventory-container"></div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const config = {
|
const config = {
|
||||||
type: Phaser.AUTO,
|
type: Phaser.AUTO,
|
||||||
@@ -1994,14 +2066,14 @@
|
|||||||
// Convert pointer position to world coordinates
|
// Convert pointer position to world coordinates
|
||||||
|
|
||||||
// Calculate the inventory area based on the container's position and size
|
// Calculate the inventory area based on the container's position and size
|
||||||
const inventoryBounds = inventory.container.getBounds();
|
const inventoryBounds = inventory.container.getBoundingClientRect();
|
||||||
|
|
||||||
if (pointer.y > inventoryBounds.y && pointer.y < inventoryBounds.y + inventoryBounds.height &&
|
if (pointer.y > inventoryBounds.top && pointer.y < inventoryBounds.bottom &&
|
||||||
pointer.x > inventoryBounds.x && pointer.x < inventoryBounds.x + inventoryBounds.width) {
|
pointer.x > inventoryBounds.left && pointer.x < inventoryBounds.right) {
|
||||||
// Find clicked inventory item
|
// Find clicked inventory item
|
||||||
const clickedItem = inventory.items.find(item => {
|
const clickedItem = inventory.items.find(item => {
|
||||||
if (!item) return false;
|
if (!item) return false;
|
||||||
const bounds = item.getBounds();
|
const bounds = item.getBoundingClientRect();
|
||||||
return Phaser.Geom.Rectangle.Contains(
|
return Phaser.Geom.Rectangle.Contains(
|
||||||
bounds,
|
bounds,
|
||||||
pointer.x,
|
pointer.x,
|
||||||
@@ -3173,7 +3245,7 @@
|
|||||||
|
|
||||||
let message = `${data.name}\n\n`;
|
let message = `${data.name}\n\n`;
|
||||||
if (data.observations) {
|
if (data.observations) {
|
||||||
message += `Observations: ${data.observations}\n\n`;
|
message += `Observations: ${data.observations}\n\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.readable && data.text) {
|
if (data.readable && data.text) {
|
||||||
@@ -3312,70 +3384,51 @@
|
|||||||
|
|
||||||
sprite.setVisible(false);
|
sprite.setVisible(false);
|
||||||
|
|
||||||
const scene = sprite.scene;
|
// Find first empty slot
|
||||||
|
const slots = inventory.container.getElementsByClassName('inventory-slot');
|
||||||
|
let emptySlot = null;
|
||||||
|
for (const slot of slots) {
|
||||||
|
if (!slot.hasChildNodes()) {
|
||||||
|
emptySlot = slot;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SIMPLIFIED INVENTORY NAMING
|
if (!emptySlot) {
|
||||||
// Use a consistent format: inventory_type_index
|
console.warn('No empty inventory slots available');
|
||||||
const inventoryId = `inventory_${sprite.name}_${inventory.items.length}`;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Create new sprite for inventory
|
// Create inventory item
|
||||||
const inventorySprite = scene.add.sprite(
|
const itemImg = document.createElement('img');
|
||||||
inventory.items.length * 60,
|
itemImg.className = 'inventory-item';
|
||||||
0,
|
itemImg.src = `assets/objects/${sprite.name}.png`;
|
||||||
sprite.name
|
itemImg.alt = sprite.scenarioData.name;
|
||||||
);
|
|
||||||
|
|
||||||
inventorySprite.setInteractive({ useHandCursor: true, pixelPerfect: true });
|
// Create tooltip
|
||||||
inventorySprite.scenarioData = {
|
const tooltip = document.createElement('div');
|
||||||
|
tooltip.className = 'inventory-tooltip';
|
||||||
|
tooltip.textContent = sprite.scenarioData.name;
|
||||||
|
|
||||||
|
// Add item data
|
||||||
|
itemImg.scenarioData = {
|
||||||
...sprite.scenarioData,
|
...sprite.scenarioData,
|
||||||
foundIn: currentRoom ? gameScenario.rooms[currentRoom].name || currentRoom : 'unknown location'
|
foundIn: currentRoom ? gameScenario.rooms[currentRoom].name || currentRoom : 'unknown location'
|
||||||
};
|
};
|
||||||
inventorySprite.name = sprite.name;
|
itemImg.name = sprite.name;
|
||||||
inventorySprite.objectId = inventoryId;
|
itemImg.objectId = `inventory_${sprite.name}_${inventory.items.length}`;
|
||||||
|
|
||||||
// Set depth higher than container
|
// Add click handler
|
||||||
inventorySprite.setDepth(2003);
|
itemImg.addEventListener('click', function() {
|
||||||
|
handleObjectInteraction(this);
|
||||||
// Add pointer events
|
|
||||||
inventorySprite.on('pointerdown', function(pointer) {
|
|
||||||
// Handle inventory item interaction
|
|
||||||
handleObjectInteraction(inventorySprite);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
inventorySprite.on('pointerover', function() {
|
// Add to slot
|
||||||
this.setTint(0xdddddd);
|
emptySlot.appendChild(itemImg);
|
||||||
|
emptySlot.appendChild(tooltip);
|
||||||
// Show tooltip with item name
|
|
||||||
const tooltipText = scene.add.text(
|
|
||||||
this.x,
|
|
||||||
this.y - 40,
|
|
||||||
this.scenarioData.name,
|
|
||||||
{
|
|
||||||
fontSize: '14px',
|
|
||||||
backgroundColor: '#000',
|
|
||||||
padding: { x: 5, y: 3 },
|
|
||||||
fixedWidth: 150,
|
|
||||||
align: 'center'
|
|
||||||
}
|
|
||||||
).setOrigin(0.5, 0.5).setDepth(2004);
|
|
||||||
|
|
||||||
this.tooltip = tooltipText;
|
|
||||||
});
|
|
||||||
|
|
||||||
inventorySprite.on('pointerout', function() {
|
|
||||||
this.clearTint();
|
|
||||||
|
|
||||||
if (this.tooltip) {
|
|
||||||
this.tooltip.destroy();
|
|
||||||
this.tooltip = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add to inventory array
|
// Add to inventory array
|
||||||
inventory.items.push(inventorySprite);
|
inventory.items.push(itemImg);
|
||||||
|
|
||||||
// Add to container
|
|
||||||
inventory.container.add(inventorySprite);
|
|
||||||
|
|
||||||
// Show notification
|
// Show notification
|
||||||
gameAlert(`Added ${sprite.scenarioData.name} to inventory`, 'success', 'Item Collected', 3000);
|
gameAlert(`Added ${sprite.scenarioData.name} to inventory`, 'success', 'Item Collected', 3000);
|
||||||
@@ -3399,37 +3452,91 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeFromInventory(item) {
|
||||||
|
try {
|
||||||
|
// Find the item in the inventory array
|
||||||
|
const itemIndex = inventory.items.indexOf(item);
|
||||||
|
if (itemIndex === -1) return false;
|
||||||
|
|
||||||
|
// Remove from array
|
||||||
|
inventory.items.splice(itemIndex, 1);
|
||||||
|
|
||||||
|
// Remove from DOM
|
||||||
|
const slot = item.parentElement;
|
||||||
|
if (slot) {
|
||||||
|
slot.innerHTML = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide bluetooth toggle if we dropped the bluetooth scanner
|
||||||
|
if (item.scenarioData.type === "bluetooth_scanner") {
|
||||||
|
const bluetoothToggle = document.getElementById('bluetooth-toggle');
|
||||||
|
bluetoothToggle.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide biometrics toggle if we dropped the fingerprint kit
|
||||||
|
if (item.scenarioData.type === "fingerprint_kit") {
|
||||||
|
const biometricsToggle = document.getElementById('biometrics-toggle');
|
||||||
|
biometricsToggle.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error removing from inventory:', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dropInventoryItem(item) {
|
||||||
|
try {
|
||||||
|
if (!item || !item.scenarioData) return false;
|
||||||
|
|
||||||
|
// Get player position
|
||||||
|
const dropPos = {
|
||||||
|
x: player.x,
|
||||||
|
y: player.y
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a new sprite at the drop position
|
||||||
|
const droppedItem = createInteractiveSprite(
|
||||||
|
item.scenarioData,
|
||||||
|
dropPos.x,
|
||||||
|
dropPos.y,
|
||||||
|
currentRoom
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!droppedItem) return false;
|
||||||
|
|
||||||
|
// Remove from inventory
|
||||||
|
removeFromInventory(item);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error dropping inventory item:', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// initializes inventory
|
// initializes inventory
|
||||||
// creates the background and slot outlines
|
// creates the background and slot outlines
|
||||||
function initializeInventory() {
|
function initializeInventory() {
|
||||||
// Reset inventory state
|
// Reset inventory state
|
||||||
inventory.items = [];
|
inventory.items = [];
|
||||||
|
|
||||||
// Create slot outlines
|
// Get the HTML inventory container
|
||||||
const slotsContainer = this.add.container(INVENTORY_X_OFFSET, this.cameras.main.height - INVENTORY_Y_OFFSET)
|
const inventoryContainer = document.getElementById('inventory-container');
|
||||||
.setScrollFactor(0)
|
inventoryContainer.innerHTML = '';
|
||||||
.setDepth(2001);
|
|
||||||
|
|
||||||
// Create 10 slot outlines
|
// Create 10 slot outlines
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
const outline = this.add.rectangle(
|
const slot = document.createElement('div');
|
||||||
i * 60,
|
slot.className = 'inventory-slot';
|
||||||
0,
|
inventoryContainer.appendChild(slot);
|
||||||
50, // slightly smaller than spacing
|
|
||||||
50,
|
|
||||||
0x666666,
|
|
||||||
0.3
|
|
||||||
);
|
|
||||||
outline.setStrokeStyle(1, 0x666666);
|
|
||||||
slotsContainer.add(outline);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize inventory container - use the same X offset as slots
|
// Store reference to container
|
||||||
inventory.container = this.add.container(INVENTORY_X_OFFSET, this.cameras.main.height - INVENTORY_Y_OFFSET)
|
inventory.container = inventoryContainer;
|
||||||
.setScrollFactor(0)
|
|
||||||
.setDepth(2001);
|
|
||||||
|
|
||||||
debugLog('INVENTORY INITIALIZED', inventory, 2); // Debug log at level 2
|
debugLog('INVENTORY INITIALIZED', inventory, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process all items marked with inInventory: true in the scenario data
|
// Process all items marked with inInventory: true in the scenario data
|
||||||
@@ -6540,61 +6647,6 @@
|
|||||||
biometricsPanel.style.display = 'none';
|
biometricsPanel.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to drop an inventory item
|
|
||||||
function dropInventoryItem(item) {
|
|
||||||
try {
|
|
||||||
if (!item || !item.scenarioData) return false;
|
|
||||||
|
|
||||||
// Get player position
|
|
||||||
const dropPos = {
|
|
||||||
x: player.x,
|
|
||||||
y: player.y
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create a new sprite at the drop position
|
|
||||||
const droppedItem = createInteractiveSprite(
|
|
||||||
item.scenarioData,
|
|
||||||
dropPos.x,
|
|
||||||
dropPos.y,
|
|
||||||
currentRoom
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!droppedItem) return false;
|
|
||||||
|
|
||||||
// Remove from inventory array
|
|
||||||
const itemIndex = inventory.items.indexOf(item);
|
|
||||||
if (itemIndex !== -1) {
|
|
||||||
inventory.items.splice(itemIndex, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove from inventory container
|
|
||||||
inventory.container.remove(item);
|
|
||||||
|
|
||||||
// Destroy inventory sprite
|
|
||||||
item.destroy();
|
|
||||||
|
|
||||||
// Recalculate inventory positions
|
|
||||||
updateInventoryPositions();
|
|
||||||
|
|
||||||
// Hide bluetooth toggle if we dropped the bluetooth scanner
|
|
||||||
if (item.scenarioData.type === "bluetooth_scanner") {
|
|
||||||
const bluetoothToggle = document.getElementById('bluetooth-toggle');
|
|
||||||
bluetoothToggle.style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide biometrics toggle if we dropped the fingerprint kit
|
|
||||||
if (item.scenarioData.type === "fingerprint_kit") {
|
|
||||||
const biometricsToggle = document.getElementById('biometrics-toggle');
|
|
||||||
biometricsToggle.style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error dropping item:', error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to initialize the toggle buttons container
|
// Function to initialize the toggle buttons container
|
||||||
function initializeToggleButtons() {
|
function initializeToggleButtons() {
|
||||||
// Set up notes toggle button
|
// Set up notes toggle button
|
||||||
|
|||||||
Reference in New Issue
Block a user