Mystery Game #15

← Back to Games List
// Physics-based Target Game Implementation const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); // Game objects const launcher = { x: 50, y: canvas.height - 50, width: 30, height: 30, rotation: 0, force: 0 }; const projectile = { x: launcher.x, y: launcher.y, radius: 5, inMotion: false, velocityX: 0, velocityY: 0 }; const objectives = []; const physics = 0.5; let isAiming = false; let initialX = 0; let initialY = 0; let points = 0; let attempts = 0; // Create objectives function createObjectives() { for (let i = 0; i < 3; i++) { objectives.push({ x: canvas.width - 200 + (i * 60), y: canvas.height - 30 - (i * 40), width: 30, height: 30, destroyed: false }); } } // Mouse controls canvas.addEventListener('mousedown', (e) => { const rect = canvas.getBoundingClientRect(); initialX = e.clientX - rect.left; initialY = e.clientY - rect.top; if (!projectile.inMotion) { isAiming = true; } }); canvas.addEventListener('mousemove', (e) => { if (isAiming && !projectile.inMotion) { const rect = canvas.getBoundingClientRect(); const mouseX = e.clientX - rect.left; const mouseY = e.clientY - rect.top; // Calculate rotation and force from drag distance const dx = mouseX - initialX; const dy = mouseY - initialY; launcher.rotation = Math.atan2(-dy, dx); launcher.force = Math.min(Math.sqrt(dx * dx + dy * dy) / 10, 20); } }); canvas.addEventListener('mouseup', () => { if (isAiming && !projectile.inMotion) { fireProjectile(); attempts++; } isAiming = false; }); function fireProjectile() { projectile.x = launcher.x; projectile.y = launcher.y; projectile.velocityX = Math.cos(launcher.rotation) * launcher.force; projectile.velocityY = Math.sin(launcher.rotation) * -launcher.force; projectile.inMotion = true; } function updateProjectile() { if (projectile.inMotion) { projectile.x += projectile.velocityX; projectile.y += projectile.velocityY; projectile.velocityY += physics; // Check for collisions with objectives objectives.forEach(obj => { if (!obj.destroyed && checkCollision(projectile, obj)) { obj.destroyed = true; points += 100; } }); // Check if projectile is out of bounds if (projectile.y > canvas.height || projectile.x < 0 || projectile.x > canvas.width) { projectile.inMotion = false; } } } function checkCollision(projectile, obj) { return projectile.x > obj.x && projectile.x < obj.x + obj.width && projectile.y > obj.y && projectile.y < obj.y + obj.height; } function render() { // Clear canvas ctx.fillStyle = 'skyblue'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw terrain ctx.fillStyle = 'green'; ctx.fillRect(0, canvas.height - 20, canvas.width, 20); // Draw launcher ctx.save(); ctx.translate(launcher.x, launcher.y); ctx.rotate(launcher.rotation); ctx.fillStyle = 'brown'; ctx.fillRect(0, -launcher.height/2, launcher.width, launcher.height); ctx.restore(); // Draw aim guide if (isAiming && !projectile.inMotion) { ctx.beginPath(); ctx.moveTo(launcher.x, launcher.y); ctx.lineTo( launcher.x + Math.cos(launcher.rotation) * (launcher.force * 10), launcher.y + Math.sin(launcher.rotation) * (launcher.force * 10) ); ctx.strokeStyle = 'rgba(255,255,255,0.5)'; ctx.stroke(); } // Draw projectile if (projectile.inMotion) { ctx.beginPath(); ctx.arc(projectile.x, projectile.y, projectile.radius, 0, Math.PI * 2); ctx.fillStyle = 'black'; ctx.fill(); } // Draw objectives objectives.forEach(obj => { ctx.fillStyle = obj.destroyed ? 'red' : 'orange'; ctx.fillRect(obj.x, obj.y, obj.width, obj.height); }); // Draw UI ctx.fillStyle = 'black'; ctx.font = '20px Arial'; ctx.fillText('Points: ' + points, 10, 30); ctx.fillText('Attempts: ' + attempts, 10, 60); // Check for victory if (objectives.every(obj => obj.destroyed)) { ctx.fillStyle = 'black'; ctx.font = '40px Arial'; ctx.fillText('Victory!', canvas.width/2 - 80, canvas.height/2); } }
# Physics-based Target Game Implementation import pygame import math from dataclasses import dataclass from typing import List, Tuple @dataclass class Launcher: x: float y: float width: int = 30 height: int = 30 rotation: float = 0 force: float = 0 @dataclass class Projectile: x: float y: float radius: int = 5 in_motion: bool = False velocity_x: float = 0 velocity_y: float = 0 @dataclass class Target: x: float y: float width: int = 30 height: int = 30 destroyed: bool = False class TargetGame: def __init__(self): pygame.init() # Game settings self.width = 800 self.height = 600 self.physics = 0.5 # Initialize display self.screen = pygame.display.set_mode((self.width, self.height)) pygame.display.set_caption('Target Game') self.clock = pygame.time.Clock() # Game objects self.launcher = Launcher(50, self.height - 50) self.projectile = Projectile(self.launcher.x, self.launcher.y) self.objectives: List[Target] = [] # Game state self.is_aiming = False self.initial_x = 0 self.initial_y = 0 self.points = 0 self.attempts = 0 self.create_objectives() def create_objectives(self): """Create target objectives""" for i in range(3): self.objectives.append( Target(self.width - 200 + (i * 60), self.height - 30 - (i * 40)) ) def handle_input(self) -> bool: """Handle mouse input""" for event in pygame.event.get(): if event.type == pygame.QUIT: return False if event.type == pygame.MOUSEBUTTONDOWN: mouse_x, mouse_y = pygame.mouse.get_pos() self.initial_x = mouse_x self.initial_y = mouse_y if not self.projectile.in_motion: self.is_aiming = True elif event.type == pygame.MOUSEBUTTONUP: if self.is_aiming and not self.projectile.in_motion: self.fire_projectile() self.attempts += 1 self.is_aiming = False elif event.type == pygame.MOUSEMOTION: if self.is_aiming and not self.projectile.in_motion: mouse_x, mouse_y = pygame.mouse.get_pos() # Calculate rotation and force from drag distance dx = mouse_x - self.initial_x dy = mouse_y - self.initial_y self.launcher.rotation = math.atan2(-dy, dx) self.launcher.force = min( math.sqrt(dx * dx + dy * dy) / 10, 20) return True def fire_projectile(self): """Fire the projectile with current launcher settings""" self.projectile.x = self.launcher.x self.projectile.y = self.launcher.y self.projectile.velocity_x = (math.cos(self.launcher.rotation) * self.launcher.force) self.projectile.velocity_y = (math.sin(self.launcher.rotation) * -self.launcher.force) self.projectile.in_motion = True def update_projectile(self): """Update projectile physics""" if self.projectile.in_motion: self.projectile.x += self.projectile.velocity_x self.projectile.y += self.projectile.velocity_y self.projectile.velocity_y += self.physics # Check for collisions with objectives for obj in self.objectives: if (not obj.destroyed and self.check_collision(self.projectile, obj)): obj.destroyed = True self.points += 100 # Check if projectile is out of bounds if (self.projectile.y > self.height or self.projectile.x < 0 or self.projectile.x > self.width): self.projectile.in_motion = False def check_collision(self, projectile: Projectile, obj: Target) -> bool: """Check collision between projectile and target""" return (projectile.x > obj.x and projectile.x < obj.x + obj.width and projectile.y > obj.y and projectile.y < obj.y + obj.height) def draw(self): """Draw the game state""" # Clear screen self.screen.fill((135, 206, 235)) # skyblue # Draw terrain pygame.draw.rect(self.screen, (0, 255, 0), (0, self.height - 20, self.width, 20)) # Draw launcher surface = pygame.Surface((self.launcher.width, self.launcher.height), pygame.SRCALPHA) pygame.draw.rect(surface, (139, 69, 19), # brown (0, 0, self.launcher.width, self.launcher.height)) rotated = pygame.transform.rotate( surface, -math.degrees(self.launcher.rotation)) rect = rotated.get_rect( center=(self.launcher.x, self.launcher.y)) self.screen.blit(rotated, rect) # Draw aim guide if self.is_aiming and not self.projectile.in_motion: end_x = (self.launcher.x + math.cos(self.launcher.rotation) * (self.launcher.force * 10)) end_y = (self.launcher.y + math.sin(self.launcher.rotation) * (self.launcher.force * 10)) pygame.draw.line(self.screen, (255, 255, 255, 128), (self.launcher.x, self.launcher.y), (end_x, end_y)) # Draw projectile if self.projectile.in_motion: pygame.draw.circle(self.screen, (0, 0, 0), (int(self.projectile.x), int(self.projectile.y)), self.projectile.radius) # Draw objectives for obj in self.objectives: color = (255, 0, 0) if obj.destroyed else (255, 165, 0) pygame.draw.rect(self.screen, color, (obj.x, obj.y, obj.width, obj.height)) # Draw UI font = pygame.font.Font(None, 36) points_text = font.render(f'Points: {self.points}', True, (0, 0, 0)) attempts_text = font.render(f'Attempts: {self.attempts}', True, (0, 0, 0)) self.screen.blit(points_text, (10, 10)) self.screen.blit(attempts_text, (10, 40)) # Check for victory if all(obj.destroyed for obj in self.objectives): font = pygame.font.Font(None, 64) victory_text = font.render('Victory!', True, (0, 0, 0)) text_rect = victory_text.get_rect( center=(self.width//2, self.height//2)) self.screen.blit(victory_text, text_rect) pygame.display.flip() def run(self): """Main game loop""" running = True while running: running = self.handle_input() self.update_projectile() self.draw() self.clock.tick(60) pygame.quit() if __name__ == '__main__': game = TargetGame() game.run()
Play Game