C50BARZ commited on
Commit
655de49
Β·
verified Β·
1 Parent(s): 932dd8a

Add 1 files

Browse files
Files changed (1) hide show
  1. index.html +146 -46
index.html CHANGED
@@ -55,52 +55,75 @@
55
  transform: scale(1.05);
56
  box-shadow: 0 0 15px rgba(255, 255, 255, 0.7);
57
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  </style>
59
  </head>
60
  <body class="min-h-screen flex flex-col items-center justify-center text-white overflow-hidden p-4">
61
- <div class="text-center mb-4">
62
- <img src="https://s3-us-west-2.amazonaws.com/anchor-generated-image-bank/staging/podcast_uploaded_nologo400/41101904/41101904-1733754532018-f9830aaa53f19.jpg"
63
- alt="Tetris Logo"
64
- class="mx-auto w-64 h-auto rounded-lg shadow-lg mb-2">
65
- <div class="flex justify-center gap-8 mb-2">
66
- <div>
67
- <p class="text-xl">Score: <span id="score" class="font-bold">0</span></p>
68
- </div>
69
- <div>
70
- <p class="text-xl">Level: <span id="level" class="font-bold">1</span></p>
 
 
 
 
 
 
 
71
  </div>
72
  </div>
73
- </div>
74
-
75
- <div class="relative">
76
- <canvas id="game-board" width="400" height="800" class="bg-black bg-opacity-30"></canvas>
77
- <div id="game-over" class="hidden absolute inset-0 bg-black bg-opacity-70 flex flex-col items-center justify-center">
78
- <h2 class="text-3xl font-bold mb-4">GAME OVER</h2>
79
- <p class="text-xl mb-6">Final Score: <span id="final-score" class="font-bold">0</span></p>
80
- <button id="restart-btn" class="px-6 py-3 bg-white text-black font-bold rounded-lg hover:bg-gray-200 transition">
81
- Play Again
82
- </button>
83
- </div>
84
- <div id="start-screen" class="absolute inset-0 bg-black bg-opacity-70 flex flex-col items-center justify-center">
85
- <button id="start-btn" class="px-8 py-4 bg-gradient-to-r from-purple-500 to-pink-500 text-white font-bold text-xl rounded-lg glow">
86
- START GAME
87
- </button>
88
- <div class="mt-8 text-center">
89
- <p class="mb-2">Controls:</p>
90
- <p>← β†’ : Move</p>
91
- <p>↑ : Rotate</p>
92
- <p>↓ : Soft Drop</p>
93
- <p>Space : Hard Drop</p>
 
 
94
  </div>
95
  </div>
96
  </div>
97
 
98
- <div class="mt-4 flex gap-4">
99
- <button id="sound-toggle" class="px-4 py-2 bg-white bg-opacity-20 rounded-lg hover:bg-opacity-30 transition">
100
- πŸ”ˆ Sound On
101
- </button>
102
- </div>
103
-
104
  <audio id="bg-music" loop>
105
  <source src="https://music.mota.press/music/tetris/project/bgms/bgm.mp3" type="audio/mpeg">
106
  </audio>
@@ -141,7 +164,7 @@
141
  // Game settings
142
  const COLS = 10;
143
  const ROWS = 20;
144
- const BLOCK_SIZE = 40; // Increased from 30 to make game larger
145
  const COLORS = [
146
  null,
147
  '#00d2d3', // I
@@ -232,18 +255,36 @@
232
 
233
  // Draw the game board
234
  function drawBoard() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  ctx.clearRect(0, 0, canvas.width, canvas.height);
236
 
 
 
 
 
237
  // Draw existing blocks
238
  board.forEach((row, y) => {
239
  row.forEach((value, x) => {
240
  if (value) {
241
  ctx.fillStyle = COLORS[value];
242
- ctx.fillRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
243
 
244
  // Add border to blocks
245
  ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
246
- ctx.strokeRect(x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
247
  }
248
  });
249
  });
@@ -255,17 +296,17 @@
255
  if (value) {
256
  ctx.fillStyle = COLORS[value];
257
  ctx.fillRect(
258
- (piece.pos.x + x) * BLOCK_SIZE,
259
- (piece.pos.y + y) * BLOCK_SIZE,
260
- BLOCK_SIZE, BLOCK_SIZE
261
  );
262
 
263
  // Add border to current piece
264
  ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
265
  ctx.strokeRect(
266
- (piece.pos.x + x) * BLOCK_SIZE,
267
- (piece.pos.y + y) * BLOCK_SIZE,
268
- BLOCK_SIZE, BLOCK_SIZE
269
  );
270
  }
271
  });
