Mystery Game #23

← Back to Games List
// Side-Scrolling Adventure const entity = { x: 100, y: 0, width: 30, height: 50, dx: 0, dy: 0, onGround: false, facing: 1 }; const physics = { gravity: 0.5, jumpForce: -12, moveSpeed: 5, friction: 0.8 }; const terrain = [ {x: 0, y: 400, width: 800, height: 40}, {x: 200, y: 300, width: 100, height: 20}, {x: 400, y: 250, width: 100, height: 20}, {x: 600, y: 350, width: 100, height: 20} ]; const hazards = [ {x: 300, y: 380, width: 60, height: 20}, {x: 500, y: 380, width: 60, height: 20} ]; const collectibles = [ {x: 250, y: 250, collected: false}, {x: 450, y: 200, collected: false}, {x: 650, y: 300, collected: false} ]; let points = 0; let isActive = true; function updatePhysics() { if (!isActive) return; // Apply gravity entity.dy += physics.gravity; // Apply movement entity.x += entity.dx; entity.y += entity.dy; // Apply friction entity.dx *= physics.friction; // Check ground collision entity.onGround = false; for (const platform of terrain) { if (checkCollision(entity, platform)) { if (entity.dy > 0) { entity.y = platform.y - entity.height; entity.dy = 0; entity.onGround = true; } else if (entity.dy < 0) { entity.y = platform.y + platform.height; entity.dy = 0; } } } // Check hazard collision for (const hazard of hazards) { if (checkCollision(entity, hazard)) { gameOver(); return; } } // Check collectible collision for (const item of collectibles) { if (!item.collected && Math.abs(entity.x + entity.width/2 - item.x) < 20 && Math.abs(entity.y + entity.height/2 - item.y) < 20) { item.collected = true; points += 100; } } // Keep in bounds if (entity.x < 0) entity.x = 0; if (entity.x > canvas.width - entity.width) { entity.x = canvas.width - entity.width; } // Check fall death if (entity.y > canvas.height) { gameOver(); } } function checkCollision(a, b) { return a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y; } function gameOver() { isActive = false; } function render(ctx) { // Clear canvas ctx.fillStyle = '#87CEEB'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw terrain ctx.fillStyle = '#5A3A22'; for (const platform of terrain) { ctx.fillRect(platform.x, platform.y, platform.width, platform.height); } // Draw hazards ctx.fillStyle = '#FF0000'; for (const hazard of hazards) { ctx.fillRect(hazard.x, hazard.y, hazard.width, hazard.height); } // Draw collectibles ctx.fillStyle = '#FFD700'; for (const item of collectibles) { if (!item.collected) { ctx.beginPath(); ctx.arc(item.x, item.y, 10, 0, Math.PI * 2); ctx.fill(); } } // Draw entity ctx.fillStyle = '#008000'; ctx.fillRect(entity.x, entity.y, entity.width, entity.height); // Draw score ctx.fillStyle = 'black'; ctx.font = '20px Arial'; ctx.fillText('Score: ' + points, 10, 30); if (!isActive) { ctx.fillStyle = 'black'; ctx.font = '40px Arial'; ctx.fillText('Game Over!', canvas.width/2 - 100, canvas.height/2); } } document.addEventListener('keydown', (e) => { if (!isActive) return; switch(e.key) { case 'ArrowLeft': entity.dx = -physics.moveSpeed; entity.facing = -1; break; case 'ArrowRight': entity.dx = physics.moveSpeed; entity.facing = 1; break; case ' ': case 'ArrowUp': if (entity.onGround) { entity.dy = physics.jumpForce; entity.onGround = false; } break; } });
# Side-Scrolling Adventure Implementation import pygame from dataclasses import dataclass from typing import List, Tuple @dataclass class Entity: x: float y: float width: int = 30 height: int = 50 dx: float = 0 dy: float = 0 on_ground: bool = False facing: int = 1 @dataclass class Physics: gravity: float = 0.5 jump_force: float = -12 move_speed: float = 5 friction: float = 0.8 @dataclass class Platform: x: int y: int width: int height: int @dataclass class Collectible: x: int y: int collected: bool = False class PlatformerGame: def __init__(self): pygame.init() # Game settings self.width = 800 self.height = 600 # Initialize display self.screen = pygame.display.set_mode((self.width, self.height)) pygame.display.set_caption('Side-Scrolling Adventure') self.clock = pygame.time.Clock() # Game objects self.entity = Entity(100, 0) self.physics = Physics() # Level objects self.terrain = [ Platform(0, 400, 800, 40), Platform(200, 300, 100, 20), Platform(400, 250, 100, 20), Platform(600, 350, 100, 20) ] self.hazards = [ Platform(300, 380, 60, 20), Platform(500, 380, 60, 20) ] self.collectibles = [ Collectible(250, 250), Collectible(450, 200), Collectible(650, 300) ] # Game state self.points = 0 self.is_active = True def check_collision(self, a: Entity, b: Platform) -> bool: """Check collision between two rectangles""" return (a.x < b.x + b.width and a.x + a.width > b.x and a.y < b.y + b.height and a.y + a.height > b.y) def update_physics(self): """Update game physics""" if not self.is_active: return # Apply gravity self.entity.dy += self.physics.gravity # Apply movement self.entity.x += self.entity.dx self.entity.y += self.entity.dy # Apply friction self.entity.dx *= self.physics.friction # Check ground collision self.entity.on_ground = False for platform in self.terrain: if self.check_collision(self.entity, platform): if self.entity.dy > 0: self.entity.y = platform.y - self.entity.height self.entity.dy = 0 self.entity.on_ground = True elif self.entity.dy < 0: self.entity.y = platform.y + platform.height self.entity.dy = 0 # Check hazard collision for hazard in self.hazards: if self.check_collision(self.entity, hazard): self.game_over() return # Check collectible collision for item in self.collectibles: if (not item.collected and abs(self.entity.x + self.entity.width/2 - item.x) < 20 and abs(self.entity.y + self.entity.height/2 - item.y) < 20): item.collected = True self.points += 100 # Keep in bounds if self.entity.x < 0: self.entity.x = 0 if self.entity.x > self.width - self.entity.width: self.entity.x = self.width - self.entity.width # Check fall death if self.entity.y > self.height: self.game_over() def game_over(self): """End the game""" self.is_active = False def handle_input(self) -> bool: """Handle keyboard input""" for event in pygame.event.get(): if event.type == pygame.QUIT: return False if event.type == pygame.KEYDOWN: if not self.is_active: continue if event.key == pygame.K_SPACE or event.key == pygame.K_UP: if self.entity.on_ground: self.entity.dy = self.physics.jump_force self.entity.on_ground = False # Continuous key input if self.is_active: keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: self.entity.dx = -self.physics.move_speed self.entity.facing = -1 elif keys[pygame.K_RIGHT]: self.entity.dx = self.physics.move_speed self.entity.facing = 1 return True def draw(self): """Draw the game state""" # Clear screen self.screen.fill((135, 206, 235)) # Sky blue # Draw terrain for platform in self.terrain: pygame.draw.rect(self.screen, (90, 58, 34), # Brown (platform.x, platform.y, platform.width, platform.height)) # Draw hazards for hazard in self.hazards: pygame.draw.rect(self.screen, (255, 0, 0), # Red (hazard.x, hazard.y, hazard.width, hazard.height)) # Draw collectibles for item in self.collectibles: if not item.collected: pygame.draw.circle(self.screen, (255, 215, 0), # Gold (item.x, item.y), 10) # Draw entity pygame.draw.rect(self.screen, (0, 128, 0), # Green (int(self.entity.x), int(self.entity.y), self.entity.width, self.entity.height)) # Draw score font = pygame.font.Font(None, 36) score_text = font.render(f'Score: {self.points}', True, (0, 0, 0)) self.screen.blit(score_text, (10, 10)) # Draw game over if not self.is_active: font = pygame.font.Font(None, 64) game_over = font.render('Game Over!', True, (0, 0, 0)) text_rect = game_over.get_rect( center=(self.width//2, self.height//2)) self.screen.blit(game_over, text_rect) pygame.display.flip() def run(self): """Main game loop""" running = True while running: running = self.handle_input() self.update_physics() self.draw() self.clock.tick(60) pygame.quit() if __name__ == '__main__': game = PlatformerGame() game.run()
Play Game