Mystery Game #24
← Back to Games List
// Two Player Combat Game
const entity1 = {
x: 100,
y: 300,
angle: 0,
dx: 0,
dy: 0,
speed: 0,
rotationSpeed: 0.1,
isRotatingLeft: false,
isRotatingRight: false,
isMoving: false,
points: 0
};
const entity2 = {
x: 700,
y: 300,
angle: Math.PI,
dx: 0,
dy: 0,
speed: 0,
rotationSpeed: 0.1,
isRotatingLeft: false,
isRotatingRight: false,
isMoving: false,
points: 0
};
const projectiles = [];
const obstacles = [
{x: 200, y: 100, width: 40, height: 200},
{x: 600, y: 300, width: 40, height: 200},
{x: 400, y: 200, width: 200, height: 40}
];
const physics = {
acceleration: 0.2,
maxSpeed: 4,
friction: 0.98,
projectileSpeed: 7,
reloadTime: 60
};
let reloadTimer1 = 0;
let reloadTimer2 = 0;
let isActive = true;
function updatePositions() {
if (!isActive) return;
// Update entity1
if (entity1.isRotatingLeft) entity1.angle -= entity1.rotationSpeed;
if (entity1.isRotatingRight) entity1.angle += entity1.rotationSpeed;
if (entity1.isMoving) {
entity1.speed = Math.min(entity1.speed + physics.acceleration,
physics.maxSpeed);
} else {
entity1.speed *= physics.friction;
}
entity1.dx = Math.cos(entity1.angle) * entity1.speed;
entity1.dy = Math.sin(entity1.angle) * entity1.speed;
let newX1 = entity1.x + entity1.dx;
let newY1 = entity1.y + entity1.dy;
if (!checkCollisions(newX1, newY1)) {
entity1.x = newX1;
entity1.y = newY1;
}
// Update entity2
if (entity2.isRotatingLeft) entity2.angle -= entity2.rotationSpeed;
if (entity2.isRotatingRight) entity2.angle += entity2.rotationSpeed;
if (entity2.isMoving) {
entity2.speed = Math.min(entity2.speed + physics.acceleration,
physics.maxSpeed);
} else {
entity2.speed *= physics.friction;
}
entity2.dx = Math.cos(entity2.angle) * entity2.speed;
entity2.dy = Math.sin(entity2.angle) * entity2.speed;
let newX2 = entity2.x + entity2.dx;
let newY2 = entity2.y + entity2.dy;
if (!checkCollisions(newX2, newY2)) {
entity2.x = newX2;
entity2.y = newY2;
}
// Update projectiles
for (let i = projectiles.length - 1; i >= 0; i--) {
const p = projectiles[i];
p.x += p.dx;
p.y += p.dy;
// Check wall collisions
if (p.x < 0 || p.x > canvas.width ||
p.y < 0 || p.y > canvas.height) {
projectiles.splice(i, 1);
continue;
}
// Check obstacle collisions
for (const obs of obstacles) {
if (p.x > obs.x && p.x < obs.x + obs.width &&
p.y > obs.y && p.y < obs.y + obs.height) {
projectiles.splice(i, 1);
break;
}
}
// Check entity collisions
if (Math.hypot(p.x - entity1.x, p.y - entity1.y) < 20 &&
p.owner !== 1) {
entity2.points++;
resetRound();
break;
}
if (Math.hypot(p.x - entity2.x, p.y - entity2.y) < 20 &&
p.owner !== 2) {
entity1.points++;
resetRound();
break;
}
}
// Update reload timers
if (reloadTimer1 > 0) reloadTimer1--;
if (reloadTimer2 > 0) reloadTimer2--;
}
function checkCollisions(x, y) {
// Check bounds
if (x < 0 || x > canvas.width || y < 0 || y > canvas.height) {
return true;
}
// Check obstacles
for (const obs of obstacles) {
if (x > obs.x - 20 && x < obs.x + obs.width + 20 &&
y > obs.y - 20 && y < obs.y + obs.height + 20) {
return true;
}
}
return false;
}
function shoot(entity, id) {
if ((id === 1 && reloadTimer1 > 0) ||
(id === 2 && reloadTimer2 > 0)) return;
projectiles.push({
x: entity.x + Math.cos(entity.angle) * 30,
y: entity.y + Math.sin(entity.angle) * 30,
dx: Math.cos(entity.angle) * physics.projectileSpeed,
dy: Math.sin(entity.angle) * physics.projectileSpeed,
owner: id
});
if (id === 1) reloadTimer1 = physics.reloadTime;
else reloadTimer2 = physics.reloadTime;
}
function resetRound() {
entity1.x = 100;
entity1.y = 300;
entity1.angle = 0;
entity1.speed = 0;
entity2.x = 700;
entity2.y = 300;
entity2.angle = Math.PI;
entity2.speed = 0;
projectiles.length = 0;
reloadTimer1 = 0;
reloadTimer2 = 0;
}
function render(ctx) {
// Clear canvas
ctx.fillStyle = '#222';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw obstacles
ctx.fillStyle = '#666';
for (const obs of obstacles) {
ctx.fillRect(obs.x, obs.y, obs.width, obs.height);
}
// Draw entities
function drawEntity(entity, color) {
ctx.save();
ctx.translate(entity.x, entity.y);
ctx.rotate(entity.angle);
ctx.fillStyle = color;
ctx.fillRect(-15, -10, 30, 20);
ctx.fillRect(0, -3, 20, 6);
ctx.restore();
}
drawEntity(entity1, '#0F0');
drawEntity(entity2, '#F00');
// Draw projectiles
ctx.fillStyle = '#FFF';
for (const p of projectiles) {
ctx.beginPath();
ctx.arc(p.x, p.y, 3, 0, Math.PI * 2);
ctx.fill();
}
// Draw scores
ctx.fillStyle = '#0F0';
ctx.font = '24px Arial';
ctx.fillText(entity1.points, 50, 40);
ctx.fillStyle = '#F00';
ctx.fillText(entity2.points, canvas.width - 70, 40);
// Draw reload bars
if (reloadTimer1 > 0) {
ctx.fillStyle = '#0F0';
ctx.fillRect(20, 50,
(physics.reloadTime - reloadTimer1) *
50 / physics.reloadTime, 5);
}
if (reloadTimer2 > 0) {
ctx.fillStyle = '#F00';
ctx.fillRect(canvas.width - 70, 50,
(physics.reloadTime - reloadTimer2) *
50 / physics.reloadTime, 5);
}
}
# Two Player Combat Game Implementation
import pygame
import math
from dataclasses import dataclass
from typing import List, Tuple
@dataclass
class Entity:
x: float
y: float
angle: float
dx: float = 0
dy: float = 0
speed: float = 0
rotation_speed: float = 0.1
is_rotating_left: bool = False
is_rotating_right: bool = False
is_moving: bool = False
points: int = 0
@dataclass
class Physics:
acceleration: float = 0.2
max_speed: float = 4
friction: float = 0.98
projectile_speed: float = 7
reload_time: int = 60
@dataclass
class Obstacle:
x: int
y: int
width: int
height: int
@dataclass
class Projectile:
x: float
y: float
dx: float
dy: float
owner: int
class CombatGame:
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('Combat Game')
self.clock = pygame.time.Clock()
# Game objects
self.entity1 = Entity(100, 300, 0)
self.entity2 = Entity(700, 300, math.pi)
self.physics = Physics()
self.obstacles = [
Obstacle(200, 100, 40, 200),
Obstacle(600, 300, 40, 200),
Obstacle(400, 200, 200, 40)
]
self.projectiles: List[Projectile] = []
self.reload_timer1 = 0
self.reload_timer2 = 0
self.is_active = True
def check_collisions(self, x: float, y: float) -> bool:
"""Check if position collides with bounds or obstacles"""
# Check bounds
if x < 0 or x > self.width or y < 0 or y > self.height:
return True
# Check obstacles
for obs in self.obstacles:
if (x > obs.x - 20 and x < obs.x + obs.width + 20 and
y > obs.y - 20 and y < obs.y + obs.height + 20):
return True
return False
def shoot(self, entity: Entity, id: int):
"""Create new projectile"""
if ((id == 1 and self.reload_timer1 > 0) or
(id == 2 and self.reload_timer2 > 0)):
return
self.projectiles.append(
Projectile(
x=entity.x + math.cos(entity.angle) * 30,
y=entity.y + math.sin(entity.angle) * 30,
dx=math.cos(entity.angle) * self.physics.projectile_speed,
dy=math.sin(entity.angle) * self.physics.projectile_speed,
owner=id
)
)
if id == 1:
self.reload_timer1 = self.physics.reload_time
else:
self.reload_timer2 = self.physics.reload_time
def reset_round(self):
"""Reset entities to starting positions"""
self.entity1.x = 100
self.entity1.y = 300
self.entity1.angle = 0
self.entity1.speed = 0
self.entity2.x = 700
self.entity2.y = 300
self.entity2.angle = math.pi
self.entity2.speed = 0
self.projectiles.clear()
self.reload_timer1 = 0
self.reload_timer2 = 0
def update_positions(self):
"""Update game physics"""
if not self.is_active:
return
# Update entity1
if self.entity1.is_rotating_left:
self.entity1.angle -= self.entity1.rotation_speed
if self.entity1.is_rotating_right:
self.entity1.angle += self.entity1.rotation_speed
if self.entity1.is_moving:
self.entity1.speed = min(
self.entity1.speed + self.physics.acceleration,
self.physics.max_speed)
else:
self.entity1.speed *= self.physics.friction
self.entity1.dx = math.cos(self.entity1.angle) * self.entity1.speed
self.entity1.dy = math.sin(self.entity1.angle) * self.entity1.speed
new_x1 = self.entity1.x + self.entity1.dx
new_y1 = self.entity1.y + self.entity1.dy
if not self.check_collisions(new_x1, new_y1):
self.entity1.x = new_x1
self.entity1.y = new_y1
# Update entity2
if self.entity2.is_rotating_left:
self.entity2.angle -= self.entity2.rotation_speed
if self.entity2.is_rotating_right:
self.entity2.angle += self.entity2.rotation_speed
if self.entity2.is_moving:
self.entity2.speed = min(
self.entity2.speed + self.physics.acceleration,
self.physics.max_speed)
else:
self.entity2.speed *= self.physics.friction
self.entity2.dx = math.cos(self.entity2.angle) * self.entity2.speed
self.entity2.dy = math.sin(self.entity2.angle) * self.entity2.speed
new_x2 = self.entity2.x + self.entity2.dx
new_y2 = self.entity2.y + self.entity2.dy
if not self.check_collisions(new_x2, new_y2):
self.entity2.x = new_x2
self.entity2.y = new_y2
# Update projectiles
for projectile in self.projectiles[:]:
projectile.x += projectile.dx
projectile.y += projectile.dy
# Check wall collisions
if (projectile.x < 0 or projectile.x > self.width or
projectile.y < 0 or projectile.y > self.height):
self.projectiles.remove(projectile)
continue
# Check obstacle collisions
for obs in self.obstacles:
if (projectile.x > obs.x and
projectile.x < obs.x + obs.width and
projectile.y > obs.y and
projectile.y < obs.y + obs.height):
self.projectiles.remove(projectile)
break
# Check entity collisions
if projectile in self.projectiles: # Still exists
dist1 = math.hypot(
projectile.x - self.entity1.x,
projectile.y - self.entity1.y)
if dist1 < 20 and projectile.owner != 1:
self.entity2.points += 1
self.reset_round()
break
dist2 = math.hypot(
projectile.x - self.entity2.x,
projectile.y - self.entity2.y)
if dist2 < 20 and projectile.owner != 2:
self.entity1.points += 1
self.reset_round()
break
# Update reload timers
if self.reload_timer1 > 0:
self.reload_timer1 -= 1
if self.reload_timer2 > 0:
self.reload_timer2 -= 1
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:
# Entity 1 controls (WASD + Space)
if event.key == pygame.K_a:
self.entity1.is_rotating_left = True
elif event.key == pygame.K_d:
self.entity1.is_rotating_right = True
elif event.key == pygame.K_w:
self.entity1.is_moving = True
elif event.key == pygame.K_SPACE:
self.shoot(self.entity1, 1)
# Entity 2 controls (Arrows + Enter)
elif event.key == pygame.K_LEFT:
self.entity2.is_rotating_left = True
elif event.key == pygame.K_RIGHT:
self.entity2.is_rotating_right = True
elif event.key == pygame.K_UP:
self.entity2.is_moving = True
elif event.key == pygame.K_RETURN:
self.shoot(self.entity2, 2)
elif event.type == pygame.KEYUP:
# Entity 1 controls
if event.key == pygame.K_a:
self.entity1.is_rotating_left = False
elif event.key == pygame.K_d:
self.entity1.is_rotating_right = False
elif event.key == pygame.K_w:
self.entity1.is_moving = False
# Entity 2 controls
elif event.key == pygame.K_LEFT:
self.entity2.is_rotating_left = False
elif event.key == pygame.K_RIGHT:
self.entity2.is_rotating_right = False
elif event.key == pygame.K_UP:
self.entity2.is_moving = False
return True
def draw(self):
"""Draw the game state"""
# Clear screen
self.screen.fill((34, 34, 34)) # Dark gray
# Draw obstacles
for obs in self.obstacles:
pygame.draw.rect(self.screen, (102, 102, 102),
(obs.x, obs.y, obs.width, obs.height))
# Draw entities
def draw_entity(entity: Entity, color: Tuple[int, int, int]):
surface = pygame.Surface((40, 20), pygame.SRCALPHA)
pygame.draw.rect(surface, color, (5, 0, 30, 20))
pygame.draw.rect(surface, color, (20, 7, 20, 6))
rotated = pygame.transform.rotate(
surface, -math.degrees(entity.angle))
rect = rotated.get_rect(
center=(entity.x, entity.y))
self.screen.blit(rotated, rect)
draw_entity(self.entity1, (0, 255, 0)) # Green
draw_entity(self.entity2, (255, 0, 0)) # Red
# Draw projectiles
for proj in self.projectiles:
pygame.draw.circle(self.screen, (255, 255, 255),
(int(proj.x), int(proj.y)), 3)
# Draw scores
font = pygame.font.Font(None, 36)
score1 = font.render(str(self.entity1.points),
True, (0, 255, 0))
score2 = font.render(str(self.entity2.points),
True, (255, 0, 0))
self.screen.blit(score1, (50, 20))
self.screen.blit(score2, (self.width - 70, 20))
# Draw reload bars
if self.reload_timer1 > 0:
width = ((self.physics.reload_time - self.reload_timer1) *
50 / self.physics.reload_time)
pygame.draw.rect(self.screen, (0, 255, 0),
(20, 50, width, 5))
if self.reload_timer2 > 0:
width = ((self.physics.reload_time - self.reload_timer2) *
50 / self.physics.reload_time)
pygame.draw.rect(self.screen, (255, 0, 0),
(self.width - 70, 50, width, 5))
pygame.display.flip()
def run(self):
"""Main game loop"""
running = True
while running:
running = self.handle_input()
self.update_positions()
self.draw()
self.clock.tick(60)
pygame.quit()
if __name__ == '__main__':
game = CombatGame()
game.run()
Play Game