@@ -517,6 +558,65 @@
517
  }
518
  });
519
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
520
  // Initial draw
521
  drawBoard();
522
  });
 
55
  transform: scale(1.05);
56
  box-shadow: 0 0 15px rgba(255, 255, 255, 0.7);
57
  }
58
+
59
+ @media (max-width: 640px) {
60
+ #game-board {
61
+ width: 100% !important;
62
+ height: auto !important;
63
+ }
64
+
65
+ .game-container {
66
+ flex-direction: column !important;
67
+ }
68
+
69
+ .game-info {
70
+ width: 100% !important;
71
+ margin-bottom: 20px;
72
+ }
73
+
74
+ .game-board-container {
75
+ width: 100% !important;
76
+ }
77
+ }
78
  </style>
79
  </head>
80
  <body class="min-h-screen flex flex-col items-center justify-center text-white overflow-hidden p-4">
81
+ <div class="game-container flex flex-col md:flex-row w-full max-w-6xl gap-8">
82
+ <div class="game-info flex flex-col items-center md:items-start md:w-1/3">
83
+ <img src="https://s3-us-west-2.amazonaws.com/anchor-generated-image-bank/staging/podcast_uploaded_nologo400/41101904/41101904-1733754532018-f9830aaa53f19.jpg"
84
+ alt="Tetris Logo"
85
+ class="w-full max-w-xs h-auto rounded-lg shadow-lg mb-4">
86
+ <div class="flex flex-col gap-4 w-full">
87
+ <div class="bg-black bg-opacity-30 p-4 rounded-lg">
88
+ <p class="text-xl">Score: <span id="score" class="font-bold">0</span></p>
89
+ </div>
90
+ <div class="bg-black bg-opacity-30 p-4 rounded-lg">
91
+ <p class="text-xl">Level: <span id="level" class="font-bold">1</span></p>
92
+ </div>
93
+ <div class="bg-black bg-opacity-30 p-4 rounded-lg">
94
+ <button id="sound-toggle" class="w-full px-4 py-2 bg-white bg-opacity-20 rounded-lg hover:bg-opacity-30 transition">
95
+ πŸ”ˆ Sound On
96
+ </button>
97
+ </div>
98
  </div>
99
  </div>
100
+
101
+ <div class="game-board-container md:w-2/3 flex justify-center">
102
+ <div class="relative w-full max-w-md">
103
+ <canvas id="game-board" width="300" height="600" class="w-full h-auto bg-black bg-opacity-30"></canvas>
104
+ <div id="game-over" class="hidden absolute inset-0 bg-black bg-opacity-70 flex flex-col items-center justify-center">
105
+ <h2 class="text-3xl font-bold mb-4">GAME OVER</h2>
106
+ <p class="text-xl mb-6">Final Score: <span id="final-score" class="font-bold">0</span></p>
107
+ <button id="restart-btn" class="px-6 py-3 bg-white text-black font-bold rounded-lg hover:bg-gray-200 transition">
108
+ Play Again
109
+ </button>
110
+ </div>
111
+ <div id="start-screen" class="absolute inset-0 bg-black bg-opacity-70 flex flex-col items-center justify-center">
112
+ <button id="start-btn" class="px-8 py-4 bg-gradient-to-r from-purple-500 to-pink-500 text-white font-bold text-xl rounded-lg glow">
113
+ START GAME
114
+ </button>
115
+ <div class="mt-8 text-center">
116
+ <p class="mb-2">Controls:</p>
117
+ <p>← β†’ : Move</p>
118
+ <p>↑ : Rotate</p>
119
+ <p>↓ : Soft Drop</p>
120
+ <p>Space : Hard Drop</p>
121
+ </div>
122
+ </div>
123
  </div>
124
  </div>
125
  </div>
126
 
 
 
 
 
 
 
127
  <audio id="bg-music" loop>
128
  <source src="https://music.mota.press/music/tetris/project/bgms/bgm.mp3" type="audio/mpeg">
129
  </audio>
 
164
  // Game settings
165
  const COLS = 10;
166
  const ROWS = 20;
