jaldpsd

Untitled

Feb 19th, 2025
393
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.02 KB | None | 0 0
  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>Reaction Rumble: Red vs Blue</title>
  7. <style>
  8. body {
  9. margin: 0;
  10. display: flex;
  11. flex-direction: column;
  12. align-items: center;
  13. justify-content: center;
  14. height: 100vh;
  15. background-color: #e0e0e0;
  16. font-family: 'Segoe UI', Arial, sans-serif;
  17. overflow: hidden;
  18. }
  19. #gameContainer {
  20. text-align: center;
  21. background: #fff;
  22. padding: 20px;
  23. border-radius: 10px;
  24. box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  25. }
  26. #gameCanvas {
  27. border: 2px solid #333;
  28. border-radius: 5px;
  29. }
  30. #title {
  31. font-size: 2em;
  32. margin-bottom: 10px;
  33. color: #333;
  34. }
  35. #status, #reactionTime {
  36. margin: 10px 0;
  37. font-size: 1.2em;
  38. color: #444;
  39. }
  40. #status { font-weight: bold; }
  41. .highlight-red { box-shadow: 0 0 20px 5px rgba(255, 0, 0, 0.7); }
  42. .highlight-blue { box-shadow: 0 0 20px 5px rgba(0, 0, 255, 0.7); }
  43. #startScreen {
  44. position: absolute;
  45. top: 50%;
  46. left: 50%;
  47. transform: translate(-50%, -50%);
  48. background: rgba(255, 255, 255, 0.9);
  49. padding: 20px;
  50. border-radius: 10px;
  51. box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  52. text-align: center;
  53. }
  54. #startScreen button {
  55. padding: 10px 20px;
  56. font-size: 1.2em;
  57. background-color: #4CAF50;
  58. color: white;
  59. border: none;
  60. border-radius: 5px;
  61. cursor: pointer;
  62. }
  63. #startScreen button:hover { background-color: #45a049; }
  64. </style>
  65. </head>
  66. <body>
  67. <div id="gameContainer">
  68. <div id="title">Reaction Rumble</div>
  69. <canvas id="gameCanvas" width="600" height="400" aria-label="Game canvas showing red and blue camps"></canvas>
  70. <div id="status" aria-live="polite">Press 'A' (Red) or 'L' (Blue) to push back! 'Space' to restart.</div>
  71. <div id="reactionTime" aria-live="polite">Reaction Time: -- ms</div>
  72. </div>
  73. <div id="startScreen">
  74. <h2>Welcome to Reaction Rumble</h2>
  75. <p>Red ('A') defends left, Blue ('L') defends right.<br>Push back the line when it moves toward you!<br>Press 'Space' to restart anytime.</p>
  76. <button id="startButton">Start Game</button>
  77. </div>
  78. <script>
  79. // Configuration
  80. const CONFIG = {
  81. WIDTH: 600,
  82. HEIGHT: 400,
  83. MAX_WAIT_TIME: 1500, // Changed from 3000ms to 1500ms (< 1.5s)
  84. KEY_COOLDOWN: 200,
  85. LINE_SPEED: 200, // Pixels per second
  86. HIGHLIGHT_DURATION: 500,
  87. };
  88.  
  89. // DOM elements
  90. const canvas = document.getElementById('gameCanvas');
  91. const ctx = canvas.getContext('2d');
  92. const status = document.getElementById('status');
  93. const reactionTimeDisplay = document.getElementById('reactionTime');
  94. const startScreen = document.getElementById('startScreen');
  95. const startButton = document.getElementById('startButton');
  96.  
  97. // Game state
  98. class Game {
  99. constructor() {
  100. this.reset();
  101. this.lastTime = performance.now();
  102. this.animationFrameId = null;
  103. }
  104.  
  105. reset() {
  106. this.linePosition = CONFIG.WIDTH / 2;
  107. this.lineSpeed = CONFIG.LINE_SPEED;
  108. this.direction = 0;
  109. this.waiting = true;
  110. this.redPressCount = 0;
  111. this.bluePressCount = 0;
  112. this.gameOver = false;
  113. this.moveStartTime = 0;
  114. this.lastKeyPressTime = 0;
  115. canvas.classList.remove('highlight-red', 'highlight-blue');
  116. status.textContent = "Press 'A' (Red) or 'L' (Blue) to push back! 'Space' to restart.";
  117. reactionTimeDisplay.textContent = 'Reaction Time: -- ms';
  118. if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId);
  119. }
  120.  
  121. startWait() {
  122. this.waiting = true;
  123. this.direction = 0;
  124. const waitTime = Math.random() * CONFIG.MAX_WAIT_TIME;
  125. setTimeout(() => {
  126. if (!this.gameOver) {
  127. this.waiting = false;
  128. this.direction = Math.random() < 0.5 ? -1 : 1;
  129. this.moveStartTime = performance.now();
  130. this.highlightActiveSide();
  131. }
  132. }, waitTime);
  133. }
  134.  
  135. highlightActiveSide() {
  136. canvas.classList.remove('highlight-red', 'highlight-blue');
  137. if (this.direction === -1) {
  138. canvas.classList.add('highlight-red');
  139. setTimeout(() => canvas.classList.remove('highlight-red'), CONFIG.HIGHLIGHT_DURATION);
  140. } else if (this.direction === 1) {
  141. canvas.classList.add('highlight-blue');
  142. setTimeout(() => canvas.classList.remove('highlight-blue'), CONFIG.HIGHLIGHT_DURATION);
  143. }
  144. }
  145.  
  146. handlePress(player, intendedDirection) {
  147. const halfCamp = CONFIG.WIDTH / 2;
  148. if (this.waiting) {
  149. if (this.linePosition > halfCamp && player === 'red') {
  150. this.linePosition = CONFIG.WIDTH - this.linePosition;
  151. } else if (this.linePosition < halfCamp && player === 'blue') {
  152. this.linePosition = CONFIG.WIDTH - this.linePosition;
  153. }
  154. return;
  155. }
  156.  
  157. const pressCount = player === 'red' ? this.redPressCount : this.bluePressCount;
  158.  
  159. if (this.direction === intendedDirection) {
  160. const reactionTime = Math.round(performance.now() - this.moveStartTime);
  161. reactionTimeDisplay.textContent = `Reaction Time: ${reactionTime} ms`;
  162. this.direction = 0;
  163. this.waiting = true;
  164. this.startWait();
  165. if (pressCount === 3) this.lineSpeed = CONFIG.LINE_SPEED;
  166. } else {
  167. if (this.linePosition > halfCamp && player === 'red') {
  168. this.linePosition = CONFIG.WIDTH - this.linePosition;
  169. } else if (this.linePosition < halfCamp && player === 'blue') {
  170. this.linePosition = CONFIG.WIDTH - this.linePosition;
  171. }
  172. }
  173.  
  174. if (pressCount === 2) this.lineSpeed = CONFIG.LINE_SPEED * 2;
  175. else if (pressCount > 3) {
  176. if (player === 'red') this.redPressCount = 0;
  177. else this.bluePressCount = 0;
  178. }
  179. }
  180.  
  181. update(timestamp) {
  182. const deltaTime = (timestamp - this.lastTime) / 1000; // Seconds
  183. this.lastTime = timestamp;
  184.  
  185. if (!this.waiting && !this.gameOver) {
  186. this.linePosition += this.direction * this.lineSpeed * deltaTime;
  187.  
  188. if (this.linePosition <= 0) {
  189. this.gameOver = true;
  190. status.textContent = 'Blue Wins! Red camp overtaken. Press Space to restart.';
  191. reactionTimeDisplay.textContent = 'Reaction Time: Game Over';
  192. } else if (this.linePosition >= CONFIG.WIDTH) {
  193. this.gameOver = true;
  194. status.textContent = 'Red Wins! Blue camp overtaken. Press Space to restart.';
  195. reactionTimeDisplay.textContent = 'Reaction Time: Game Over';
  196. }
  197. }
  198.  
  199. this.draw();
  200. this.animationFrameId = requestAnimationFrame(this.update.bind(this));
  201. }
  202.  
  203. draw() {
  204. ctx.clearRect(0, 0, CONFIG.WIDTH, CONFIG.HEIGHT);
  205. // Draw red camp from left (0) to linePosition
  206. ctx.fillStyle = '#ff5555';
  207. ctx.fillRect(0, 0, this.linePosition, CONFIG.HEIGHT);
  208. // Draw blue camp from linePosition to right (CONFIG.WIDTH)
  209. ctx.fillStyle = '#5555ff';
  210. ctx.fillRect(this.linePosition, 0, CONFIG.WIDTH - this.linePosition, CONFIG.HEIGHT);
  211. // Draw dividing line
  212. ctx.fillStyle = 'black';
  213. ctx.fillRect(this.linePosition - 2, 0, 4, CONFIG.HEIGHT);
  214. }
  215. }
  216.  
  217. // Game instance
  218. const game = new Game();
  219.  
  220. // Event handlers
  221. document.addEventListener('keydown', (e) => {
  222. const now = performance.now();
  223. if (now - game.lastKeyPressTime < CONFIG.KEY_COOLDOWN) return;
  224. game.lastKeyPressTime = now;
  225.  
  226. const key = e.key.toLowerCase();
  227. if (key === ' ') {
  228. game.reset();
  229. game.startWait();
  230. game.update(now);
  231. return;
  232. }
  233. if (game.gameOver) return;
  234.  
  235. if (key === 'a') {
  236. game.redPressCount++;
  237. game.handlePress('red', -1);
  238. } else if (key === 'l') {
  239. game.bluePressCount++;
  240. game.handlePress('blue', 1);
  241. }
  242. });
  243.  
  244. startButton.addEventListener('click', () => {
  245. startScreen.style.display = 'none';
  246. game.startWait();
  247. game.update(performance.now());
  248. });
  249.  
  250. // Initial state
  251. game.draw(); // Draw initial canvas
  252. </script>
  253. </body>
  254. </html>
Advertisement
Add Comment
Please, Sign In to add comment