Mystery Game #3

← Back to Games List
// Catapult Game Implementation const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); // Game objects const catapult = { x: 50, y: canvas.height - 50, width: 30, height: 30, angle: 0, power: 0 }; const projectile = { x: catapult.x, y: catapult.y, radius: 5, active: false, dx: 0, dy: 0 }; const targets = []; const gravity = 0.5; let isDragging = false; let startX = 0; let startY = 0; let score = 0; let shots = 0; // Create targets function createTargets() { for (let i = 0; i < 3; i++) { targets.push({ x: canvas.width - 200 + (i * 60), y: canvas.height - 30 - (i * 40), width: 30, height: 30, hit: false }); } } // Mouse controls canvas.addEventListener('mousedown', (e) => { const rect = canvas.getBoundingClientRect(); startX = e.clientX - rect.left; startY = e.clientY - rect.top; if (!projectile.active) { isDragging = true; } }); canvas.addEventListener('mousemove', (e) => { if (isDragging && !projectile.active) { const rect = canvas.getBoundingClientRect(); const mouseX = e.clientX - rect.left; const mouseY = e.clientY - rect.top; // Calculate angle and power from drag distance const dx = mouseX - startX; const dy = mouseY - startY; catapult.angle = Math.atan2(-dy, dx); catapult.power = Math.min(Math.sqrt(dx * dx + dy * dy) / 10, 20); } }); canvas.addEventListener('mouseup', () => { if (isDragging && !projectile.active) { launchProjectile(); shots++; } isDragging = false; }); function launchProjectile() { projectile.x = catapult.x; projectile.y = catapult.y; projectile.dx = Math.cos(catapult.angle) * catapult.power; projectile.dy = Math.sin(catapult.angle) * -catapult.power; projectile.active = true; } function updateProjectile() { if (projectile.active) { projectile.x += projectile.dx; projectile.y += projectile.dy; projectile.dy += gravity; // Check for collisions with targets targets.forEach(target => { if (!target.hit && checkCollision(projectile, target)) { target.hit = true; score += 100; } }); // Check if projectile is out of bounds if (projectile.y > canvas.height || projectile.x < 0 || projectile.x > canvas.width) { projectile.active = false; } } } function checkCollision(projectile, target) { return projectile.x > target.x && projectile.x < target.x + target.width && projectile.y > target.y && projectile.y < target.y + target.height; } function draw() { // Clear canvas ctx.fillStyle = 'skyblue'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw ground ctx.fillStyle = 'green'; ctx.fillRect(0, canvas.height - 20, canvas.width, 20); // Draw catapult ctx.save(); ctx.translate(catapult.x, catapult.y); ctx.rotate(catapult.angle); ctx.fillStyle = 'brown'; ctx.fillRect(0, -catapult.height/2, catapult.width, catapult.height); ctx.restore(); // Draw aiming line when dragging if (isDragging && !projectile.active) { ctx.beginPath(); ctx.moveTo(catapult.x, catapult.y); ctx.lineTo( catapult.x + Math.cos(catapult.angle) * (catapult.power * 10), catapult.y + Math.sin(catapult.angle) * (catapult.power * 10) ); ctx.strokeStyle = 'rgba(255,255,255,0.5)'; ctx.stroke(); } // Draw projectile if (projectile.active) { ctx.beginPath(); ctx.arc(projectile.x, projectile.y, projectile.radius, 0, Math.PI * 2); ctx.fillStyle = 'black'; ctx.fill(); } // Draw targets targets.forEach(target => { ctx.fillStyle = target.hit ? 'red' : 'orange'; ctx.fillRect(target.x, target.y, target.width, target.height); }); // Draw score and shots ctx.fillStyle = 'black'; ctx.font = '20px Arial'; ctx.fillText('Score: ' + score, 10, 30); ctx.fillText('Shots: ' + shots, 10, 60); // Check for win if (targets.every(target => target.hit)) { ctx.fillStyle = 'black'; ctx.font = '40px Arial'; ctx.fillText('You Win!', canvas.width/2 - 80, canvas.height/2); } } function startGame() { // Reset game state targets.length = 0; createTargets(); score = 0; shots = 0; projectile.active = false; catapult.angle = 0; catapult.power = 0; // Start game loop function gameLoop() { updateProjectile(); draw(); requestAnimationFrame(gameLoop); } gameLoop(); }
# Catapult Game Implementation import pygame import math from dataclasses import dataclass from typing import List @dataclass class Catapult: x: float y: float width: int = 30 height: int = 30 angle: float = 0 power: float = 0 @dataclass class Projectile: x: float y: float radius: int = 5 active: bool = False dx: float = 0 dy: float = 0 @dataclass class Target: x: float y: float width: int = 30 height: int = 30 hit: bool = False class CatapultGame: def __init__(self): pygame.init() self.width = 800 self.height = 600 self.screen = pygame.display.set_mode((self.width, self.height)) pygame.display.set_caption('Catapult Game') self.catapult = Catapult(50, self.height - 50) self.projectile = Projectile(self.catapult.x, self.catapult.y) self.targets: List[Target] = [] self.gravity = 0.5 self.is_dragging = False self.start_x = 0 self.start_y = 0 self.score = 0 self.shots = 0 self.clock = pygame.time.Clock() self.create_targets() def create_targets(self): for i in range(3): self.targets.append(Target( x=self.width - 200 + (i * 60), y=self.height - 30 - (i * 40) )) 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.projectile.active: self.start_x, self.start_y = pygame.mouse.get_pos() self.is_dragging = True elif event.type == pygame.MOUSEBUTTONUP: if self.is_dragging and not self.projectile.active: self.launch_projectile() self.shots += 1 self.is_dragging = False if self.is_dragging and not self.projectile.active: mouse_x, mouse_y = pygame.mouse.get_pos() dx = mouse_x - self.start_x dy = mouse_y - self.start_y self.catapult.angle = math.atan2(-dy, dx) self.catapult.power = min(math.sqrt(dx * dx + dy * dy) / 10, 20) return True def launch_projectile(self): self.projectile.x = self.catapult.x self.projectile.y = self.catapult.y self.projectile.dx = math.cos(self.catapult.angle) * self.catapult.power self.projectile.dy = math.sin(self.catapult.angle) * -self.catapult.power self.projectile.active = True def update(self): if self.projectile.active: self.projectile.x += self.projectile.dx self.projectile.y += self.projectile.dy self.projectile.dy += self.gravity # Check for collisions with targets for target in self.targets: if not target.hit and self.check_collision(self.projectile, target): target.hit = True self.score += 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.active = False def check_collision(self, projectile: Projectile, target: Target) -> bool: return (projectile.x > target.x and projectile.x < target.x + target.width and projectile.y > target.y and projectile.y < target.y + target.height) def draw(self): # Clear screen self.screen.fill((135, 206, 235)) # skyblue # Draw ground pygame.draw.rect(self.screen, (0, 255, 0), (0, self.height - 20, self.width, 20)) # Draw catapult surface = pygame.Surface((self.catapult.width, self.catapult.height)) surface.fill((139, 69, 19)) # brown rotated = pygame.transform.rotate( surface, -math.degrees(self.catapult.angle)) rect = rotated.get_rect( center=(self.catapult.x, self.catapult.y)) self.screen.blit(rotated, rect) # Draw aiming line if self.is_dragging and not self.projectile.active: end_x = (self.catapult.x + math.cos(self.catapult.angle) * (self.catapult.power * 10)) end_y = (self.catapult.y + math.sin(self.catapult.angle) * (self.catapult.power * 10)) pygame.draw.line(self.screen, (255, 255, 255, 128), (self.catapult.x, self.catapult.y), (end_x, end_y)) # Draw projectile if self.projectile.active: pygame.draw.circle(self.screen, (0, 0, 0), (int(self.projectile.x), int(self.projectile.y)), self.projectile.radius) # Draw targets for target in self.targets: color = (255, 0, 0) if target.hit else (255, 165, 0) pygame.draw.rect(self.screen, color, (target.x, target.y, target.width, target.height)) # Draw score and shots font = pygame.font.Font(None, 36) score_text = font.render(f'Score: {self.score}', True, (0, 0, 0)) shots_text = font.render(f'Shots: {self.shots}', True, (0, 0, 0)) self.screen.blit(score_text, (10, 10)) self.screen.blit(shots_text, (10, 40)) # Check for win if all(target.hit for target in self.targets): win_font = pygame.font.Font(None, 72) win_text = win_font.render('You Win!', True, (0, 0, 0)) text_rect = win_text.get_rect( center=(self.width/2, self.height/2)) self.screen.blit(win_text, text_rect) pygame.display.flip() def run(self): while True: if not self.handle_input(): break self.update() self.draw() self.clock.tick(60) pygame.quit() if __name__ == '__main__': game = CatapultGame() game.run()
Play Game