Skip to content

Commit ebab023

Browse files
authored
Create enemy.py
1 parent c688871 commit ebab023

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

Shadow-Labyrinth/enemy.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import pygame
2+
import math
3+
import random
4+
5+
TILE_SIZE = 40
6+
ENEMY_SPEED = 2
7+
HEARING_RANGE = 250
8+
SIGHT_RANGE = 180
9+
PATROL_SPEED = 1
10+
11+
class Enemy(pygame.sprite.Sprite):
12+
def __init__(self, color, walls, damage=10):
13+
super().__init__()
14+
self.image = pygame.Surface((TILE_SIZE // 2, TILE_SIZE // 2))
15+
self.image.fill(color)
16+
self.rect = self.image.get_rect(center=self.random_position(walls))
17+
self.target = None
18+
self.damage = damage
19+
20+
def random_position(self, walls):
21+
pos = (random.randint(TILE_SIZE, 800 - TILE_SIZE), random.randint(TILE_SIZE, 600 - TILE_SIZE))
22+
while any(self.rect.colliderect(wall.rect) for wall in walls):
23+
pos = (random.randint(TILE_SIZE, 800 - TILE_SIZE), random.randint(TILE_SIZE, 600 - TILE_SIZE))
24+
return pos
25+
26+
def move_towards(self, target_pos, walls, speed=ENEMY_SPEED):
27+
dx = target_pos[0] - self.rect.centerx
28+
dy = target_pos[1] - self.rect.centery
29+
dist = math.hypot(dx, dy)
30+
if dist > 0:
31+
dx, dy = dx / dist * speed, dy / dist * speed
32+
new_rect = self.rect.move(dx, dy)
33+
if not any(new_rect.colliderect(wall.rect) for wall in walls):
34+
self.rect = new_rect
35+
36+
def is_in_light(self, light_positions):
37+
for pos, radius in light_positions:
38+
dist = math.hypot(self.rect.centerx - pos[0], self.rect.centery - pos[1])
39+
if dist < radius:
40+
return True
41+
return False
42+
43+
class SoundEnemy(Enemy):
44+
def __init__(self, walls):
45+
super().__init__((255, 0, 0), walls, damage=15)
46+
self.heard_sounds = [] # List of (pos, strength)
47+
48+
def update(self, player, walls, sound_pos, light_positions):
49+
if sound_pos:
50+
dist = math.hypot(self.rect.centerx - sound_pos[0], self.rect.centery - sound_pos[1])
51+
if dist < HEARING_RANGE:
52+
strength = HEARING_RANGE - dist
53+
self.heard_sounds.append((sound_pos, strength))
54+
if self.heard_sounds:
55+
self.heard_sounds = [(pos, str - 1) for pos, str in self.heard_sounds if str > 0]
56+
if self.heard_sounds:
57+
strongest = max(self.heard_sounds, key=lambda x: x[1])
58+
self.move_towards(strongest[0], walls)
59+
elif self.is_in_light(light_positions):
60+
self.move_towards(player.rect.center, walls)
61+
62+
class LightEnemy(Enemy):
63+
def __init__(self, walls):
64+
super().__init__((0, 0, 255), walls, damage=20)
65+
66+
def update(self, player, walls, sound_pos, light_positions):
67+
if self.is_in_light(light_positions):
68+
self.move_towards(player.rect.center, walls, speed=ENEMY_SPEED * 1.2)
69+
elif sound_pos and random.random() < 0.5:
70+
dist = math.hypot(self.rect.centerx - sound_pos[0], self.rect.centery - sound_pos[1])
71+
if dist < HEARING_RANGE / 2:
72+
self.move_towards(sound_pos, walls)
73+
74+
class PatrolEnemy(Enemy):
75+
def __init__(self, walls):
76+
super().__init__((0, 255, 0), walls, damage=10)
77+
self.patrol_points = [self.random_position(walls) for _ in range(4)]
78+
self.current_patrol = 0
79+
80+
def update(self, player, walls, sound_pos, light_positions):
81+
if self.is_in_light(light_positions):
82+
self.move_towards(player.rect.center, walls)
83+
elif sound_pos:
84+
dist = math.hypot(self.rect.centerx - sound_pos[0], self.rect.centery - sound_pos[1])
85+
if dist < HEARING_RANGE:
86+
self.move_towards(sound_pos, walls)
87+
else:
88+
# Patrol
89+
target = self.patrol_points[self.current_patrol]
90+
self.move_towards(target, walls, speed=PATROL_SPEED)
91+
if math.hypot(self.rect.centerx - target[0], self.rect.centery - target[1]) < 10:
92+
self.current_patrol = (self.current_patrol + 1) % len(self.patrol_points)

0 commit comments

Comments
 (0)