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