bbc123321 commited on
Commit
5e1bb7f
·
verified ·
1 Parent(s): 60495f8

Manual changes saved

Browse files
Files changed (1) hide show
  1. index.html +71 -23
index.html CHANGED
@@ -11,7 +11,7 @@
11
  #canvasContainer { position:relative; flex:1; display:flex; justify-content:center; align-items:center; height:100vh; overflow:hidden; }
12
  #gameCanvas { display:block; user-select:none; cursor:crosshair; box-shadow:0 0 20px rgba(0,0,0,.5); width:100%; height:100%; }
13
  #stormWarning { z-index:10; }
14
- #deathScreen { z-index:20; }
15
 
16
  /* HUD */
17
  #hudHealth { position:absolute; left:12px; bottom:12px; background:rgba(0,0,0,0.55); padding:6px 8px; border-radius:8px; font-weight:700; font-size:13px; display:flex; align-items:center; gap:8px; z-index:30; }
@@ -63,7 +63,7 @@
63
  <li><strong>E</strong> — Use medkit in selected slot OR Interact / Loot</li>
64
  <li><strong>Q</strong> — Build (costs 10 materials)</li>
65
  <li><strong>R</strong> — Reload selected weapon</li>
66
- <li><strong>1-5</strong> — Select inventory slot</li>
67
  <li><strong>F</strong> — Equip / Unequip selected slot (pickaxe is the default)</li>
68
  </ul>
69
  </div>
@@ -98,6 +98,19 @@
98
  </button>
99
  </div>
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  <div id="hudHealth" class="hidden">
102
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#ffd86b" stroke-width="1.6"><path d="M20.8 8.6a5.5 5.5 0 0 0-7.8 0L12 10.6l-1-1a5.5 5.5 0 0 0-7.8 7.8l1 1L12 22l7.8-3.6 1-1a5.5 5.5 0 0 0 0-7.8z"></path></svg>
103
  <span id="hudHealthText">100%</span>
@@ -124,6 +137,9 @@
124
  const pickaxeSlot = document.getElementById('pickaxeSlot');
125
  const stormWarning = document.getElementById('stormWarning');
126
  const deathScreen = document.getElementById('deathScreen');
 
 
 
127
 
128
  // World (bigger)
129
  const WORLD = { width: 6000, height: 4000 };
@@ -151,32 +167,46 @@
151
  const keys = { w:false,a:false,s:false,d:false,e:false,q:false,r:false,f:false };
152
  const mouse = { canvasX:0, canvasY:0, worldX:0, worldY:0, down:false };
153
 
154
- // Consolidated key handlers (single source of truth to avoid double toggles)
 
 
 
 
 
 
 
155
  window.addEventListener('keydown',(e)=>{
156
  const k = e.key.toLowerCase();
157
- // movement keys should work only while game active
 
158
  if (gameActive){
159
  if (k in keys) keys[k] = true;
 
160
  if (['1','2','3','4','5'].includes(k)) {
161
- player.selectedSlot = parseInt(k)-1;
162
- // If pickaxe was equipped and user presses a number, unequip pickaxe and equip the slot
163
- if (player.equippedIndex === -1) {
164
- player.equippedIndex = player.selectedSlot;
165
- }
166
  updateHUD();
167
  }
 
168
  if (k === 'f') {
169
- // toggle between pickaxe (-1) and selected slot
170
- player.equippedIndex = (player.equippedIndex === player.selectedSlot) ? -1 : player.selectedSlot;
 
171
  updateHUD();
172
  }
 
173
  if (k === 'r') keys.r = true;
174
  } else {
175
- // allow selecting slots on landing screen (optional)
176
- if (['1','2','3','4','5'].includes(k)) { player.selectedSlot = parseInt(k)-1; updateHUD(); }
177
- // don't change equip state outside game
 
 
178
  }
179
  });
 
180
  window.addEventListener('keyup',(e)=>{
181
  const k = e.key.toLowerCase();
182
  if (k in keys) keys[k] = false;
@@ -193,7 +223,6 @@
193
  player.angle = Math.atan2(mouse.worldY - player.y, mouse.worldX - player.x);
194
  });
