mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-21 11:18:08 +00:00
Implement Notebook Functionality: Add a notebook button to the Password and Container minigames for saving post-it notes. Enhance inventory interactions with pulse animations instead of notifications for item collection. Update CSS for new animations and layout adjustments in various minigames to improve user experience.
This commit is contained in:
@@ -38,6 +38,26 @@
|
||||
background: rgb(149 157 216 / 80%);
|
||||
}
|
||||
|
||||
/* Pulse animation for newly added items */
|
||||
@keyframes pulse-slot {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.5);
|
||||
box-shadow: 0 0 0 10px rgba(255, 255, 255, 0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.inventory-slot.pulse {
|
||||
animation: pulse-slot 0.6s ease-out;
|
||||
}
|
||||
|
||||
.inventory-item {
|
||||
max-width: 48px;
|
||||
max-height: 48px;
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
margin: 0;
|
||||
overflow: auto; /* Allow scrolling if content is too long */
|
||||
box-sizing: border-box;
|
||||
height: 90%; /* so that it scolls before the bottom of the image */
|
||||
}
|
||||
|
||||
/* Text box container */
|
||||
|
||||
@@ -180,11 +180,7 @@
|
||||
background: rgba(0, 255, 0, 0.1);
|
||||
}
|
||||
|
||||
.icon-small {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
|
||||
.icon-keyboard {
|
||||
width: 40px;
|
||||
@@ -226,6 +222,13 @@
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.hint-controls {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.password-hint-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -236,7 +239,7 @@
|
||||
background: #f39c12;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
padding: 12px 24px;
|
||||
/* border-radius: 5px; */
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
|
||||
@@ -43,6 +43,15 @@ export class ContainerMinigame extends MinigameScene {
|
||||
`;
|
||||
}
|
||||
|
||||
// Add notebook button to minigame controls if postit note exists
|
||||
if (this.controlsElement && this.containerItem.scenarioData.postitNote && this.containerItem.scenarioData.showPostit) {
|
||||
const notebookBtn = document.createElement('button');
|
||||
notebookBtn.className = 'minigame-button';
|
||||
notebookBtn.id = 'minigame-notebook-postit';
|
||||
notebookBtn.innerHTML = '<img src="assets/icons/notes-sm.png" alt="Notebook" class="icon-small"> Add to Notebook';
|
||||
this.controlsElement.appendChild(notebookBtn);
|
||||
}
|
||||
|
||||
// Create the container minigame UI
|
||||
this.createContainerUI();
|
||||
}
|
||||
@@ -235,6 +244,12 @@ export class ContainerMinigame extends MinigameScene {
|
||||
if (closeBtn) {
|
||||
this.addEventListener(closeBtn, 'click', () => this.complete(false));
|
||||
}
|
||||
|
||||
// Add to Notebook button
|
||||
const addToNotebookBtn = document.getElementById('minigame-notebook-postit');
|
||||
if (addToNotebookBtn) {
|
||||
this.addEventListener(addToNotebookBtn, 'click', () => this.addPostitToNotebook());
|
||||
}
|
||||
}
|
||||
|
||||
isInteractiveItem(item) {
|
||||
@@ -396,6 +411,80 @@ export class ContainerMinigame extends MinigameScene {
|
||||
window.gameAlert('Crypto workstation not available', 'error', 'Error', 3000);
|
||||
}
|
||||
}
|
||||
|
||||
addPostitToNotebook() {
|
||||
console.log('Adding postit note to notebook:', this.containerItem.scenarioData.postitNote);
|
||||
|
||||
const postitNote = this.containerItem.scenarioData.postitNote;
|
||||
if (!postitNote || postitNote.trim() === '') {
|
||||
this.showMessage('No postit note to add.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// Create comprehensive notebook content
|
||||
const notebookTitle = `Postit Note - ${this.containerItem.scenarioData.name}`;
|
||||
let notebookContent = `Postit Note:\n${'-'.repeat(50)}\n\n${postitNote}`;
|
||||
|
||||
// Add container contents list
|
||||
notebookContent += `\n\n${'='.repeat(20)}\n`;
|
||||
notebookContent += `CONTAINER CONTENTS: ${this.containerItem.scenarioData.name}\n`;
|
||||
notebookContent += `${'='.repeat(20)}\n`;
|
||||
|
||||
if (this.contents && this.contents.length > 0) {
|
||||
this.contents.forEach((item, index) => {
|
||||
notebookContent += `${index + 1}. ${item.name || item.type}`;
|
||||
if (item.description) {
|
||||
notebookContent += ` - ${item.description}`;
|
||||
}
|
||||
notebookContent += '\n';
|
||||
});
|
||||
} else {
|
||||
notebookContent += 'No items found\n';
|
||||
}
|
||||
|
||||
notebookContent += `${'='.repeat(20)}\n`;
|
||||
notebookContent += `Date: ${new Date().toLocaleString()}`;
|
||||
|
||||
const notebookObservations = `Postit note found in ${this.containerItem.scenarioData.name}.`;
|
||||
|
||||
// Check if notes minigame is available
|
||||
if (window.startNotesMinigame) {
|
||||
// Store the container state globally so we can return to it
|
||||
const containerState = {
|
||||
containerItem: this.containerItem,
|
||||
contents: this.contents,
|
||||
isTakeable: this.isTakeable
|
||||
};
|
||||
|
||||
window.pendingContainerReturn = containerState;
|
||||
|
||||
// Create a postit item for the notes minigame
|
||||
const postitItem = {
|
||||
scenarioData: {
|
||||
type: 'postit_note',
|
||||
name: notebookTitle,
|
||||
text: notebookContent,
|
||||
observations: notebookObservations,
|
||||
important: true
|
||||
}
|
||||
};
|
||||
|
||||
// Start notes minigame
|
||||
window.startNotesMinigame(
|
||||
postitItem,
|
||||
notebookContent,
|
||||
notebookObservations,
|
||||
null,
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
this.showMessage("Added postit note to notebook", 'success');
|
||||
} else {
|
||||
console.error('Notes minigame not available');
|
||||
this.showMessage('Notebook not available', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
takeItem(item, itemElement) {
|
||||
console.log('Taking item from container:', item);
|
||||
|
||||
@@ -799,10 +799,6 @@ window.addNote = function(title, text, important = false) {
|
||||
|
||||
window.gameState.notes.push(note);
|
||||
|
||||
// Show notification for new note
|
||||
if (window.showNotification) {
|
||||
window.showNotification(`New note added: ${title}`, 'info', 'Note Added', 3000);
|
||||
}
|
||||
|
||||
return note;
|
||||
};
|
||||
|
||||
@@ -36,6 +36,15 @@ export class PasswordMinigame extends MinigameScene {
|
||||
// Set up the password interface
|
||||
this.setupPasswordInterface();
|
||||
|
||||
// Add notebook button to minigame controls if postit note exists (before cancel button)
|
||||
if (this.controlsElement && this.gameData.showPostit && this.gameData.postitNote) {
|
||||
const notebookBtn = document.createElement('button');
|
||||
notebookBtn.className = 'minigame-button';
|
||||
notebookBtn.id = 'minigame-notebook-postit';
|
||||
notebookBtn.innerHTML = '<img src="assets/icons/notes-sm.png" alt="Notebook" class="icon-small"> Add to Notebook';
|
||||
this.controlsElement.appendChild(notebookBtn);
|
||||
}
|
||||
|
||||
// Set up event listeners
|
||||
this.setupEventListeners();
|
||||
}
|
||||
@@ -61,8 +70,11 @@ export class PasswordMinigame extends MinigameScene {
|
||||
</div>
|
||||
|
||||
${this.gameData.showHint ? `
|
||||
<div class="password-hint-container">
|
||||
<div class="hint-controls">
|
||||
<button type="button" class="hint-btn" id="show-hint">Show Hint</button>
|
||||
<button type="button" class="submit-btn" id="submit-password">Submit</button>
|
||||
</div>
|
||||
<div class="password-hint-container">
|
||||
<div class="password-hint" id="password-hint" style="display: none;">
|
||||
<strong>Hint:</strong> ${this.gameData.passwordHint}
|
||||
</div>
|
||||
@@ -78,12 +90,9 @@ export class PasswordMinigame extends MinigameScene {
|
||||
` : ''}
|
||||
|
||||
<div class="password-controls">
|
||||
${this.gameData.showHint ? `
|
||||
<button type="button" class="submit-btn" id="submit-password">Submit</button>
|
||||
` : ''}
|
||||
${this.gameData.showKeyboard ? `
|
||||
<button type="button" class="keyboard-toggle-btn" id="keyboard-toggle">
|
||||
<img class="icon-keyboard" src="assets/objects/keyboard3.png" alt="Toggle keyboard">
|
||||
<img class="icon-keyboard" src="assets/objects/keyboard1.png" alt="Toggle keyboard">
|
||||
</button>
|
||||
` : ''}
|
||||
</div>
|
||||
@@ -211,6 +220,14 @@ export class PasswordMinigame extends MinigameScene {
|
||||
this.handleKeyboardClick(event);
|
||||
});
|
||||
}
|
||||
|
||||
// Notebook button for postit (in minigame controls)
|
||||
const notebookBtn = document.getElementById('minigame-notebook-postit');
|
||||
if (notebookBtn) {
|
||||
this.addEventListener(notebookBtn, 'click', () => {
|
||||
this.addPostitToNotebook();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
start() {
|
||||
@@ -385,6 +402,78 @@ export class PasswordMinigame extends MinigameScene {
|
||||
};
|
||||
}
|
||||
|
||||
addPostitToNotebook() {
|
||||
if (!this.gameState.isActive) return;
|
||||
|
||||
const postitNote = this.gameData.postitNote;
|
||||
if (!postitNote || postitNote.trim() === '') {
|
||||
this.showFailure("No postit note to add.", false, 2000);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the device name from available sources
|
||||
const deviceName = this.params.deviceName ||
|
||||
this.params.scenarioData?.name ||
|
||||
this.params.title ||
|
||||
'Unknown Device';
|
||||
|
||||
// Create comprehensive notebook content
|
||||
const notebookTitle = `Postit Note - ${deviceName}`;
|
||||
let notebookContent = `Postit Note:\n${'-'.repeat(20)}\n\n${postitNote}`;
|
||||
notebookContent += `\n\n${'='.repeat(20)}\n`;
|
||||
notebookContent += `PASSWORD PROTECTED: ${deviceName}\n`;
|
||||
notebookContent += `${'='.repeat(20)}\n`;
|
||||
notebookContent += `Date: ${new Date().toLocaleString()}`;
|
||||
|
||||
const notebookObservations = 'Postit note found during password entry.';
|
||||
|
||||
// Check if notes minigame is available
|
||||
if (window.startNotesMinigame) {
|
||||
// Store the password state globally so we can return to it
|
||||
const passwordState = {
|
||||
password: this.gameData.password,
|
||||
passwordHint: this.gameData.passwordHint,
|
||||
showHint: this.gameData.showHint,
|
||||
showKeyboard: this.gameData.showKeyboard,
|
||||
maxAttempts: this.gameData.maxAttempts,
|
||||
attempts: this.gameData.attempts,
|
||||
showPassword: this.gameData.showPassword,
|
||||
postitNote: this.gameData.postitNote,
|
||||
showPostit: this.gameData.showPostit,
|
||||
capsLock: this.gameData.capsLock,
|
||||
keyboardVisible: this.gameData.keyboardVisible,
|
||||
params: this.params
|
||||
};
|
||||
|
||||
window.pendingPasswordReturn = passwordState;
|
||||
|
||||
// Create a postit item for the notes minigame
|
||||
const postitItem = {
|
||||
scenarioData: {
|
||||
type: 'postit_note',
|
||||
name: notebookTitle,
|
||||
text: notebookContent,
|
||||
observations: notebookObservations,
|
||||
important: true
|
||||
}
|
||||
};
|
||||
|
||||
// Start notes minigame
|
||||
window.startNotesMinigame(
|
||||
postitItem,
|
||||
notebookContent,
|
||||
notebookObservations,
|
||||
null,
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
this.showSuccess("Added postit note to notebook", false, 2000);
|
||||
} else {
|
||||
this.showFailure("Notebook not available", false, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
// Call parent cleanup (handles event listeners)
|
||||
super.cleanup();
|
||||
|
||||
@@ -776,7 +776,7 @@ export class PhoneMessagesMinigame extends MinigameScene {
|
||||
content += `Source: ${this.params?.title || 'Phone'}\n`;
|
||||
content += `Total Messages: ${this.phoneData.messages.length}\n`;
|
||||
content += `Date: ${new Date().toLocaleString()}\n\n`;
|
||||
content += `${'='.repeat(50)}\n\n`;
|
||||
content += `${'='.repeat(20)}\n\n`;
|
||||
|
||||
this.phoneData.messages.forEach((message, index) => {
|
||||
content += `Message ${index + 1}:\n`;
|
||||
@@ -796,7 +796,7 @@ export class PhoneMessagesMinigame extends MinigameScene {
|
||||
}
|
||||
});
|
||||
|
||||
content += `${'='.repeat(50)}\n`;
|
||||
content += `${'='.repeat(20)}\n`;
|
||||
content += `End of Phone Messages Log`;
|
||||
|
||||
return content;
|
||||
|
||||
@@ -340,11 +340,11 @@ export class TextFileMinigame extends MinigameScene {
|
||||
content += `Source: ${this.textFileData.source}\n`;
|
||||
content += `Type: ${this.textFileData.fileType.toUpperCase()}\n`;
|
||||
content += `Date: ${new Date().toLocaleString()}\n\n`;
|
||||
content += `${'='.repeat(50)}\n\n`;
|
||||
content += `${'='.repeat(20)}\n\n`;
|
||||
content += `FILE CONTENTS:\n`;
|
||||
content += `${'-'.repeat(20)}\n\n`;
|
||||
content += this.textFileData.fileContent;
|
||||
content += `\n\n${'='.repeat(50)}\n`;
|
||||
content += `\n\n${'='.repeat(20)}\n`;
|
||||
content += `End of File: ${this.textFileData.fileName}`;
|
||||
|
||||
return content;
|
||||
|
||||
@@ -375,7 +375,7 @@ export function handleObjectInteraction(sprite) {
|
||||
}
|
||||
|
||||
// Show notification
|
||||
window.gameAlert(message, 'info', data.name, 0);
|
||||
window.gameAlert(message, 'info', data.name, 5000);
|
||||
}
|
||||
|
||||
// Handle container item interactions
|
||||
|
||||
@@ -170,10 +170,12 @@ export function addToInventory(sprite) {
|
||||
// Add to inventory array
|
||||
window.inventory.items.push(itemImg);
|
||||
|
||||
// Show notification
|
||||
if (window.gameAlert) {
|
||||
window.gameAlert(`Added ${sprite.scenarioData.name} to inventory`, 'success', 'Item Collected', 3000);
|
||||
}
|
||||
// Apply pulse animation to the slot instead of showing notification
|
||||
slot.classList.add('pulse');
|
||||
// Remove the pulse class after the animation completes
|
||||
setTimeout(() => {
|
||||
slot.classList.remove('pulse');
|
||||
}, 600);
|
||||
|
||||
// If this is the Bluetooth scanner, automatically open the minigame after adding to inventory
|
||||
if (sprite.scenarioData.type === "bluetooth_scanner" && window.startBluetoothScannerMinigame) {
|
||||
@@ -234,9 +236,13 @@ function addKeyToInventory(sprite) {
|
||||
// Update or create the key ring display
|
||||
updateKeyRingDisplay();
|
||||
|
||||
// Show notification
|
||||
if (window.gameAlert) {
|
||||
window.gameAlert(`Added ${sprite.scenarioData.name} to key ring`, 'success', 'Key Collected', 3000);
|
||||
// Apply pulse animation to the key ring slot instead of showing notification
|
||||
const keyRingSlot = window.inventory.keyRing.slot;
|
||||
if (keyRingSlot) {
|
||||
keyRingSlot.classList.add('pulse');
|
||||
setTimeout(() => {
|
||||
keyRingSlot.classList.remove('pulse');
|
||||
}, 600);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user