hytopia 0.1.70 → 0.1.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,270 @@
1
+ <!-- Scripts -->
2
+ <script>
3
+ // State
4
+ let queueCount = 0;
5
+ let gameState = '';
6
+ let gameStartTime = 0;
7
+
8
+ // Helper functions
9
+ function formatTime(seconds) {
10
+ const minutes = Math.floor(seconds / 60);
11
+ const remainingSeconds = seconds % 60;
12
+ return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
13
+ }
14
+
15
+ function updateGameStatus(status) {
16
+ const gameStatusElements = document.getElementsByClassName('game-status');
17
+ for (let i = 0; i < gameStatusElements.length; i++) {
18
+ gameStatusElements[i].innerText = status;
19
+ }
20
+ }
21
+
22
+ function updatePlayerList(players) {
23
+ const playerListElement = document.getElementsByClassName('player-list')[0];
24
+ playerListElement.innerHTML = '';
25
+
26
+ players.forEach(player => {
27
+ const playerEntry = document.createElement('div');
28
+ playerEntry.classList.add('player-entry');
29
+ playerEntry.innerText = player;
30
+ playerListElement.appendChild(playerEntry);
31
+ });
32
+ }
33
+
34
+ // Event handlers
35
+ hytopia.onData(data => {
36
+ console.log(data);
37
+
38
+ if (data.queueCount !== undefined) {
39
+ queueCount = data.queueCount;
40
+
41
+ const joinNpcQueuedPlayerCount = document.getElementById('join-npc-queued-player-count');
42
+ if (joinNpcQueuedPlayerCount) {
43
+ joinNpcQueuedPlayerCount.innerText = data.queueCount;
44
+ }
45
+
46
+ const queuedPlayerCount = document.getElementById('queued-player-count');
47
+ if (queuedPlayerCount) {
48
+ queuedPlayerCount.innerText = data.queueCount;
49
+ }
50
+ }
51
+
52
+ if (data.gameState !== undefined) {
53
+ gameState = data.gameState;
54
+
55
+ if (gameState === 'awaitingPlayers') {
56
+ document.getElementById('game-board-awaiting-players-info').style.display = 'block';
57
+ document.getElementById('game-board-active-game-info').style.display = 'none';
58
+ updateGameStatus('AWAITING PLAYERS...');
59
+ }
60
+
61
+ if (gameState === 'starting') {
62
+ const gameCountdownStartTime = data.gameCountdownStartTime;
63
+ const countdownSeconds = data.countdown;
64
+
65
+ const updateCountdown = () => {
66
+ const now = Date.now();
67
+ const timeLeft = Math.max(0, Math.ceil((gameCountdownStartTime + (countdownSeconds * 1000) - now) / 1000));
68
+ updateGameStatus(`GAME STARTING IN ${timeLeft}...`);
69
+
70
+ if (timeLeft > 0 && gameState === 'starting') {
71
+ setTimeout(updateCountdown, 1000);
72
+ }
73
+ };
74
+
75
+ updateCountdown();
76
+ }
77
+
78
+ if (gameState === 'inProgress') {
79
+ document.getElementById('game-board-awaiting-players-info').style.display = 'none';
80
+ document.getElementById('game-board-active-game-info').style.display = 'block';
81
+ updateGameStatus('GAME IN PROGRESS');
82
+ }
83
+ }
84
+
85
+ if (data.gameLevel !== undefined) {
86
+ document.getElementById('game-board-level').innerText = data.gameLevel;
87
+ }
88
+
89
+ if (data.gameStartTime !== undefined) {
90
+ gameStartTime = data.gameStartTime;
91
+
92
+ const updateElapsedTime = () => {
93
+ const now = Date.now();
94
+ const timeElapsed = Math.floor((now - gameStartTime) / 1000);
95
+ document.getElementById('elapsed-time').innerText = formatTime(timeElapsed);
96
+
97
+ if (gameState === 'inProgress') {
98
+ setTimeout(updateElapsedTime, 1000);
99
+ }
100
+ };
101
+
102
+ updateElapsedTime();
103
+ }
104
+
105
+ if (data.playersRemaining !== undefined) {
106
+ document.getElementById('players-remaining').innerText = data.playersRemaining.length;
107
+ updatePlayerList(data.playersRemaining);
108
+ }
109
+ });
110
+
111
+ hytopia.registerSceneUITemplate('join-npc-ui', () => {
112
+ const joinNpcUi = document.getElementById('join-npc-ui').content.cloneNode(true);
113
+ joinNpcUi.getElementById('join-npc-queued-player-count').innerText = queueCount;
114
+ return joinNpcUi;
115
+ });
116
+
117
+ hytopia.registerSceneUITemplate('player-queued', () => {
118
+ return document.getElementById('player-queued').content.cloneNode(true);
119
+ });
120
+ </script>
121
+
122
+ <!-- Game UI -->
123
+ <template id="join-npc-ui">
124
+ <div class="join-message-box">
125
+ <h2>Join Game</h2>
126
+ <p>Come close to queue up for the next game!</p>
127
+ <p class="player-count">PLAYERS QUEUED: <span id="join-npc-queued-player-count">0</span></p>
128
+ <p class="game-status">AWAITING PLAYERS...</p>
129
+ <div class="arrow"></div>
130
+ </div>
131
+ </template>
132
+
133
+ <template id="player-queued">
134
+ <div class="queued-message-box">
135
+ <p class="queued-text">READY</p>
136
+ <div class="arrow"></div>
137
+ </div>
138
+ </template>
139
+
140
+ <div class="game-board">
141
+ <h2>Hole In The Wall</h2>
142
+
143
+ <div id="game-board-awaiting-players-info">
144
+ <p class="elapsed-time">Queued Players: <span id="queued-player-count">0</span></p>
145
+ <p class="game-status">AWAITING PLAYERS...</p>
146
+ </div>
147
+
148
+ <div id="game-board-active-game-info">
149
+ <p class="level">Level: <span id="game-board-level">1</span></p>
150
+ <p class="elapsed-time">Elapsed Time: <span id="elapsed-time">00:00</span></p>
151
+ <p class="players-remaining">Players remaining: <span id="players-remaining">10</span></p>
152
+ <div class="player-list"></div>
153
+ </div>
154
+ </div>
155
+
156
+ <!-- Styles -->
157
+ <style>
158
+ /* Global styles */
159
+ * {
160
+ font-family: Arial, sans-serif;
161
+ user-select: none;
162
+ }
163
+
164
+ /* Game board styles */
165
+ .game-board {
166
+ position: fixed;
167
+ top: 20px;
168
+ right: 20px;
169
+ background: rgba(0,0,0,0.8);
170
+ padding: 15px 20px;
171
+ border-radius: 12px;
172
+ width: 200px;
173
+ }
174
+
175
+ .game-board h2 {
176
+ color: white;
177
+ margin: 0 0 10px 0;
178
+ font-size: 24px;
179
+ text-align: center;
180
+ }
181
+
182
+ #game-board-active-game-info {
183
+ display: none;
184
+ }
185
+
186
+ .level {
187
+ color: #4ade80;
188
+ margin: 0 0 5px 0;
189
+ text-align: center;
190
+ font-weight: bold;
191
+ }
192
+
193
+ .elapsed-time {
194
+ color: #60a5fa;
195
+ margin: 0 0 5px 0;
196
+ text-align: center;
197
+ font-weight: bold;
198
+ }
199
+
200
+ .players-remaining, #game-board-awaiting-players-info {
201
+ color: #ff4444;
202
+ margin: 0 0 15px 0;
203
+ text-align: center;
204
+ font-weight: bold;
205
+ }
206
+
207
+ .player-list {
208
+ max-height: 220px;
209
+ overflow-y: scroll;
210
+ }
211
+
212
+ .player-entry {
213
+ color: white;
214
+ padding: 5px 10px;
215
+ margin: 5px 0;
216
+ background: rgba(255,255,255,0.1);
217
+ border-radius: 4px;
218
+ }
219
+
220
+ .join-message-box, .queued-message-box {
221
+ background: rgba(0,0,0,0.8);
222
+ padding: 15px 20px 10px 20px;
223
+ border-radius: 12px;
224
+ position: relative;
225
+ max-width: 250px;
226
+ text-align: center;
227
+ }
228
+
229
+ .join-message-box h2 {
230
+ color: white;
231
+ margin: 0 0 10px 0;
232
+ font-size: 24px;
233
+ text-align: center;
234
+ }
235
+
236
+ .join-message-box p {
237
+ color: white;
238
+ margin: 0 0 15px 0;
239
+ text-align: center;
240
+ }
241
+
242
+ .join-message-box .player-count {
243
+ color: #4ade80;
244
+ font-weight: bold;
245
+ }
246
+
247
+ .join-message-box .game-status {
248
+ color: #ef4444;
249
+ font-weight: bold;
250
+ }
251
+
252
+ .queued-message-box .queued-text {
253
+ color: #4ade80;
254
+ font-size: 24px;
255
+ font-weight: bold;
256
+ margin: 0;
257
+ }
258
+
259
+ .join-message-box .arrow {
260
+ width: 0;
261
+ height: 0;
262
+ border-left: 10px solid transparent;
263
+ border-right: 10px solid transparent;
264
+ border-top: 10px solid rgba(0,0,0,0.8);
265
+ position: absolute;
266
+ bottom: -10px;
267
+ left: 50%;
268
+ transform: translateX(-50%);
269
+ }
270
+ </style>