195
  canvas.addEventListener('mousedown', (e)=>{
196
- // update mouse coords immediately and set down
197
  const rect = canvas.getBoundingClientRect();
198
  mouse.canvasX = e.clientX - rect.left;
199
  mouse.canvasY = e.clientY - rect.top;
@@ -281,16 +310,23 @@
281
  slot.className = 'gear-slot';
282
  slot.dataset.index = i;
283
  slot.addEventListener('click', ()=> {
284
- player.selectedSlot = i;
285
- // If pickaxe equipped and user clicks a slot, equip that slot
286
- if (player.equippedIndex === -1) player.equippedIndex = player.selectedSlot;
 
 
287
  updateHUD();
288
  });
289
  hudGear.appendChild(slot);
290
  }
291
  // pickaxe click toggles equip (explicit: clicking pickaxe equips/unequips it)
292
  pickaxeSlot.onclick = () => {
293
- player.equippedIndex = (player.equippedIndex === -1) ? player.selectedSlot : -1;
 
 
 
 
 
294
  updateHUD();
295
  };
296
  updateHUD();
@@ -333,7 +369,6 @@
333
  const angle = Math.atan2(targetY-originY, targetX-originX);
334
  // decrement ammo if present
335
  if (typeof weaponObj.ammoInMag === 'number') weaponObj.ammoInMag -= 1;
336
- // weaponObj may be an inventory item (with .weapon) or weaponPickup (with .weapon) — both consistent
337
  const dmg = weaponObj.weapon && weaponObj.weapon.dmg ? weaponObj.weapon.dmg : (weaponObj.dmg || 10);
338
  const color = (weaponObj.weapon && weaponObj.weapon.color) || weaponObj.color || '#fff';
339
  bullets.push({
@@ -378,7 +413,7 @@
378
  }
379
 
380
  // Interact: use medkit in selected slot OR loot chests / pickup items.
381
- // IMPORTANT: builds (objects) are NOT harvested via E anymore; only via pickaxe melee or shooting.
382
  function interactNearby(){
383
  // use medkit in selected slot
384
  const sel = player.selectedSlot;
@@ -658,8 +693,16 @@
658
 
659
  // Utility
660
  function updatePlayerCount(){
661
- const alive = enemies.filter(e => e.health > 0).length;
662
- document.getElementById('playerCount').textContent = `${1 + alive}/20`;
 
 
 
 
 
 
 
 
663
  }
664
 
665
  // Drawing (chests no text; glow; pickups visible)
@@ -925,6 +968,9 @@
925
  let gameActive = false;
926
 
927
  function startGame(){
 
 
 
928
  gameActive = true;
929
  landingScreen.classList.add('hidden');
930
  gameScreen.classList.remove('hidden');
@@ -968,6 +1014,8 @@
968
  function playerDeath(){ gameActive = false; deathScreen.classList.remove('hidden'); }
969
 
970
  document.getElementById('respawnBtn').addEventListener('click', ()=>{ deathScreen.classList.add('hidden'); landingScreen.classList.remove('hidden'); });
 
 
971
 
972
  document.querySelectorAll('.biome-selector').forEach(el => el.addEventListener('click', ()=> startGame()));
973
 
 
11
  #canvasContainer { position:relative; flex:1; display:flex; justify-content:center; align-items:center; height:100vh; overflow:hidden; }
12
  #gameCanvas { display:block; user-select:none; cursor:crosshair; box-shadow:0 0 20px rgba(0,0,0,.5); width:100%; height:100%; }
13
  #stormWarning { z-index:10; }
14
+ #deathScreen, #victoryScreen { z-index:20; }
15
 
16
  /* HUD */
17
  #hudHealth { position:absolute; left:12px; bottom:12px; background:rgba(0,0,0,0.55); padding:6px 8px; border-radius:8px; font-weight:700; font-size:13px; display:flex; align-items:center; gap:8px; z-index:30; }
 
63
  <li><strong>E</strong> — Use medkit in selected slot OR Interact / Loot</li>
64
  <li><strong>Q</strong> — Build (costs 10 materials)</li>
65
  <li><strong>R</strong> — Reload selected weapon</li>
66
+ <li><strong>1-5</strong> — Select inventory slot (also equips it)</li>
67
  <li><strong>F</strong> — Equip / Unequip selected slot (pickaxe is the default)</li>
68
  </ul>
69
  </div>
 
98
  </button>
99
  </div>
100
 
101
+ <div id="victoryScreen" class="hidden absolute inset-0 bg-black bg-opacity-80 flex flex-col items-center justify-center rounded-xl">
102
+ <h2 class="text-5xl font-bold text-green-400 mb-4">VICTORY</h2>
103
+ <p class="text-xl mb-6">You are the last player standing!</p>
104
+ <div class="flex gap-4">
105
+ <button id="goHomeBtn" class="bg-yellow-500 hover:bg-yellow-600 text-black font-bold py-3 px-6 rounded-lg flex items-center">
106
+ <i data-feather="home" class="mr-2"></i> Go to Home
107
+ </button>
108
+ <button id="continueBtn" class="bg-gray-700 hover:bg-gray-600 text-white font-bold py-3 px-6 rounded-lg flex items-center">
109
+ <i data-feather="repeat" class="mr-2"></i> Play Again
110
+ </button>
111
+ </div>
112
+ </div>
113
+
114
  <div id="hudHealth" class="hidden">
115
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#ffd86b" stroke-width="1.6"><path d="M20.8 8.6a5.5 5.5 0 0 0-7.8 0L12 10.6l-1-1a5.5 5.5 0 0 0-7.8 7.8l1 1L12 22l7.8-3.6 1-1a5.5 5.5 0 0 0 0-7.8z"></path></svg>
116
  <span id="hudHealthText">100%</span>
 
137
  const pickaxeSlot = document.getElementById('pickaxeSlot');
138
  const stormWarning = document.getElementById('stormWarning');
139
  const deathScreen = document.getElementById('deathScreen');
140
+ const victoryScreen = document.getElementById('victoryScreen');
141
+ const goHomeBtn = document.getElementById('goHomeBtn');
142
+ const continueBtn = document.getElementById('continueBtn');
143
 
144
  // World (bigger)
145
  const WORLD = { width: 6000, height: 4000 };
 
167
  const keys = { w:false,a:false,s:false,d:false,e:false,q:false,r:false,f:false };
168
  const mouse = { canvasX:0, canvasY:0, worldX:0, worldY:0, down:false };
169
 
170
+ // Helper: equip slot index (or -1 for pickaxe)
171
+ function equipSlot(index){
172
+ // index: -1 for pickaxe, 0-4 for inventory
173
+ player.equippedIndex = index;
174
+ // if equipping a slot that is empty, still equip it (shows nothing but slot is 'equipped')
175
+ updateHUD();
176
+ }
177
+
178
  window.addEventListener('keydown',(e)=>{
179
  const k = e.key.toLowerCase();
180
+
181
+ // Movement & action keys only processed when game active
182
  if (gameActive){
183
  if (k in keys) keys[k] = true;
184
+
185
  if (['1','2','3','4','5'].includes(k)) {
186
+ const idx = parseInt(k)-1;
187
+ player.selectedSlot = idx;
188
+ // Equip the pressed slot (this ensures weapons swap immediately)
189
+ equipSlot(idx);
 
190
  updateHUD();
191
  }
192
+
193
  if (k === 'f') {
194
+ // toggle between pickaxe and selected slot
195
+ if (player.equippedIndex === player.selectedSlot) equipSlot(-1);
196
+ else equipSlot(player.selectedSlot);
197
  updateHUD();
198
  }
199
+
200
  if (k === 'r') keys.r = true;
201
  } else {
202
+ // allow selection on landing screen
203
+ if (['1','2','3','4','5'].includes(k)) {
204
+ player.selectedSlot = parseInt(k)-1;
205
+ updateHUD();
206
+ }
207
  }
208
  });
209
+
210
  window.addEventListener('keyup',(e)=>{
211
  const k = e.key.toLowerCase();
212
  if (k in keys) keys[k] = false;
 
223
  player.angle = Math.atan2(mouse.worldY - player.y, mouse.worldX - player.x);
224
  });
225
  canvas.addEventListener('mousedown', (e)=>{
 
226
  const rect = canvas.getBoundingClientRect();
227
  mouse.canvasX = e.clientX - rect.left;
228
  mouse.canvasY = e.clientY - rect.top;
 
310
  slot.className = 'gear-slot';
311
  slot.dataset.index = i;
312
  slot.addEventListener('click', ()=> {
313
+ const idx = parseInt(slot.dataset.index);
314
+ player.selectedSlot = idx;
315
+ // if clicking currently equipped slot -> toggle unequip to pickaxe
316
+ if (player.equippedIndex === idx) equipSlot(-1);
317
+ else equipSlot(idx);
318
  updateHUD();
319
  });
320
  hudGear.appendChild(slot);
321
  }
322
  // pickaxe click toggles equip (explicit: clicking pickaxe equips/unequips it)
323
  pickaxeSlot.onclick = () => {
324
+ if (player.equippedIndex === -1) {
325
+ // pickaxe already equipped -> equip selected slot instead
326
+ equipSlot(player.selectedSlot);
327
+ } else {
328
+ equipSlot(-1);
329
+ }
330
  updateHUD();
331
  };
332
  updateHUD();
 
369
  const angle = Math.atan2(targetY-originY, targetX-originX);
370
  // decrement ammo if present
371
  if (typeof weaponObj.ammoInMag === 'number') weaponObj.ammoInMag -= 1;
 
372
  const dmg = weaponObj.weapon && weaponObj.weapon.dmg ? weaponObj.weapon.dmg : (weaponObj.dmg || 10);
373
  const color = (weaponObj.weapon && weaponObj.weapon.color) || weaponObj.color || '#fff';
374
  bullets.push({
 
413
  }
414
 
415
  // Interact: use medkit in selected slot OR loot chests / pickup items.
416
+ // Builds (objects) are NOT harvested via E anymore; only via pickaxe melee or shooting.
417
  function interactNearby(){
418
  // use medkit in selected slot
419
  const sel = player.selectedSlot;
 
693
 
694
  // Utility
695
  function updatePlayerCount(){
696
+ const aliveEnemies = enemies.filter(e => e.health > 0).length;
697
+ document.getElementById('playerCount').textContent = `${1 + aliveEnemies}/20`;
698
+
699
+ // Victory check: if all enemies dead and player alive & game active -> show victory
700
+ if (gameActive && aliveEnemies === 0 && player.health > 0){
701
+ // stop game loop and show victory UI
702
+ gameActive = false;
703
+ victoryScreen.classList.remove('hidden');
704
+ clearInterval(timerInterval);
705
+ }
706
  }
707
 
708
  // Drawing (chests no text; glow; pickups visible)
 
968
  let gameActive = false;
969
 
970
  function startGame(){
971
+ victoryScreen.classList.add('hidden');
972
+ deathScreen.classList.add('hidden');
973
+
974
  gameActive = true;
975
  landingScreen.classList.add('hidden');
976
  gameScreen.classList.remove('hidden');
 
1014
  function playerDeath(){ gameActive = false; deathScreen.classList.remove('hidden'); }
1015
 
1016
  document.getElementById('respawnBtn').addEventListener('click', ()=>{ deathScreen.classList.add('hidden'); landingScreen.classList.remove('hidden'); });
1017
+ goHomeBtn.addEventListener('click', ()=>{ victoryScreen.classList.add('hidden'); gameScreen.classList.add('hidden'); landingScreen.classList.remove('hidden'); });
1018
+ continueBtn.addEventListener('click', ()=>{ victoryScreen.classList.add('hidden'); startGame(); });
1019
 
1020
  document.querySelectorAll('.biome-selector').forEach(el => el.addEventListener('click', ()=> startGame()));
1021