Mystery Game #7

← Back to Games List
// Whack-a-Mole Game Implementation const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); // Game settings const gridSize = 3; const holeSize = 80; const padding = 40; const totalWidth = (holeSize + padding) * gridSize; const totalHeight = (holeSize + padding) * gridSize; // Center the grid canvas.width = totalWidth + padding; canvas.height = totalHeight + padding + 50; // Extra space for score // Game state const holes = []; let score = 0; let timeLeft = 30; let gameActive = false; let lastSpawnTime = 0; let spawnInterval = 1000; let minSpawnInterval = 500; // Create holes grid function createHoles() { for (let row = 0; row < gridSize; row++) { for (let col = 0; col < gridSize; col++) { const x = col * (holeSize + padding) + padding; const y = row * (holeSize + padding) + padding; holes.push({ x: x, y: y, size: holeSize, active: false, timeUp: 0, upDuration: 0 }); } } } // Handle mouse click canvas.addEventListener('click', function(e) { if (!gameActive) { startGame(); return; } const rect = canvas.getBoundingClientRect(); const clickX = e.clientX - rect.left; const clickY = e.clientY - rect.top; holes.forEach(hole => { if (hole.active && clickX > hole.x && clickX < hole.x + hole.size && clickY > hole.y && clickY < hole.y + hole.size) { score += 10; hole.active = false; spawnInterval = Math.max(minSpawnInterval, spawnInterval - 10); } }); }); function spawnTarget() { if (!gameActive) return; const now = Date.now(); if (now - lastSpawnTime < spawnInterval) return; // Deactivate any expired targets holes.forEach(hole => { if (hole.active && now > hole.timeUp) { hole.active = false; } }); // Find inactive holes const inactiveHoles = holes.filter(hole => !hole.active); if (inactiveHoles.length === 0) return; // Randomly activate one const target = inactiveHoles[Math.floor(Math.random() * inactiveHoles.length)]; target.active = true; target.upDuration = Math.random() * 500 + 750; // Random duration between 750-1250ms target.timeUp = now + target.upDuration; lastSpawnTime = now; } function draw() { // Clear canvas ctx.fillStyle = 'skyblue'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw holes and targets holes.forEach(hole => { // Draw hole (dark circle) ctx.beginPath(); ctx.arc(hole.x + hole.size/2, hole.y + hole.size/2, hole.size/2, 0, Math.PI * 2); ctx.fillStyle = '#333'; ctx.fill(); // Draw target if active if (hole.active) { ctx.beginPath(); ctx.arc(hole.x + hole.size/2, hole.y + hole.size/2 - 10, hole.size/3, 0, Math.PI * 2); ctx.fillStyle = 'brown'; ctx.fill(); // Draw eyes ctx.fillStyle = 'black'; ctx.beginPath(); ctx.arc(hole.x + hole.size/2 - 8, hole.y + hole.size/2 - 15, 3, 0, Math.PI * 2); ctx.arc(hole.x + hole.size/2 + 8, hole.y + hole.size/2 - 15, 3, 0, Math.PI * 2); ctx.fill(); } }); // Draw score and time ctx.fillStyle = 'black'; ctx.font = '20px Arial'; ctx.textAlign = 'left'; ctx.fillText('Score: ' + score, 10, canvas.height - 20); ctx.textAlign = 'right'; ctx.fillText('Time: ' + timeLeft, canvas.width - 10, canvas.height - 20); // Draw start message if game not active if (!gameActive) { ctx.fillStyle = 'rgba(0, 0, 0, 0.7)'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = 'white'; ctx.font = '30px Arial'; ctx.textAlign = 'center'; if (timeLeft === 30) { ctx.fillText('Click to Start!', canvas.width/2, canvas.height/2); } else { ctx.fillText('Game Over!', canvas.width/2, canvas.height/2 - 30); ctx.font = '20px Arial'; ctx.fillText('Final Score: ' + score, canvas.width/2, canvas.height/2 + 10); ctx.fillText('Click to Play Again', canvas.width/2, canvas.height/2 + 40); } } } function startGame() { score = 0; timeLeft = 30; gameActive = true; spawnInterval = 1000; lastSpawnTime = Date.now(); // Reset all holes holes.forEach(hole => { hole.active = false; }); // Start countdown const timer = setInterval(() => { if (!gameActive) { clearInterval(timer); return; } timeLeft--; if (timeLeft <= 0) { gameActive = false; clearInterval(timer); } }, 1000); } function gameLoop() { spawnTarget(); draw(); requestAnimationFrame(gameLoop); } // Initialize game createHoles(); gameLoop();
# Whack-a-Mole Game Implementation import pygame import random import time from dataclasses import dataclass from typing import List @dataclass class Hole: x: int y: int size: int active: bool = False time_up: float = 0 up_duration: float = 0 class WhackAMoleGame: def __init__(self): pygame.init() # Game settings self.grid_size = 3 self.hole_size = 80 self.padding = 40 self.total_width = (self.hole_size + self.padding) * self.grid_size + self.padding self.total_height = (self.hole_size + self.padding) * self.grid_size + self.padding + 50 # Initialize display self.screen = pygame.display.set_mode((self.total_width, self.total_height)) pygame.display.set_caption('Whack-a-Mole') self.clock = pygame.time.Clock() # Game state self.holes: List[Hole] = [] self.score = 0 self.time_left = 30 self.game_active = False self.last_spawn_time = 0 self.spawn_interval = 1000 self.min_spawn_interval = 500 self.create_holes() def create_holes(self): for row in range(self.grid_size): for col in range(self.grid_size): x = col * (self.hole_size + self.padding) + self.padding y = row * (self.hole_size + self.padding) + self.padding self.holes.append(Hole(x=x, y=y, size=self.hole_size)) def handle_input(self) -> bool: for event in pygame.event.get(): if event.type == pygame.QUIT: return False if event.type == pygame.MOUSEBUTTONDOWN: if not self.game_active: self.start_game() else: mouse_x, mouse_y = pygame.mouse.get_pos() self.check_mole_hit(mouse_x, mouse_y) return True def check_mole_hit(self, x: int, y: int): for hole in self.holes: if (hole.active and x > hole.x and x < hole.x + hole.size and y > hole.y and y < hole.y + hole.size): self.score += 10 hole.active = False self.spawn_interval = max(self.min_spawn_interval, self.spawn_interval - 10) def spawn_target(self): if not self.game_active: return now = time.time() * 1000 # Convert to milliseconds if now - self.last_spawn_time < self.spawn_interval: return # Deactivate expired targets for hole in self.holes: if hole.active and now > hole.time_up: hole.active = False # Find inactive holes inactive_holes = [hole for hole in self.holes if not hole.active] if not inactive_holes: return # Randomly activate one target = random.choice(inactive_holes) target.active = True target.up_duration = random.random() * 500 + 750 target.time_up = now + target.up_duration self.last_spawn_time = now def draw(self): # Clear screen self.screen.fill((135, 206, 235)) # skyblue # Draw holes and moles for hole in self.holes: # Draw hole pygame.draw.circle(self.screen, (51, 51, 51), # dark gray (hole.x + hole.size//2, hole.y + hole.size//2), hole.size//2) # Draw mole if active if hole.active: # Draw mole body pygame.draw.circle(self.screen, (139, 69, 19), # brown (hole.x + hole.size//2, hole.y + hole.size//2 - 10), hole.size//3) # Draw eyes pygame.draw.circle(self.screen, (0, 0, 0), (hole.x + hole.size//2 - 8, hole.y + hole.size//2 - 15), 3) pygame.draw.circle(self.screen, (0, 0, 0), (hole.x + hole.size//2 + 8, hole.y + hole.size//2 - 15), 3) # Draw score and time font = pygame.font.Font(None, 36) score_text = font.render(f'Score: {self.score}', True, (0, 0, 0)) time_text = font.render(f'Time: {self.time_left}', True, (0, 0, 0)) self.screen.blit(score_text, (10, self.total_height - 30)) self.screen.blit(time_text, (self.total_width - 120, self.total_height - 30)) # Draw overlay if game not active if not self.game_active: overlay = pygame.Surface((self.total_width, self.total_height)) overlay.fill((0, 0, 0)) overlay.set_alpha(178) # 70% opacity self.screen.blit(overlay, (0, 0)) font = pygame.font.Font(None, 48) if self.time_left == 30: text = font.render('Click to Start!', True, (255, 255, 255)) text_rect = text.get_rect(center=(self.total_width//2, self.total_height//2)) self.screen.blit(text, text_rect) else: game_over = font.render('Game Over!', True, (255, 255, 255)) game_over_rect = game_over.get_rect( center=(self.total_width//2, self.total_height//2 - 30)) self.screen.blit(game_over, game_over_rect) font = pygame.font.Font(None, 36) score = font.render(f'Final Score: {self.score}', True, (255, 255, 255)) score_rect = score.get_rect( center=(self.total_width//2, self.total_height//2 + 10)) self.screen.blit(score, score_rect) play_again = font.render('Click to Play Again', True, (255, 255, 255)) play_again_rect = play_again.get_rect( center=(self.total_width//2, self.total_height//2 + 40)) self.screen.blit(play_again, play_again_rect) pygame.display.flip() def start_game(self): self.score = 0 self.time_left = 30 self.game_active = True self.spawn_interval = 1000 self.last_spawn_time = time.time() * 1000 # Reset holes for hole in self.holes: hole.active = False def update_timer(self): if self.game_active: current_time = pygame.time.get_ticks() if current_time - self.last_timer_update >= 1000: self.time_left -= 1 self.last_timer_update = current_time if self.time_left <= 0: self.game_active = False def run(self): self.last_timer_update = pygame.time.get_ticks() running = True while running: running = self.handle_input() self.spawn_target() self.update_timer() self.draw() self.clock.tick(60) pygame.quit() if __name__ == '__main__': game = WhackAMoleGame() game.run()
Play Game