pijou commited on
Commit
762708f
·
verified ·
1 Parent(s): de0c171

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +871 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Newlll
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: newlll
3
+ emoji: 🐳
4
+ colorFrom: green
5
+ colorTo: gray
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,871 @@
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>Raccoon Rumble</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.min.js"></script>
9
+ <style>
10
+ @font-face {
11
+ font-family: 'PressStart2P';
12
+ src: url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
13
+ }
14
+
15
+ body {
16
+ margin: 0;
17
+ padding: 0;
18
+ overflow: hidden;
19
+ background-color: #111;
20
+ font-family: 'PressStart2P', cursive;
21
+ }
22
+
23
+ #game-container {
24
+ position: relative;
25
+ width: 100vw;
26
+ height: 100vh;
27
+ display: flex;
28
+ justify-content: center;
29
+ align-items: center;
30
+ }
31
+
32
+ #game-canvas {
33
+ display: block;
34
+ margin: 0 auto;
35
+ background-color: #000;
36
+ }
37
+
38
+ .health-bar {
39
+ height: 30px;
40
+ transition: width 0.3s ease;
41
+ }
42
+
43
+ .combo-text {
44
+ position: absolute;
45
+ color: #ff0;
46
+ font-size: 24px;
47
+ text-shadow: 0 0 10px #f80;
48
+ animation: pop 0.5s ease-out;
49
+ }
50
+
51
+ @keyframes pop {
52
+ 0% { transform: scale(0.5); opacity: 0; }
53
+ 80% { transform: scale(1.2); opacity: 1; }
54
+ 100% { transform: scale(1); opacity: 1; }
55
+ }
56
+
57
+ .menu-screen {
58
+ position: absolute;
59
+ top: 0;
60
+ left: 0;
61
+ width: 100%;
62
+ height: 100%;
63
+ background-color: rgba(0, 0, 0, 0.8);
64
+ display: flex;
65
+ flex-direction: column;
66
+ justify-content: center;
67
+ align-items: center;
68
+ z-index: 100;
69
+ color: white;
70
+ }
71
+
72
+ .menu-title {
73
+ font-size: 48px;
74
+ color: #ff9500;
75
+ margin-bottom: 40px;
76
+ text-shadow: 0 0 10px #ff0;
77
+ }
78
+
79
+ .menu-button {
80
+ background-color: #ff9500;
81
+ color: #000;
82
+ border: none;
83
+ padding: 15px 30px;
84
+ margin: 10px;
85
+ font-size: 20px;
86
+ cursor: pointer;
87
+ border-radius: 5px;
88
+ transition: all 0.3s;
89
+ font-family: 'PressStart2P', cursive;
90
+ }
91
+
92
+ .menu-button:hover {
93
+ background-color: #ff0;
94
+ transform: scale(1.05);
95
+ }
96
+
97
+ .controls-display {
98
+ background-color: rgba(0, 0, 0, 0.7);
99
+ padding: 20px;
100
+ border-radius: 10px;
101
+ margin-top: 30px;
102
+ max-width: 600px;
103
+ }
104
+
105
+ .control-item {
106
+ display: flex;
107
+ align-items: center;
108
+ margin: 10px 0;
109
+ }
110
+
111
+ .key {
112
+ background-color: #333;
113
+ color: white;
114
+ padding: 5px 10px;
115
+ margin-right: 15px;
116
+ border-radius: 5px;
117
+ min-width: 40px;
118
+ text-align: center;
119
+ }
120
+ </style>
121
+ </head>
122
+ <body>
123
+ <div id="game-container">
124
+ <div id="game-canvas"></div>
125
+
126
+ <!-- Main Menu -->
127
+ <div id="main-menu" class="menu-screen">
128
+ <h1 class="menu-title">RACCOON RUMBLE</h1>
129
+ <button id="start-button" class="menu-button">START GAME</button>
130
+ <button id="controls-button" class="menu-button">CONTROLS</button>
131
+
132
+ <div class="mt-8 text-center">
133
+ <p>Player 1: WASD + JKL</p>
134
+ <p>Player 2: Arrow Keys + Numpad 1-3</p>
135
+ <p>Or connect a gamepad!</p>
136
+ </div>
137
+ </div>
138
+
139
+ <!-- Controls Screen -->
140
+ <div id="controls-screen" class="menu-screen" style="display: none;">
141
+ <h1 class="menu-title">CONTROLS</h1>
142
+
143
+ <div class="controls-display">
144
+ <h2 class="text-xl mb-4 text-center">Player 1 (Keyboard)</h2>
145
+ <div class="control-item">
146
+ <div class="key">W</div>
147
+ <span>Jump</span>
148
+ </div>
149
+ <div class="control-item">
150
+ <div class="key">A</div>
151
+ <span>Move Left</span>
152
+ </div>
153
+ <div class="control-item">
154
+ <div class="key">D</div>
155
+ <span>Move Right</span>
156
+ </div>
157
+ <div class="control-item">
158
+ <div class="key">J</div>
159
+ <span>Light Attack</span>
160
+ </div>
161
+ <div class="control-item">
162
+ <div class="key">K</div>
163
+ <span>Heavy Attack</span>
164
+ </div>
165
+ <div class="control-item">
166
+ <div class="key">L</div>
167
+ <span>Special Attack</span>
168
+ </div>
169
+
170
+ <h2 class="text-xl mt-8 mb-4 text-center">Player 2 (Keyboard)</h2>
171
+ <div class="control-item">
172
+ <div class="key">↑</div>
173
+ <span>Jump</span>
174
+ </div>
175
+ <div class="control-item">
176
+ <div class="key">←</div>
177
+ <span>Move Left</span>
178
+ </div>
179
+ <div class="control-item">
180
+ <div class="key">→</div>
181
+ <span>Move Right</span>
182
+ </div>
183
+ <div class="control-item">
184
+ <div class="key">Num 1</div>
185
+ <span>Light Attack</span>
186
+ </div>
187
+ <div class="control-item">
188
+ <div class="key">Num 2</div>
189
+ <span>Heavy Attack</span>
190
+ </div>
191
+ <div class="control-item">
192
+ <div class="key">Num 3</div>
193
+ <span>Special Attack</span>
194
+ </div>
195
+
196
+ <p class="mt-8 text-center">Gamepads: Use left stick/d-pad to move and face buttons for attacks</p>
197
+ </div>
198
+
199
+ <button id="back-button" class="menu-button mt-8">BACK TO MENU</button>
200
+ </div>
201
+
202
+ <!-- Game Over Screen -->
203
+ <div id="game-over-screen" class="menu-screen" style="display: none;">
204
+ <h1 id="winner-text" class="menu-title">PLAYER 1 WINS!</h1>
205
+ <button id="rematch-button" class="menu-button">REMATCH</button>
206
+ <button id="menu-button" class="menu-button">MAIN MENU</button>
207
+ </div>
208
+ </div>
209
+
210
+ <script>
211
+ // Game configuration
212
+ const config = {
213
+ type: Phaser.AUTO,
214
+ width: 1024,
215
+ height: 576,
216
+ physics: {
217
+ default: 'arcade',
218
+ arcade: {
219
+ gravity: { y: 800 },
220
+ debug: false
221
+ }
222
+ },
223
+ scene: {
224
+ preload: preload,
225
+ create: create,
226
+ update: update
227
+ },
228
+ parent: 'game-container',
229
+ canvas: document.getElementById('game-canvas')
230
+ };
231
+
232
+ // Game variables
233
+ let game = new Phaser.Game(config);
234
+ let player1, player2;
235
+ let platforms;
236
+ let cursors, p2Cursors;
237
+ let gamepads = [];
238
+ let comboCount = 0;
239
+ let lastHitTime = 0;
240
+ let comboTexts = [];
241
+ let background;
242
+ let hitSound, jumpSound, specialSound, backgroundMusic;
243
+ let gameState = 'menu'; // menu, playing, gameover
244
+
245
+ // Raccoon character class
246
+ class Raccoon extends Phaser.Physics.Arcade.Sprite {
247
+ constructor(scene, x, y, isPlayer1) {
248
+ super(scene, x, y, 'raccoon');
249
+ this.isPlayer1 = isPlayer1;
250
+ this.health = 100;
251
+ this.maxHealth = 100;
252
+ this.isAttacking = false;
253
+ this.isBlocking = false;
254
+ this.isJumping = false;
255
+ this.isSpecial = false;
256
+ this.comboCount = 0;
257
+ this.lastHitTime = 0;
258
+ this.facingRight = isPlayer1;
259
+ this.specialMeter = 0;
260
+ this.maxSpecialMeter = 100;
261
+ this.invulnerable = false;
262
+
263
+ scene.add.existing(this);
264
+ scene.physics.add.existing(this);
265
+
266
+ this.setCollideWorldBounds(true);
267
+ this.setBounce(0.2);
268
+ this.setDragX(400);
269
+ this.setSize(60, 90);
270
+ this.setOffset(35, 30);
271
+
272
+ // Create animations
273
+ this.createAnimations();
274
+
275
+ // Set up attack hitboxes
276
+ this.attackHitbox = scene.add.zone(0, 0, 80, 80);
277
+ scene.physics.add.existing(this.attackHitbox);
278
+ this.attackHitbox.body.enable = false;
279
+
280
+ // Health bar
281
+ this.healthBar = scene.add.rectangle(
282
+ isPlayer1 ? 100 : config.width - 100,
283
+ 50,
284
+ this.health * 2,
285
+ 20,
286
+ isPlayer1 ? 0x00ff00 : 0xff0000
287
+ );
288
+ this.healthBar.setOrigin(isPlayer1 ? 0 : 1, 0.5);
289
+
290
+ // Special meter
291
+ this.specialMeterBar = scene.add.rectangle(
292
+ isPlayer1 ? 100 : config.width - 100,
293
+ 80,
294
+ 0,
295
+ 10,
296
+ 0x00aaff
297
+ );
298
+ this.specialMeterBar.setOrigin(isPlayer1 ? 0 : 1, 0.5);
299
+
300
+ // Player indicator
301
+ this.playerIndicator = scene.add.text(
302
+ isPlayer1 ? 20 : config.width - 20,
303
+ 50,
304
+ isPlayer1 ? 'P1' : 'P2',
305
+ {
306
+ fontSize: '24px',
307
+ fill: isPlayer1 ? '#00ff00' : '#ff0000',
308
+ fontFamily: 'PressStart2P'
309
+ }
310
+ );
311
+ this.playerIndicator.setOrigin(isPlayer1 ? 0 : 1, 0.5);
312
+ }
313
+
314
+ createAnimations() {
315
+ const anims = this.scene.anims;
316
+
317
+ // Idle animation
318
+ anims.create({
319
+ key: `idle-${this.isPlayer1 ? 'p1' : 'p2'}`,
320
+ frames: anims.generateFrameNumbers('raccoon', { start: 0, end: 3 }),
321
+ frameRate: 8,
322
+ repeat: -1
323
+ });
324
+
325
+ // Walk animation
326
+ anims.create({
327
+ key: `walk-${this.isPlayer1 ? 'p1' : 'p2'}`,
328
+ frames: anims.generateFrameNumbers('raccoon', { start: 4, end: 7 }),
329
+ frameRate: 12,
330
+ repeat: -1
331
+ });
332
+
333
+ // Jump animation
334
+ anims.create({
335
+ key: `jump-${this.isPlayer1 ? 'p1' : 'p2'}`,
336
+ frames: anims.generateFrameNumbers('raccoon', { start: 8, end: 11 }),
337
+ frameRate: 8,
338
+ repeat: 0
339
+ });
340
+
341
+ // Light attack animation
342
+ anims.create({
343
+ key: `light-attack-${this.isPlayer1 ? 'p1' : 'p2'}`,
344
+ frames: anims.generateFrameNumbers('raccoon', { start: 12, end: 15 }),
345
+ frameRate: 12,
346
+ repeat: 0
347
+ });
348
+
349
+ // Heavy attack animation
350
+ anims.create({
351
+ key: `heavy-attack-${this.isPlayer1 ? 'p1' : 'p2'}`,
352
+ frames: anims.generateFrameNumbers('raccoon', { start: 16, end: 19 }),
353
+ frameRate: 10,
354
+ repeat: 0
355
+ });
356
+
357
+ // Special attack animation
358
+ anims.create({
359
+ key: `special-attack-${this.isPlayer1 ? 'p1' : 'p2'}`,
360
+ frames: anims.generateFrameNumbers('raccoon', { start: 20, end: 23 }),
361
+ frameRate: 8,
362
+ repeat: 0
363
+ });
364
+
365
+ // Hit animation
366
+ anims.create({
367
+ key: `hit-${this.isPlayer1 ? 'p1' : 'p2'}`,
368
+ frames: anims.generateFrameNumbers('raccoon', { start: 24, end: 27 }),
369
+ frameRate: 10,
370
+ repeat: 0
371
+ });
372
+
373
+ // Block animation
374
+ anims.create({
375
+ key: `block-${this.isPlayer1 ? 'p1' : 'p2'}`,
376
+ frames: anims.generateFrameNumbers('raccoon', { start: 28, end: 31 }),
377
+ frameRate: 8,
378
+ repeat: 0
379
+ });
380
+ }
381
+
382
+ update(cursors, gamepad) {
383
+ if (this.health <= 0) return;
384
+
385
+ // Update health bar
386
+ this.healthBar.width = (this.health / this.maxHealth) * 200;
387
+
388
+ // Update special meter
389
+ this.specialMeterBar.width = (this.specialMeter / this.maxSpecialMeter) * 200;
390
+
391
+ // Handle movement
392
+ if (!this.isAttacking && !this.isBlocking) {
393
+ let moveX = 0;
394
+
395
+ // Keyboard controls
396
+ if (cursors) {
397
+ if (cursors.left.isDown) {
398
+ moveX = -1;
399
+ this.facingRight = false;
400
+ } else if (cursors.right.isDown) {
401
+ moveX = 1;
402
+ this.facingRight = true;
403
+ }
404
+
405
+ if (cursors.up.isDown && this.body.onFloor()) {
406
+ this.jump();
407
+ }
408
+ }
409
+
410
+ // Gamepad controls
411
+ if (gamepad) {
412
+ if (gamepad.axes[0] < -0.5 || gamepad.buttons[14].pressed) {
413
+ moveX = -1;
414
+ this.facingRight = false;
415
+ } else if (gamepad.axes[0] > 0.5 || gamepad.buttons[15].pressed) {
416
+ moveX = 1;
417
+ this.facingRight = true;
418
+ }
419
+
420
+ if ((gamepad.buttons[0].pressed || gamepad.buttons[12].pressed) && this.body.onFloor()) {
421
+ this.jump();
422
+ }
423
+ }
424
+
425
+ this.setVelocityX(moveX * 200);
426
+
427
+ // Play animations based on state
428
+ if (this.body.onFloor()) {
429
+ if (moveX !== 0) {
430
+ this.play(`walk-${this.isPlayer1 ? 'p1' : 'p2'}`, true);
431
+ } else {
432
+ this.play(`idle-${this.isPlayer1 ? 'p1' : 'p2'}`, true);
433
+ }
434
+ }
435
+ }
436
+
437
+ // Flip sprite based on facing direction
438
+ this.flipX = !this.facingRight;
439
+
440
+ // Position attack hitbox
441
+ this.positionAttackHitbox();
442
+
443
+ // Handle attacks
444
+ if (!this.isAttacking && !this.isBlocking) {
445
+ // Keyboard attacks
446
+ if (cursors) {
447
+ if (cursors.lightAttack.isDown) {
448
+ this.lightAttack();
449
+ } else if (cursors.heavyAttack.isDown) {
450
+ this.heavyAttack();
451
+ } else if (cursors.specialAttack.isDown && this.specialMeter >= this.maxSpecialMeter) {
452
+ this.specialAttack();
453
+ }
454
+ }
455
+
456
+ // Gamepad attacks
457
+ if (gamepad) {
458
+ if (gamepad.buttons[2].pressed) {
459
+ this.lightAttack();
460
+ } else if (gamepad.buttons[1].pressed) {
461
+ this.heavyAttack();
462
+ } else if (gamepad.buttons[3].pressed && this.specialMeter >= this.maxSpecialMeter) {
463
+ this.specialAttack();
464
+ }
465
+ }
466
+ }
467
+
468
+ // Handle blocking
469
+ if (!this.isAttacking) {
470
+ let isBlocking = false;
471
+
472
+ // Keyboard blocking
473
+ if (cursors && cursors.down.isDown && !this.body.onFloor()) {
474
+ isBlocking = true;
475
+ }
476
+
477
+ // Gamepad blocking
478
+ if (gamepad && (gamepad.buttons[8].pressed || gamepad.buttons[9].pressed)) {
479
+ isBlocking = true;
480
+ }
481
+
482
+ if (isBlocking && !this.isBlocking) {
483
+ this.block();
484
+ } else if (!isBlocking && this.isBlocking) {
485
+ this.releaseBlock();
486
+ }
487
+ }
488
+
489
+ // Update special meter (gain over time)
490
+ if (this.specialMeter < this.maxSpecialMeter) {
491
+ this.specialMeter += 0.1;
492
+ if (this.specialMeter > this.maxSpecialMeter) {
493
+ this.specialMeter = this.maxSpecialMeter;
494
+ }
495
+ }
496
+ }
497
+
498
+ positionAttackHitbox() {
499
+ if (!this.attackHitbox) return;
500
+
501
+ const offsetX = this.facingRight ? 50 : -50;
502
+ this.attackHitbox.x = this.x + offsetX;
503
+ this.attackHitbox.y = this.y - 20;
504
+ }
505
+
506
+ jump() {
507
+ if (this.body.onFloor()) {
508
+ this.setVelocityY(-500);
509
+ this.play(`jump-${this.isPlayer1 ? 'p1' : 'p2'}`, true);
510
+ this.isJumping = true;
511
+ jumpSound.play();
512
+
513
+ this.scene.time.delayedCall(1000, () => {
514
+ this.isJumping = false;
515
+ });
516
+ }
517
+ }
518
+
519
+ lightAttack() {
520
+ this.isAttacking = true;
521
+ this.play(`light-attack-${this.isPlayer1 ? 'p1' : 'p2'}`, true);
522
+ hitSound.play();
523
+
524
+ // Enable hitbox
525
+ this.attackHitbox.body.enable = true;
526
+ this.attackHitbox.body.setSize(80, 80);
527
+
528
+ // Check for hits
529
+ this.scene.physics.overlap(this.attackHitbox, this.isPlayer1 ? player2 : player1, this.handleHit.bind(this, 10, 'light'));
530
+
531
+ // Disable hitbox after animation
532
+ this.scene.time.delayedCall(300, () => {
533
+ this.attackHitbox.body.enable = false;
534
+ this.isAttacking = false;
535
+ });
536
+ }
537
+
538
+ heavyAttack() {
539
+ this.isAttacking = true;
540
+ this.play(`heavy-attack-${this.isPlayer1 ? 'p1' : 'p2'}`, true);
541
+ hitSound.play({ volume: 0.8 });
542
+
543
+ // Enable hitbox
544
+ this.attackHitbox.body.enable = true;
545
+ this.attackHitbox.body.setSize(100, 100);
546
+
547
+ // Check for hits
548
+ this.scene.physics.overlap(this.attackHitbox, this.isPlayer1 ? player2 : player1, this.handleHit.bind(this, 20, 'heavy'));
549
+
550
+ // Disable hitbox after animation
551
+ this.scene.time.delayedCall(400, () => {
552
+ this.attackHitbox.body.enable = false;
553
+ this.isAttacking = false;
554
+ });
555
+ }
556
+
557
+ specialAttack() {
558
+ this.isAttacking = true;
559
+ this.isSpecial = true;
560
+ this.play(`special-attack-${this.isPlayer1 ? 'p1' : 'p2'}`, true);
561
+ specialSound.play();
562
+
563
+ // Reset special meter
564
+ this.specialMeter = 0;
565
+
566
+ // Enable hitbox (larger for special)
567
+ this.attackHitbox.body.enable = true;
568
+ this.attackHitbox.body.setSize(120, 120);
569
+
570
+ // Check for hits
571
+ this.scene.physics.overlap(this.attackHitbox, this.isPlayer1 ? player2 : player1, this.handleHit.bind(this, 30, 'special'));
572
+
573
+ // Disable hitbox after animation
574
+ this.scene.time.delayedCall(600, () => {
575
+ this.attackHitbox.body.enable = false;
576
+ this.isAttacking = false;
577
+ this.isSpecial = false;
578
+ });
579
+ }
580
+
581
+ block() {
582
+ this.isBlocking = true;
583
+ this.setVelocityX(0);
584
+ this.play(`block-${this.isPlayer1 ? 'p1' : 'p2'}`, true);
585
+ }
586
+
587
+ releaseBlock() {
588
+ this.isBlocking = false;
589
+ }
590
+
591
+ handleHit(damage, attackType, attacker, defender) {
592
+ if (defender.invulnerable) return;
593
+
594
+ // Check if defender is blocking
595
+ if (defender.isBlocking) {
596
+ // Reduce damage when blocking
597
+ damage *= 0.3;
598
+
599
+ // Play block animation
600
+ defender.play(`block-${defender.isPlayer1 ? 'p1' : 'p2'}`, true);
601
+
602
+ // Small knockback
603
+ const knockback = this.facingRight ? -100 : 100;
604
+ defender.setVelocityX(knockback);
605
+
606
+ // Make defender briefly invulnerable
607
+ defender.invulnerable = true;
608
+ this.scene.time.delayedCall(500, () => {
609
+ defender.invulnerable = false;
610
+ });
611
+ } else {
612
+ // Play hit animation
613
+ defender.play(`hit-${defender.isPlayer1 ? 'p1' : 'p2'}`, true);
614
+
615
+ // Apply knockback based on attack type
616
+ let knockback = 0;
617
+ if (attackType === 'light') knockback = this.facingRight ? 150 : -150;
618
+ else if (attackType === 'heavy') knockback = this.facingRight ? 250 : -250;
619
+ else if (attackType === 'special') knockback = this.facingRight ? 400 : -400;
620
+
621
+ defender.setVelocityX(knockback);
622
+ defender.setVelocityY(-100);
623
+
624
+ // Make defender briefly invulnerable
625
+ defender.invulnerable = true;
626
+ this.scene.time.delayedCall(800, () => {
627
+ defender.invulnerable = false;
628
+ });
629
+ }
630
+
631
+ // Apply damage
632
+ defender.health -= damage;
633
+ if (defender.health < 0) defender.health = 0;
634
+
635
+ // Add to attacker's special meter
636
+ this.specialMeter += damage;
637
+ if (this.specialMeter > this.maxSpecialMeter) {
638
+ this.specialMeter = this.maxSpecialMeter;
639
+ }
640
+
641
+ // Combo system
642
+ const now = this.scene.time.now;
643
+ if (now - this.lastHitTime < 1000) {
644
+ this.comboCount++;
645
+
646
+ // Show combo text
647
+ const comboText = this.scene.add.text(
648
+ defender.x,
649
+ defender.y - 100,
650
+ `COMBO x${this.comboCount + 1}!`,
651
+ {
652
+ fontSize: '32px',
653
+ fill: '#ff0',
654
+ fontFamily: 'PressStart2P',
655
+ stroke: '#000',
656
+ strokeThickness: 4
657
+ }
658
+ );
659
+ comboText.setOrigin(0.5);
660
+
661
+ // Add to combo texts array for cleanup
662
+ comboTexts.push(comboText);
663
+
664
+ // Animate combo text
665
+ this.scene.tweens.add({
666
+ targets: comboText,
667
+ y: comboText.y - 50,
668
+ alpha: 0,
669
+ duration: 1000,
670
+ onComplete: () => {
671
+ comboText.destroy();
672
+ comboTexts = comboTexts.filter(t => t !== comboText);
673
+ }
674
+ });
675
+ } else {
676
+ this.comboCount = 0;
677
+ }
678
+
679
+ this.lastHitTime = now;
680
+
681
+ // Check for KO
682
+ if (defender.health <= 0) {
683
+ this.scene.gameOver(this.isPlayer1 ? 'Player 1' : 'Player 2');
684
+ }
685
+ }
686
+ }
687
+
688
+ // Preload assets
689
+ function preload() {
690
+ // Load raccoon sprite sheet
691
+ this.load.spritesheet('raccoon', 'https://i.imgur.com/JQlY5zX.png', {
692
+ frameWidth: 128,
693
+ frameHeight: 128
694
+ });
695
+
696
+ // Load backgrounds
697
+ this.load.image('background1', 'https://i.imgur.com/XH7QZ0a.png');
698
+ this.load.image('background2', 'https://i.imgur.com/Y9vBQ3c.png');
699
+
700
+ // Load platforms
701
+ this.load.image('platform', 'https://i.imgur.com/8Z7WQkK.png');
702
+
703
+ // Load sounds
704
+ this.load.audio('hit', 'https://assets.codepen.io/21542/hit.mp3');
705
+ this.load.audio('jump', 'https://assets.codepen.io/21542/jump.mp3');
706
+ this.load.audio('special', 'https://assets.codepen.io/21542/special.mp3');
707
+ this.load.audio('backgroundMusic', 'https://assets.codepen.io/21542/fight-music.mp3');
708
+ }
709
+
710
+ // Create game objects
711
+ function create() {
712
+ // Randomly select background
713
+ const bgKey = Phaser.Math.Between(0, 1) === 0 ? 'background1' : 'background2';
714
+ background = this.add.image(config.width / 2, config.height / 2, bgKey);
715
+ background.setDisplaySize(config.width, config.height);
716
+
717
+ // Create platforms
718
+ platforms = this.physics.add.staticGroup();
719
+
720
+ // Main platform
721
+ platforms.create(config.width / 2, config.height - 50, 'platform')
722
+ .setScale(10, 1)
723
+ .refreshBody();
724
+
725
+ // Side platforms
726
+ platforms.create(200, 400, 'platform').setScale(3, 1).refreshBody();
727
+ platforms.create(config.width - 200, 400, 'platform').setScale(3, 1).refreshBody();
728
+
729
+ // Create players
730
+ player1 = new Raccoon(this, 300, 300, true);
731
+ player2 = new Raccoon(this, config.width - 300, 300, false);
732
+
733
+ // Set up physics collisions
734
+ this.physics.add.collider(player1, platforms);
735
+ this.physics.add.collider(player2, platforms);
736
+
737
+ // Set up keyboard controls
738
+ cursors = this.input.keyboard.addKeys({
739
+ up: Phaser.Input.Keyboard.KeyCodes.W,
740
+ left: Phaser.Input.Keyboard.KeyCodes.A,
741
+ right: Phaser.Input.Keyboard.KeyCodes.D,
742
+ down: Phaser.Input.Keyboard.KeyCodes.S,
743
+ lightAttack: Phaser.Input.Keyboard.KeyCodes.J,
744
+ heavyAttack: Phaser.Input.Keyboard.KeyCodes.K,
745
+ specialAttack: Phaser.Input.Keyboard.KeyCodes.L
746
+ });
747
+
748
+ p2Cursors = this.input.keyboard.addKeys({
749
+ up: Phaser.Input.Keyboard.KeyCodes.UP,
750
+ left: Phaser.Input.Keyboard.KeyCodes.LEFT,
751
+ right: Phaser.Input.Keyboard.KeyCodes.RIGHT,
752
+ down: Phaser.Input.Keyboard.KeyCodes.DOWN,
753
+ lightAttack: Phaser.Input.Keyboard.KeyCodes.NUMPAD_ONE,
754
+ heavyAttack: Phaser.Input.Keyboard.KeyCodes.NUMPAD_TWO,
755
+ specialAttack: Phaser.Input.Keyboard.KeyCodes.NUMPAD_THREE
756
+ });
757
+
758
+ // Set up gamepad controls
759
+ this.input.gamepad.on('connected', (pad) => {
760
+ console.log('Gamepad connected');
761
+ gamepads[pad.index] = pad;
762
+ });
763
+
764
+ // Initialize sounds
765
+ hitSound = this.sound.add('hit');
766
+ jumpSound = this.sound.add('jump');
767
+ specialSound = this.sound.add('special');
768
+ backgroundMusic = this.sound.add('backgroundMusic');
769
+
770
+ // Set up UI events
771
+ document.getElementById('start-button').addEventListener('click', () => {
772
+ this.startGame();
773
+ });
774
+
775
+ document.getElementById('controls-button').addEventListener('click', () => {
776
+ document.getElementById('main-menu').style.display = 'none';
777
+ document.getElementById('controls-screen').style.display = 'flex';
778
+ });
779
+
780
+ document.getElementById('back-button').addEventListener('click', () => {
781
+ document.getElementById('controls-screen').style.display = 'none';
782
+ document.getElementById('main-menu').style.display = 'flex';
783
+ });
784
+
785
+ document.getElementById('rematch-button').addEventListener('click', () => {
786
+ this.startGame();
787
+ });
788
+
789
+ document.getElementById('menu-button').addEventListener('click', () => {
790
+ this.showMainMenu();
791
+ });
792
+
793
+ // Start in menu state
794
+ this.showMainMenu();
795
+ }
796
+
797
+ // Update game state
798
+ function update() {
799
+ if (gameState !== 'playing') return;
800
+
801
+ // Update gamepads
802
+ const gamepads = navigator.getGamepads();
803
+
804
+ // Update players
805
+ player1.update(cursors, gamepads[0]);
806
+ player2.update(p2Cursors, gamepads[1]);
807
+
808
+ // Clean up old combo texts
809
+ comboTexts.forEach(text => {
810
+ if (text.active) {
811
+ text.y -= 1;
812
+ }
813
+ });
814
+ }
815
+
816
+ // Scene methods
817
+ function startGame() {
818
+ // Reset game state
819
+ gameState = 'playing';
820
+
821
+ // Hide menus
822
+ document.getElementById('main-menu').style.display = 'none';
823
+ document.getElementById('controls-screen').style.display = 'none';
824
+ document.getElementById('game-over-screen').style.display = 'none';
825
+
826
+ // Reset players
827
+ player1.health = player1.maxHealth;
828
+ player2.health = player2.maxHealth;
829
+ player1.specialMeter = 0;
830
+ player2.specialMeter = 0;
831
+ player1.setPosition(300, 300);
832
+ player2.setPosition(config.width - 300, 300);
833
+ player1.setVelocity(0, 0);
834
+ player2.setVelocity(0, 0);
835
+ player1.isAttacking = false;
836
+ player2.isAttacking = false;
837
+ player1.isBlocking = false;
838
+ player2.isBlocking = false;
839
+
840
+ // Play background music
841
+ backgroundMusic.play({
842
+ loop: true,
843
+ volume: 0.5
844
+ });
845
+ }
846
+
847
+ function gameOver(winner) {
848
+ gameState = 'gameover';
849
+
850
+ // Stop background music
851
+ backgroundMusic.stop();
852
+
853
+ // Show game over screen
854
+ document.getElementById('game-over-screen').style.display = 'flex';
855
+ document.getElementById('winner-text').textContent = `${winner} WINS!`;
856
+ }
857
+
858
+ function showMainMenu() {
859
+ gameState = 'menu';
860
+
861
+ // Stop background music
862
+ backgroundMusic.stop();
863
+
864
+ // Show main menu
865
+ document.getElementById('main-menu').style.display = 'flex';
866
+ document.getElementById('controls-screen').style.display = 'none';
867
+ document.getElementById('game-over-screen').style.display = 'none';
868
+ }
869
+ </script>
870
+ <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=pijou/newlll" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
871
+ </html>