UNPKG

hytopia

Version:

The HYTOPIA SDK makes it easy for developers to create massively multiplayer games using JavaScript or TypeScript.

216 lines (189 loc) 5.21 kB
<!-- Template for Agent Chat Bubble --> <template id="agent-chat"> <div class="agent-chat"> <div class="agent-header"> <div class="agent-name"></div> </div> <div class="chat-bubble"> <div class="message"></div> </div> </div> </template> <div id="agent-thoughts-panel"> <h2>Agent Thoughts</h2> <div id="thoughts-container"> <!-- Thoughts will be inserted here --> </div> </div> <style> /* Chat Bubble Styles */ .agent-chat { position: absolute; top: -40px; left: 50%; transform: translateX(-50%); text-align: center; pointer-events: none; width: 500px; } .agent-header { margin-bottom: 8px; } .agent-name { background: #4a5568; color: white; padding: 4px 12px; border-radius: 12px; display: inline-block; font-weight: bold; font-size: 16px; text-shadow: 0 1px 2px rgba(0,0,0,0.2); box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .chat-bubble { background: rgba(255, 255, 255, 0.9); color: black; padding: 8px 12px; border-radius: 16px; width: 100%; max-width: 500px; border: 1px solid rgba(0, 0, 0, 0.1); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); opacity: 1; transition: opacity 0.3s ease; display: inline-block; min-width: 200px; } .chat-bubble.fade { opacity: 0; } .message { font-size: 14px; word-wrap: break-word; line-height: 1.4; white-space: pre-wrap; } /* Thoughts Panel Styles */ #upgrade-panel { position: absolute; right: 20px; top: 20px; background-color: rgba(0, 0, 0, 0.7); color: white; padding: 15px; border-radius: 8px; min-width: 200px; font-family: Arial, sans-serif; } #agent-thoughts-panel { position: absolute; right: 20px; top: 200px; background-color: rgba(0, 0, 0, 0.7); color: white; padding: 15px; border-radius: 8px; min-width: 250px; max-width: 300px; font-family: Arial, sans-serif; } #agent-thoughts-panel h2 { margin: 0 0 10px 0; font-size: 16px; color: #3498db; } .thought-entry { margin-bottom: 15px; padding: 10px; background: rgba(255, 255, 255, 0.1); border-radius: 6px; } .thought-agent-name { color: #3498db; font-weight: bold; margin-bottom: 5px; } .thought-text { font-style: italic; font-size: 14px; line-height: 1.4; } /* Add these styles */ .inventory-list { margin-top: 8px; font-size: 12px; color: #aaa; } .inventory-item { display: flex; justify-content: space-between; padding: 2px 0; } .inventory-item-name { color: #ddd; } .inventory-item-quantity { color: #888; } </style> <script> // Register chat bubble template hytopia.registerSceneUITemplate('agent-chat', (id, onState) => { const element = document.getElementById('agent-chat').content.cloneNode(true); const container = element.querySelector('.agent-chat'); const bubble = container.querySelector('.chat-bubble'); const messageEl = container.querySelector('.message'); let fadeTimeout; onState(data => { // Set agent name const nameEl = container.querySelector('.agent-name'); if (nameEl && data.agentName) { nameEl.textContent = data.agentName; } // Agent header is always visible container.style.display = 'block'; if (data.message) { // Clear any existing timeout clearTimeout(fadeTimeout); // Show new message messageEl.textContent = data.message; bubble.classList.remove('fade'); bubble.style.display = 'block'; // Set timeout to fade after 5 seconds fadeTimeout = setTimeout(() => { bubble.classList.add('fade'); setTimeout(() => { bubble.style.display = 'none'; }, 300); // Match transition duration }, 5000); } else { // Hide only the chat bubble if there's no message bubble.style.display = 'none'; } }); return element; }); // Handle received data from server hytopia.onData((data) => { console.log(data); if (data.type === 'agentThoughts') { const container = document.getElementById('thoughts-container'); container.innerHTML = data.agents.map(agent => ` <div class="thought-entry"> <div class="thought-agent-name">${agent.name}</div> <div class="thought-text">${agent.lastThought}</div> ${agent.inventory && agent.inventory.length > 0 ? ` <div class="inventory-list"> ${agent.inventory.map(item => ` <div class="inventory-item"> <span class="inventory-item-name">${item.name}</span> <span class="inventory-item-quantity">x${item.quantity}</span> </div> `).join('')} </div> ` : ''} </div> `).join(''); } }); </script>