Mystery Game #20
← Back to Games List
// Maze Collection Game
const gridSize = 20;
const cols = 28;
const rows = 31;
const layout = [
'############################',
'#............##............#',
'#.####.#####.##.#####.####.#',
'#.####.#####.##.#####.####.#',
'#.####.#####.##.#####.####.#',
'#..........................#',
'#.####.##.########.##.####.#',
'#.####.##.########.##.####.#',
'#......##....##....##......#',
'######.##### ## #####.######',
' #.##### ## #####.# ',
' #.## ##.# ',
' #.## ###--### ##.# ',
'######.## # # ##.######',
' . # # . ',
'######.## # # ##.######',
' #.## ######## ##.# ',
' #.## ##.# ',
' #.## ######## ##.# ',
'######.## ######## ##.######',
'#............##............#',
'#.####.#####.##.#####.####.#',
'#.####.#####.##.#####.####.#',
'#...##................##...#',
'###.##.##.########.##.##.###',
'#......##....##....##......#',
'#.##########.##.##########.#',
'#.##########.##.##########.#',
'#..........................#',
'############################'
];
const entity = {
x: 14,
y: 23,
dx: 0,
dy: 0,
angle: 0,
speed: 0.15
};
const collectors = [];
const targets = [];
let points = 0;
let isActive = true;
function initializeGame() {
// Parse layout
for (let y = 0; y < rows; y++) {
for (let x = 0; x < cols; x++) {
if (layout[y][x] === '.') {
collectors.push({x, y});
} else if (layout[y][x] === 'o') {
targets.push({x, y, active: true});
}
}
}
}
function updateGame() {
if (!isActive) return;
// Update entity position
const newX = entity.x + entity.dx * entity.speed;
const newY = entity.y + entity.dy * entity.speed;
// Check wall collision
if (!isWall(Math.floor(newX), Math.floor(newY))) {
entity.x = newX;
entity.y = newY;
}
// Wrap around tunnels
if (entity.x < 0) entity.x = cols - 1;
if (entity.x >= cols) entity.x = 0;
// Collect items
for (let i = collectors.length - 1; i >= 0; i--) {
const c = collectors[i];
const dx = c.x - entity.x;
const dy = c.y - entity.y;
if (Math.sqrt(dx * dx + dy * dy) < 0.5) {
collectors.splice(i, 1);
points += 10;
}
}
// Check win condition
if (collectors.length === 0) {
isActive = false;
showMessage('Victory!');
}
}
function isWall(x, y) {
if (y < 0 || y >= rows || x < 0 || x >= cols) return true;
return layout[y][x] === '#';
}
function render(ctx) {
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw walls
ctx.fillStyle = 'blue';
for (let y = 0; y < rows; y++) {
for (let x = 0; x < cols; x++) {
if (layout[y][x] === '#') {
ctx.fillRect(x * gridSize, y * gridSize,
gridSize, gridSize);
}
}
}
// Draw collectors
ctx.fillStyle = 'white';
collectors.forEach(c => {
ctx.beginPath();
ctx.arc(c.x * gridSize + gridSize/2,
c.y * gridSize + gridSize/2,
2, 0, Math.PI * 2);
ctx.fill();
});
// Draw entity
ctx.fillStyle = 'yellow';
ctx.beginPath();
ctx.arc(entity.x * gridSize + gridSize/2,
entity.y * gridSize + gridSize/2,
gridSize/2 - 2,
entity.angle + Math.PI/6,
entity.angle + Math.PI * 2 - Math.PI/6);
ctx.lineTo(entity.x * gridSize + gridSize/2,
entity.y * gridSize + gridSize/2);
ctx.fill();
// Draw score
ctx.fillStyle = 'white';
ctx.font = '20px Arial';
ctx.fillText('Score: ' + points, 10, 20);
}
document.addEventListener('keydown', (e) => {
switch(e.key) {
case 'ArrowLeft':
entity.dx = -1;
entity.dy = 0;
entity.angle = Math.PI;
break;
case 'ArrowRight':
entity.dx = 1;
entity.dy = 0;
entity.angle = 0;
break;
case 'ArrowUp':
entity.dx = 0;
entity.dy = -1;
entity.angle = -Math.PI/2;
break;
case 'ArrowDown':
entity.dx = 0;
entity.dy = 1;
entity.angle = Math.PI/2;
break;
}
});
# Maze Collection Game Implementation
import pygame
import math
from dataclasses import dataclass
from typing import List, Tuple
@dataclass
class Entity:
x: float
y: float
dx: float = 0
dy: float = 0
angle: float = 0
speed: float = 0.15
@dataclass
class Collector:
x: int
y: int
class MazeGame:
def __init__(self):
pygame.init()
# Game settings
self.grid_size = 20
self.cols = 28
self.rows = 31
self.width = self.cols * self.grid_size
self.height = self.rows * self.grid_size
# Initialize display
self.screen = pygame.display.set_mode((self.width, self.height))
pygame.display.set_caption('Maze Collection')
self.clock = pygame.time.Clock()
# Game objects
self.entity = Entity(14, 23)
self.collectors: List[Collector] = []
self.points = 0
self.is_active = True
# Maze layout
self.layout = [
'############################',
'#............##............#',
'#.####.#####.##.#####.####.#',
'#.####.#####.##.#####.####.#',
'#.####.#####.##.#####.####.#',
'#..........................#',
'#.####.##.########.##.####.#',
'#.####.##.########.##.####.#',
'#......##....##....##......#',
'######.##### ## #####.######',
' #.##### ## #####.# ',
' #.## ##.# ',
' #.## ###--### ##.# ',
'######.## # # ##.######',
' . # # . ',
'######.## # # ##.######',
' #.## ######## ##.# ',
' #.## ##.# ',
' #.## ######## ##.# ',
'######.## ######## ##.######',
'#............##............#',
'#.####.#####.##.#####.####.#',
'#.####.#####.##.#####.####.#',
'#...##................##...#',
'###.##.##.########.##.##.###',
'#......##....##....##......#',
'#.##########.##.##########.#',
'#.##########.##.##########.#',
'#..........................#',
'############################'
]
self.initialize_game()
def initialize_game(self):
"""Initialize game state and parse layout"""
self.collectors.clear()
# Parse layout
for y in range(self.rows):
for x in range(self.cols):
if self.layout[y][x] == '.':
self.collectors.append(Collector(x, y))
def is_wall(self, x: int, y: int) -> bool:
"""Check if position contains a wall"""
if y < 0 or y >= self.rows or x < 0 or x >= self.cols:
return True
return self.layout[y][x] == '#'
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 event.key == pygame.K_LEFT:
self.entity.dx = -1
self.entity.dy = 0
self.entity.angle = math.pi
elif event.key == pygame.K_RIGHT:
self.entity.dx = 1
self.entity.dy = 0
self.entity.angle = 0
elif event.key == pygame.K_UP:
self.entity.dx = 0
self.entity.dy = -1
self.entity.angle = -math.pi/2
elif event.key == pygame.K_DOWN:
self.entity.dx = 0
self.entity.dy = 1
self.entity.angle = math.pi/2
return True
def update_game(self):
"""Update game state"""
if not self.is_active:
return
# Update entity position
new_x = self.entity.x + self.entity.dx * self.entity.speed
new_y = self.entity.y + self.entity.dy * self.entity.speed
# Check wall collision
if not self.is_wall(int(new_x), int(new_y)):
self.entity.x = new_x
self.entity.y = new_y
# Wrap around tunnels
if self.entity.x < 0:
self.entity.x = self.cols - 1
if self.entity.x >= self.cols:
self.entity.x = 0
# Collect items
for collector in self.collectors[:]:
dx = collector.x - self.entity.x
dy = collector.y - self.entity.y
if math.sqrt(dx * dx + dy * dy) < 0.5:
self.collectors.remove(collector)
self.points += 10
# Check win condition
if not self.collectors:
self.is_active = False
def draw(self):
"""Draw the game state"""
# Clear screen
self.screen.fill((0, 0, 0)) # Black background
# Draw walls
for y in range(self.rows):
for x in range(self.cols):
if self.layout[y][x] == '#':
pygame.draw.rect(self.screen, (0, 0, 255), # Blue
(x * self.grid_size,
y * self.grid_size,
self.grid_size,
self.grid_size))
# Draw collectors
for collector in self.collectors:
pygame.draw.circle(self.screen, (255, 255, 255), # White
(int(collector.x * self.grid_size + self.grid_size/2),
int(collector.y * self.grid_size + self.grid_size/2)),
2)
# Draw entity (Pac-Man style)
center_x = int(self.entity.x * self.grid_size + self.grid_size/2)
center_y = int(self.entity.y * self.grid_size + self.grid_size/2)
radius = self.grid_size/2 - 2
# Draw mouth animation
start_angle = self.entity.angle + math.pi/6
end_angle = self.entity.angle + math.pi * 2 - math.pi/6
pygame.draw.arc(self.screen, (255, 255, 0), # Yellow
(center_x - radius,
center_y - radius,
radius * 2,
radius * 2),
start_angle,
end_angle,
int(radius))
# Draw line to center (mouth)
end_x = center_x + math.cos(self.entity.angle) * radius
end_y = center_y + math.sin(self.entity.angle) * radius
pygame.draw.line(self.screen, (255, 255, 0),
(center_x, center_y),
(int(end_x), int(end_y)))
# Draw score
font = pygame.font.Font(None, 36)
score_text = font.render(f'Score: {self.points}',
True, (255, 255, 255))
self.screen.blit(score_text, (10, 10))
# Draw victory message
if not self.is_active:
font = pygame.font.Font(None, 64)
victory_text = font.render('Victory!', True, (255, 255, 255))
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_game()
self.draw()
self.clock.tick(60)
pygame.quit()
if __name__ == '__main__':
game = MazeGame()
game.run()
Play Game