MaxHeadspace commited on
Commit
dfb414e
·
verified ·
1 Parent(s): 59a9824

lastly make a crazy 8-bit like minecraft 3d graphices that is a house and frot and back yard and you have a chain saw and you have to find all the kids in the house and saw them... then you can hide and wait for the rescue and po po to show up and you keep sawing them till uyou die lol like youre jason but a chain saw - Initial Deployment

Browse files
Files changed (2) hide show
  1. README.md +6 -4
  2. index.html +697 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Chainsaw Massacre 2d
3
- emoji: 🏆
4
  colorFrom: blue
5
- colorTo: yellow
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: chainsaw-massacre-2d
3
+ emoji: 🐳
4
  colorFrom: blue
5
+ colorTo: green
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,697 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Chainsaw Massacre: 8-Bit Horror</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <style>
9
+ body {
10
+ margin: 0;
11
+ overflow: hidden;
12
+ background-color: #111;
13
+ font-family: 'Press Start 2P', cursive;
14
+ }
15
+ canvas {
16
+ display: block;
17
+ }
18
+ #ui {
19
+ position: absolute;
20
+ top: 0;
21
+ left: 0;
22
+ width: 100%;
23
+ color: white;
24
+ text-shadow: 2px 2px 0 #000;
25
+ pointer-events: none;
26
+ }
27
+ #health-bar {
28
+ width: 200px;
29
+ height: 20px;
30
+ border: 3px solid white;
31
+ margin: 10px;
32
+ }
33
+ #health-fill {
34
+ height: 100%;
35
+ width: 100%;
36
+ background-color: red;
37
+ transition: width 0.3s;
38
+ }
39
+ #game-over {
40
+ display: none;
41
+ position: absolute;
42
+ top: 50%;
43
+ left: 50%;
44
+ transform: translate(-50%, -50%);
45
+ background-color: rgba(0, 0, 0, 0.8);
46
+ padding: 20px;
47
+ border: 5px solid red;
48
+ text-align: center;
49
+ }
50
+ #start-screen {
51
+ position: absolute;
52
+ top: 0;
53
+ left: 0;
54
+ width: 100%;
55
+ height: 100%;
56
+ background-color: #000;
57
+ display: flex;
58
+ flex-direction: column;
59
+ justify-content: center;
60
+ align-items: center;
61
+ color: white;
62
+ z-index: 100;
63
+ }
64
+ @font-face {
65
+ font-family: 'Press Start 2P';
66
+ src: url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
67
+ }
68
+ .pixel-text {
69
+ font-family: 'Press Start 2P', cursive;
70
+ }
71
+ .blood-particle {
72
+ position: absolute;
73
+ width: 5px;
74
+ height: 5px;
75
+ background-color: red;
76
+ border-radius: 50%;
77
+ pointer-events: none;
78
+ }
79
+ </style>
80
+ </head>
81
+ <body>
82
+ <div id="start-screen" class="pixel-text">
83
+ <h1 class="text-4xl mb-8 text-red-600">CHAINSAW MASSACRE</h1>
84
+ <p class="mb-4 text-yellow-400">8-BIT HORROR</p>
85
+ <p class="mb-8 text-green-400">Find and eliminate all targets</p>
86
+ <button id="start-btn" class="bg-red-600 hover:bg-red-700 text-white px-8 py-4 rounded-lg text-xl transition-all hover:scale-110">
87
+ START GAME
88
+ </button>
89
+ <div class="mt-12 text-xs text-gray-400">
90
+ <p>WASD to move | SPACE to attack | SHIFT to run</p>
91
+ <p>Left click to chainsaw | Right click to hide</p>
92
+ </div>
93
+ </div>
94
+
95
+ <div id="ui" class="pixel-text">
96
+ <div class="flex justify-between items-center p-4">
97
+ <div>
98
+ <div id="health-bar">
99
+ <div id="health-fill"></div>
100
+ </div>
101
+ <div id="score" class="mt-2">KILLS: 0</div>
102
+ </div>
103
+ <div id="phase" class="text-xl">PHASE 1: HUNT KIDS</div>
104
+ <div id="timer" class="text-xl">TIME: 00:00</div>
105
+ </div>
106
+ </div>
107
+
108
+ <div id="game-over" class="pixel-text">
109
+ <h1 class="text-4xl text-red-600 mb-4">GAME OVER</h1>
110
+ <p id="final-score" class="text-2xl mb-8">You killed 0 victims</p>
111
+ <button id="restart-btn" class="bg-red-600 hover:bg-red-700 text-white px-8 py-4 rounded-lg text-xl">
112
+ PLAY AGAIN
113
+ </button>
114
+ </div>
115
+
116
+ <canvas id="gameCanvas"></canvas>
117
+
118
+ <script>
119
+ // Game setup
120
+ const canvas = document.getElementById('gameCanvas');
121
+ const ctx = canvas.getContext('2d');
122
+ const startScreen = document.getElementById('start-screen');
123
+ const startBtn = document.getElementById('start-btn');
124
+ const gameOverScreen = document.getElementById('game-over');
125
+ const restartBtn = document.getElementById('restart-btn');
126
+ const healthFill = document.getElementById('health-fill');
127
+ const scoreDisplay = document.getElementById('score');
128
+ const phaseDisplay = document.getElementById('phase');
129
+ const timerDisplay = document.getElementById('timer');
130
+ const finalScoreDisplay = document.getElementById('final-score');
131
+
132
+ // Set canvas size
133
+ canvas.width = window.innerWidth;
134
+ canvas.height = window.innerHeight;
135
+
136
+ // Game state
137
+ let gameRunning = false;
138
+ let score = 0;
139
+ let health = 100;
140
+ let gameTime = 0;
141
+ let gamePhase = 1; // 1 = hunt kids, 2 = hide, 3 = fight police
142
+ let timerInterval;
143
+
144
+ // Player
145
+ const player = {
146
+ x: canvas.width / 2,
147
+ y: canvas.height / 2,
148
+ size: 30,
149
+ speed: 3,
150
+ isAttacking: false,
151
+ isHiding: false,
152
+ direction: 0, // angle in radians
153
+ chainsawSound: new Audio('data:audio/wav;base64,UklGRl9vT19XQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YU...'), // placeholder
154
+ };
155
+
156
+ // Kids (victims)
157
+ let kids = [];
158
+ const KID_COUNT = 8;
159
+
160
+ // Police
161
+ let police = [];
162
+ const POLICE_COUNT = 5;
163
+
164
+ // House structure (simplified for 8-bit)
165
+ const house = {
166
+ walls: [
167
+ {x: 200, y: 200, width: 400, height: 300, color: '#8B4513'}, // main house
168
+ {x: 300, y: 150, width: 200, height: 50, color: '#A52A2A'}, // roof
169
+ {x: 600, y: 300, width: 100, height: 200, color: '#8B4513'}, // garage
170
+ {x: 200, y: 500, width: 200, height: 50, color: '#228B22'}, // front yard fence
171
+ {x: 400, y: 500, width: 300, height: 50, color: '#228B22'}, // front yard fence
172
+ ],
173
+ doors: [
174
+ {x: 350, y: 500, width: 50, height: 30, color: '#654321'}
175
+ ],
176
+ windows: [
177
+ {x: 250, y: 250, width: 50, height: 50, color: '#87CEEB'},
178
+ {x: 450, y: 250, width: 50, height: 50, color: '#87CEEB'},
179
+ {x: 620, y: 350, width: 50, height: 50, color: '#87CEEB'}
180
+ ]
181
+ };
182
+
183
+ // Trees in yard
184
+ const trees = [
185
+ {x: 100, y: 400, trunkWidth: 20, trunkHeight: 60, leavesWidth: 80, leavesHeight: 100},
186
+ {x: 700, y: 400, trunkWidth: 20, trunkHeight: 60, leavesWidth: 80, leavesHeight: 100},
187
+ {x: 150, y: 600, trunkWidth: 20, trunkHeight: 60, leavesWidth: 80, leavesHeight: 100},
188
+ {x: 650, y: 600, trunkWidth: 20, trunkHeight: 60, leavesWidth: 80, leavesHeight: 100}
189
+ ];
190
+
191
+ // Initialize game
192
+ function initGame() {
193
+ // Reset game state
194
+ gameRunning = true;
195
+ score = 0;
196
+ health = 100;
197
+ gameTime = 0;
198
+ gamePhase = 1;
199
+ kids = [];
200
+ police = [];
201
+
202
+ // Create kids
203
+ for (let i = 0; i < KID_COUNT; i++) {
204
+ kids.push({
205
+ x: Math.random() * (canvas.width - 100) + 50,
206
+ y: Math.random() * (canvas.height - 100) + 50,
207
+ size: 20,
208
+ speed: 1 + Math.random() * 1,
209
+ direction: Math.random() * Math.PI * 2,
210
+ changeDirectionTimer: 0,
211
+ isAlive: true,
212
+ screamSound: new Audio('data:audio/wav;base64,UklGRl9vT19XQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YU...') // placeholder
213
+ });
214
+ }
215
+
216
+ // Start timer
217
+ clearInterval(timerInterval);
218
+ timerInterval = setInterval(updateTimer, 1000);
219
+
220
+ // Hide start screen
221
+ startScreen.style.display = 'none';
222
+ gameOverScreen.style.display = 'none';
223
+
224
+ // Start game loop
225
+ requestAnimationFrame(gameLoop);
226
+ }
227
+
228
+ // Game loop
229
+ function gameLoop() {
230
+ if (!gameRunning) return;
231
+
232
+ // Clear canvas
233
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
234
+
235
+ // Update game state
236
+ updatePlayer();
237
+ updateKids();
238
+ if (gamePhase >= 3) updatePolice();
239
+
240
+ // Draw game world
241
+ drawWorld();
242
+
243
+ // Draw player
244
+ drawPlayer();
245
+
246
+ // Draw kids
247
+ drawKids();
248
+
249
+ // Draw police if phase 3
250
+ if (gamePhase >= 3) drawPolice();
251
+
252
+ // Check game phase transitions
253
+ checkPhaseTransitions();
254
+
255
+ // Check game over
256
+ if (health <= 0) {
257
+ gameOver();
258
+ return;
259
+ }
260
+
261
+ // Continue loop
262
+ requestAnimationFrame(gameLoop);
263
+ }
264
+
265
+ // Update player
266
+ function updatePlayer() {
267
+ // Movement
268
+ const moveX = (keys['d'] ? 1 : 0) - (keys['a'] ? 1 : 0);
269
+ const moveY = (keys['s'] ? 1 : 0) - (keys['w'] ? 1 : 0);
270
+
271
+ if (moveX !== 0 || moveY !== 0) {
272
+ player.direction = Math.atan2(moveY, moveX);
273
+ const speed = keys['Shift'] ? player.speed * 1.5 : player.speed;
274
+ player.x += Math.cos(player.direction) * speed;
275
+ player.y += Math.sin(player.direction) * speed;
276
+
277
+ // Boundary check
278
+ player.x = Math.max(player.size, Math.min(canvas.width - player.size, player.x));
279
+ player.y = Math.max(player.size, Math.min(canvas.height - player.size, player.y));
280
+ }
281
+
282
+ // Attacking
283
+ if (mouse.isAttacking && !player.isAttacking) {
284
+ player.isAttacking = true;
285
+ player.chainsawSound.play();
286
+
287
+ // Check for hits on kids or police
288
+ const targets = gamePhase >= 3 ? [...kids, ...police] : kids;
289
+ for (let target of targets) {
290
+ if (!target.isAlive) continue;
291
+
292
+ const dist = Math.sqrt(
293
+ Math.pow(target.x - player.x, 2) +
294
+ Math.pow(target.y - player.y, 2)
295
+ );
296
+
297
+ if (dist < player.size + target.size) {
298
+ // Hit!
299
+ target.isAlive = false;
300
+ score++;
301
+ scoreDisplay.textContent = `KILLS: ${score}`;
302
+
303
+ // Create blood particles
304
+ createBlood(target.x, target.y);
305
+
306
+ // Play scream sound
307
+ if (target.screamSound) target.screamSound.play();
308
+ }
309
+ }
310
+
311
+ setTimeout(() => {
312
+ player.isAttacking = false;
313
+ }, 500);
314
+ }
315
+
316
+ // Hiding
317
+ player.isHiding = mouse.isHiding;
318
+ }
319
+
320
+ // Update kids
321
+ function updateKids() {
322
+ for (let kid of kids) {
323
+ if (!kid.isAlive) continue;
324
+
325
+ // Random movement
326
+ kid.changeDirectionTimer--;
327
+ if (kid.changeDirectionTimer <= 0) {
328
+ kid.direction = Math.random() * Math.PI * 2;
329
+ kid.changeDirectionTimer = 30 + Math.random() * 60;
330
+ }
331
+
332
+ // Move
333
+ kid.x += Math.cos(kid.direction) * kid.speed;
334
+ kid.y += Math.sin(kid.direction) * kid.speed;
335
+
336
+ // Boundary check
337
+ kid.x = Math.max(kid.size, Math.min(canvas.width - kid.size, kid.x));
338
+ kid.y = Math.max(kid.size, Math.min(canvas.height - kid.size, kid.y));
339
+
340
+ // Run from player if close
341
+ const distToPlayer = Math.sqrt(
342
+ Math.pow(kid.x - player.x, 2) +
343
+ Math.pow(kid.y - player.y, 2)
344
+ );
345
+
346
+ if (distToPlayer < 200) {
347
+ // Run away
348
+ const angleAway = Math.atan2(kid.y - player.y, kid.x - player.x);
349
+ kid.x += Math.cos(angleAway) * kid.speed * 2;
350
+ kid.y += Math.sin(angleAway) * kid.speed * 2;
351
+ }
352
+ }
353
+ }
354
+
355
+ // Update police
356
+ function updatePolice() {
357
+ if (police.length === 0) {
358
+ // Spawn police
359
+ for (let i = 0; i < POLICE_COUNT; i++) {
360
+ police.push({
361
+ x: Math.random() * (canvas.width - 100) + 50,
362
+ y: Math.random() * (canvas.height - 100) + 50,
363
+ size: 25,
364
+ speed: 2 + Math.random() * 1,
365
+ direction: Math.random() * Math.PI * 2,
366
+ changeDirectionTimer: 0,
367
+ isAlive: true,
368
+ shootTimer: 0
369
+ });
370
+ }
371
+ }
372
+
373
+ for (let cop of police) {
374
+ if (!cop.isAlive) continue;
375
+
376
+ // Chase player
377
+ cop.direction = Math.atan2(player.y - cop.y, player.x - cop.x);
378
+ cop.x += Math.cos(cop.direction) * cop.speed;
379
+ cop.y += Math.sin(cop.direction) * cop.speed;
380
+
381
+ // Shoot at player periodically
382
+ cop.shootTimer--;
383
+ if (cop.shootTimer <= 0) {
384
+ cop.shootTimer = 60 + Math.random() * 60;
385
+
386
+ // Check if player is in line of sight
387
+ const distToPlayer = Math.sqrt(
388
+ Math.pow(player.x - cop.x, 2) +
389
+ Math.pow(player.y - cop.y, 2)
390
+ );
391
+
392
+ if (distToPlayer < 300 && !player.isHiding) {
393
+ // Player hit
394
+ health -= 10;
395
+ healthFill.style.width = `${health}%`;
396
+
397
+ // Create blood particles at player
398
+ createBlood(player.x, player.y);
399
+ }
400
+ }
401
+ }
402
+ }
403
+
404
+ // Draw world
405
+ function drawWorld() {
406
+ // Draw grass background
407
+ ctx.fillStyle = '#228B22';
408
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
409
+
410
+ // Draw house
411
+ for (let wall of house.walls) {
412
+ ctx.fillStyle = wall.color;
413
+ ctx.fillRect(wall.x, wall.y, wall.width, wall.height);
414
+ }
415
+
416
+ // Draw doors
417
+ for (let door of house.doors) {
418
+ ctx.fillStyle = door.color;
419
+ ctx.fillRect(door.x, door.y, door.width, door.height);
420
+ }
421
+
422
+ // Draw windows
423
+ for (let window of house.windows) {
424
+ ctx.fillStyle = window.color;
425
+ ctx.fillRect(window.x, window.y, window.width, window.height);
426
+ }
427
+
428
+ // Draw trees
429
+ for (let tree of trees) {
430
+ // Trunk
431
+ ctx.fillStyle = '#8B4513';
432
+ ctx.fillRect(
433
+ tree.x - tree.trunkWidth/2,
434
+ tree.y - tree.trunkHeight/2,
435
+ tree.trunkWidth,
436
+ tree.trunkHeight
437
+ );
438
+
439
+ // Leaves
440
+ ctx.fillStyle = '#006400';
441
+ ctx.beginPath();
442
+ ctx.ellipse(
443
+ tree.x,
444
+ tree.y - tree.leavesHeight/2,
445
+ tree.leavesWidth/2,
446
+ tree.leavesHeight/2,
447
+ 0, 0, Math.PI * 2
448
+ );
449
+ ctx.fill();
450
+ }
451
+ }
452
+
453
+ // Draw player
454
+ function drawPlayer() {
455
+ // Body
456
+ ctx.fillStyle = player.isHiding ? '#555' : '#333';
457
+ ctx.beginPath();
458
+ ctx.arc(player.x, player.y, player.size, 0, Math.PI * 2);
459
+ ctx.fill();
460
+
461
+ // Face (simple 8-bit style)
462
+ ctx.fillStyle = '#FFF';
463
+ ctx.beginPath();
464
+ ctx.arc(
465
+ player.x + Math.cos(player.direction) * player.size/2,
466
+ player.y + Math.sin(player.direction) * player.size/2,
467
+ player.size/4, 0, Math.PI * 2
468
+ );
469
+ ctx.fill();
470
+
471
+ // Chainsaw
472
+ if (player.isAttacking) {
473
+ ctx.fillStyle = '#FF0000';
474
+ ctx.beginPath();
475
+ ctx.arc(
476
+ player.x + Math.cos(player.direction) * player.size * 1.5,
477
+ player.y + Math.sin(player.direction) * player.size * 1.5,
478
+ player.size/2, 0, Math.PI * 2
479
+ );
480
+ ctx.fill();
481
+
482
+ // Blood spray
483
+ ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
484
+ ctx.beginPath();
485
+ ctx.moveTo(player.x, player.y);
486
+ ctx.lineTo(
487
+ player.x + Math.cos(player.direction) * player.size * 3,
488
+ player.y + Math.sin(player.direction) * player.size * 3
489
+ );
490
+ ctx.lineWidth = 10;
491
+ ctx.stroke();
492
+ }
493
+ }
494
+
495
+ // Draw kids
496
+ function drawKids() {
497
+ for (let kid of kids) {
498
+ if (!kid.isAlive) continue;
499
+
500
+ // Body
501
+ ctx.fillStyle = '#FF69B4';
502
+ ctx.beginPath();
503
+ ctx.arc(kid.x, kid.y, kid.size, 0, Math.PI * 2);
504
+ ctx.fill();
505
+
506
+ // Face
507
+ ctx.fillStyle = '#FFF';
508
+ ctx.beginPath();
509
+ ctx.arc(kid.x, kid.y - kid.size/3, kid.size/3, 0, Math.PI * 2);
510
+ ctx.fill();
511
+
512
+ // Scream mouth if running
513
+ const distToPlayer = Math.sqrt(
514
+ Math.pow(kid.x - player.x, 2) +
515
+ Math.pow(kid.y - player.y, 2)
516
+ );
517
+
518
+ if (distToPlayer < 200) {
519
+ ctx.fillStyle = '#FF0000';
520
+ ctx.beginPath();
521
+ ctx.arc(kid.x, kid.y - kid.size/3, kid.size/5, 0, Math.PI * 2);
522
+ ctx.fill();
523
+ }
524
+ }
525
+ }
526
+
527
+ // Draw police
528
+ function drawPolice() {
529
+ for (let cop of police) {
530
+ if (!cop.isAlive) continue;
531
+
532
+ // Body
533
+ ctx.fillStyle = '#0000FF';
534
+ ctx.beginPath();
535
+ ctx.arc(cop.x, cop.y, cop.size, 0, Math.PI * 2);
536
+ ctx.fill();
537
+
538
+ // Face
539
+ ctx.fillStyle = '#FFF';
540
+ ctx.beginPath();
541
+ ctx.arc(cop.x, cop.y - cop.size/3, cop.size/3, 0, Math.PI * 2);
542
+ ctx.fill();
543
+
544
+ // Badge
545
+ ctx.fillStyle = '#FFD700';
546
+ ctx.beginPath();
547
+ ctx.arc(cop.x, cop.y, cop.size/3, 0, Math.PI * 2);
548
+ ctx.fill();
549
+
550
+ // Gun if shooting
551
+ if (cop.shootTimer > 50) {
552
+ ctx.strokeStyle = '#000';
553
+ ctx.lineWidth = 3;
554
+ ctx.beginPath();
555
+ ctx.moveTo(cop.x, cop.y);
556
+ ctx.lineTo(
557
+ cop.x + Math.cos(cop.direction) * cop.size * 2,
558
+ cop.y + Math.sin(cop.direction) * cop.size * 2
559
+ );
560
+ ctx.stroke();
561
+ }
562
+ }
563
+ }
564
+
565
+ // Create blood particles
566
+ function createBlood(x, y) {
567
+ for (let i = 0; i < 10; i++) {
568
+ const particle = document.createElement('div');
569
+ particle.className = 'blood-particle';
570
+ particle.style.left = `${x + (Math.random() * 20 - 10)}px`;
571
+ particle.style.top = `${y + (Math.random() * 20 - 10)}px`;
572
+ document.body.appendChild(particle);
573
+
574
+ // Animate
575
+ const angle = Math.random() * Math.PI * 2;
576
+ const distance = 10 + Math.random() * 40;
577
+ const duration = 300 + Math.random() * 700;
578
+
579
+ particle.animate([
580
+ {
581
+ transform: `translate(0, 0)`,
582
+ opacity: 1
583
+ },
584
+ {
585
+ transform: `translate(${Math.cos(angle) * distance}px, ${Math.sin(angle) * distance}px)`,
586
+ opacity: 0
587
+ }
588
+ ], {
589
+ duration: duration,
590
+ easing: 'cubic-bezier(0.1, 0.8, 0.2, 1)'
591
+ });
592
+
593
+ // Remove after animation
594
+ setTimeout(() => {
595
+ particle.remove();
596
+ }, duration);
597
+ }
598
+ }
599
+
600
+ // Check phase transitions
601
+ function checkPhaseTransitions() {
602
+ // Phase 1 to 2: when all kids are dead
603
+ if (gamePhase === 1) {
604
+ const aliveKids = kids.filter(kid => kid.isAlive).length;
605
+ if (aliveKids === 0) {
606
+ gamePhase = 2;
607
+ phaseDisplay.textContent = 'PHASE 2: HIDE AND WAIT';
608
+
609
+ // Timer for police arrival
610
+ setTimeout(() => {
611
+ gamePhase = 3;
612
+ phaseDisplay.textContent = 'PHASE 3: FIGHT POLICE';
613
+ }, 10000); // 10 seconds
614
+ }
615
+ }
616
+ }
617
+
618
+ // Update timer
619
+ function updateTimer() {
620
+ gameTime++;
621
+ const minutes = Math.floor(gameTime / 60).toString().padStart(2, '0');
622
+ const seconds = (gameTime % 60).toString().padStart(2, '0');
623
+ timerDisplay.textContent = `TIME: ${minutes}:${seconds}`;
624
+ }
625
+
626
+ // Game over
627
+ function gameOver() {
628
+ gameRunning = false;
629
+ clearInterval(timerInterval);
630
+
631
+ // Show game over screen
632
+ finalScoreDisplay.textContent = `You killed ${score} victims`;
633
+ gameOverScreen.style.display = 'block';
634
+ }
635
+
636
+ // Input handling
637
+ const keys = {};
638
+ const mouse = {
639
+ x: 0,
640
+ y: 0,
641
+ isAttacking: false,
642
+ isHiding: false
643
+ };
644
+
645
+ window.addEventListener('keydown', (e) => {
646
+ keys[e.key.toLowerCase()] = true;
647
+ });
648
+
649
+ window.addEventListener('keyup', (e) => {
650
+ keys[e.key.toLowerCase()] = false;
651
+ });
652
+
653
+ canvas.addEventListener('mousemove', (e) => {
654
+ mouse.x = e.clientX;
655
+ mouse.y = e.clientY;
656
+
657
+ // Update player direction to face mouse
658
+ player.direction = Math.atan2(
659
+ e.clientY - player.y,
660
+ e.clientX - player.x
661
+ );
662
+ });
663
+
664
+ canvas.addEventListener('mousedown', (e) => {
665
+ if (e.button === 0) { // Left click
666
+ mouse.isAttacking = true;
667
+ } else if (e.button === 2) { // Right click
668
+ mouse.isHiding = true;
669
+ }
670
+ });
671
+
672
+ canvas.addEventListener('mouseup', (e) => {
673
+ if (e.button === 0) {
674
+ mouse.isAttacking = false;
675
+ } else if (e.button === 2) {
676
+ mouse.isHiding = false;
677
+ }
678
+ });
679
+
680
+ canvas.addEventListener('contextmenu', (e) => {
681
+ e.preventDefault(); // Prevent right-click menu
682
+ });
683
+
684
+ // Window resize
685
+ window.addEventListener('resize', () => {
686
+ canvas.width = window.innerWidth;
687
+ canvas.height = window.innerHeight;
688
+ });
689
+
690
+ // Start button
691
+ startBtn.addEventListener('click', initGame);
692
+
693
+ // Restart button
694
+ restartBtn.addEventListener('click', initGame);
695
+ </script>
696
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=MaxHeadspace/chainsaw-massacre-2d" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
697
+ </html>