167
+ const BLOCK_SIZE = 30;
168
  const COLORS = [
169
  null,
170
  '#00d2d3', // I
 
255
 
256
  // Draw the game board
257
  function drawBoard() {
258
+ // Adjust canvas size for mobile
259
+ const scale = Math.min(
260
+ window.innerWidth * 0.8 / (COLS * BLOCK_SIZE),
261
+ window.innerHeight * 0.7 / (ROWS * BLOCK_SIZE)
262
+ );
263
+
264
+ const scaledWidth = COLS * BLOCK_SIZE * scale;
265
+ const scaledHeight = ROWS * BLOCK_SIZE * scale;
266
+
267
+ if (canvas.width !== scaledWidth || canvas.height !== scaledHeight) {
268
+ canvas.width = scaledWidth;
269
+ canvas.height = scaledHeight;
270
+ }
271
+
272
  ctx.clearRect(0, 0, canvas.width, canvas.height);
273
 
274
+ // Calculate block size based on current canvas dimensions
275
+ const blockWidth = canvas.width / COLS;
276
+ const blockHeight = canvas.height / ROWS;
277
+
278
  // Draw existing blocks
279
  board.forEach((row, y) => {
280
  row.forEach((value, x) => {
281
  if (value) {
282
  ctx.fillStyle = COLORS[value];
283
+ ctx.fillRect(x * blockWidth, y * blockHeight, blockWidth, blockHeight);
284
 
285
  // Add border to blocks
286
  ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
287
+ ctx.strokeRect(x * blockWidth, y * blockHeight, blockWidth, blockHeight);
288
  }
289
  });
290
  });
 
296
  if (value) {
297
  ctx.fillStyle = COLORS[value];
298
  ctx.fillRect(
299
+ (piece.pos.x + x) * blockWidth,
300
+ (piece.pos.y + y) * blockHeight,
301
+ blockWidth, blockHeight
302
  );
303
 
304
  // Add border to current piece
305
  ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
306
  ctx.strokeRect(
307
+ (piece.pos.x + x) * blockWidth,
308
+ (piece.pos.y + y) * blockHeight,
309
+ blockWidth, blockHeight
310
  );
311
  }
312
  });
 
558
  }
559
  });
560
 
561
+ // Touch controls for mobile
562
+ let touchStartX = 0;
563
+ let touchStartY = 0;
564
+
565
+ canvas.addEventListener('touchstart', (e) => {
566
+ touchStartX = e.touches[0].clientX;
567
+ touchStartY = e.touches[0].clientY;
568
+ e.preventDefault();
569
+ }, { passive: false });
570
+
571
+ canvas.addEventListener('touchmove', (e) => {
572
+ if (!piece || gameOver || startScreen.classList.contains('hidden') === false) return;
573
+
574
+ const touchX = e.touches[0].clientX;
575
+ const touchY = e.touches[0].clientY;
576
+ const diffX = touchX - touchStartX;
577
+ const diffY = touchY - touchStartY;
578
+
579
+ // Horizontal swipe
580
+ if (Math.abs(diffX) > 30) {
581
+ if (diffX > 0) {
582
+ movePiece(1);
583
+ } else {
584
+ movePiece(-1);
585
+ }
586
+ touchStartX = touchX;
587
+ }
588
+
589
+ // Vertical swipe down (drop)
590
+ if (diffY > 30) {
591
+ dropPiece();
592
+ touchStartY = touchY;
593
+ }
594
+
595
+ // Vertical swipe up (rotate)
596
+ if (diffY < -30) {
597
+ rotate();
598
+ touchStartY = touchY;
599
+ }
600
+
601
+ e.preventDefault();
602
+ }, { passive: false });
603
+
604
+ canvas.addEventListener('touchend', (e) => {
605
+ // Tap (hard drop)
606
+ if (Math.abs(e.changedTouches[0].clientX - touchStartX) < 10 &&
607
+ Math.abs(e.changedTouches[0].clientY - touchStartY) < 10) {
608
+ hardDrop();
609
+ }
610
+ e.preventDefault();
611
+ }, { passive: false });
612
+
613
+ // Handle window resize
614
+ window.addEventListener('resize', () => {
615
+ if (!gameOver && startScreen.classList.contains('hidden')) {
616
+ drawBoard();
617
+ }
618
+ });
619
+
620
  // Initial draw
621
  drawBoard();
622
  });