diff --git a/map/levels/1.json b/map/levels/1.json index e0f1904..24b74fe 100644 --- a/map/levels/1.json +++ b/map/levels/1.json @@ -177,7 +177,7 @@ "attack_interval": 2.0, "attack_range": 300, "sprite_sheet": "assets/map/enemy/turret.gif", - "size": [50,100] + "size": [80,80] }, { "id": "enemy3_01", @@ -206,7 +206,7 @@ "attack_interval": 2.0, "attack_range": 300, "sprite_sheet": "assets/map/enemy/turret.gif", - "size": [50,100] + "size": [80,80] } ], diff --git a/map/levels/2.json b/map/levels/2.json index 91c06a9..afe2ddf 100644 --- a/map/levels/2.json +++ b/map/levels/2.json @@ -272,7 +272,7 @@ "attack_interval": 2.0, "attack_range": 300, "sprite_sheet": "assets/map/enemy/turret.gif", - "size": [50,100] + "size": [80,80] }, { "id": "enemy2_02", @@ -343,7 +343,7 @@ "attack_interval": 2.0, "attack_range": 300, "sprite_sheet": "assets/map/enemy/turret.gif", - "size": [50,100] + "size": [80,80] }, { "id": "enemy1_05", @@ -356,7 +356,7 @@ "attack_interval": 2.0, "attack_range": 300, "sprite_sheet": "assets/map/enemy/turret.gif", - "size": [50,100] + "size": [80,80] }, { "id": "enemy1_06", diff --git a/map_test.json b/map_test.json index fd9c603..2b4847b 100644 --- a/map_test.json +++ b/map_test.json @@ -135,6 +135,19 @@ "attack_interval": 2.0, "attack_range": 300, "sprite_sheet": "assets/map/enemy/turret_enemy.png" + }, + { + "id": "boss", + "type": "boss", + "x": 2000, + "y": 0, + "health": 3, + "damage": 1, + "behavior": "boss", + "attack_interval": 1.0, + "attack_range": 1000, + "sprite_sheet": "assets/map/enemy/boss.gif", + "size": [200,200] } ], diff --git a/src/Entity/Enemy.py b/src/Entity/Enemy.py index 015ea5b..e8dedc9 100644 --- a/src/Entity/Enemy.py +++ b/src/Entity/Enemy.py @@ -9,6 +9,7 @@ from src.Entity.Projectile import Projectile class Enemy(Entity): def __init__(self, enemy_data): self.size = enemy_data.get("size", [50, 50]) + print(self.size) super().__init__(self.size) # Base attributes @@ -30,13 +31,13 @@ class Enemy(Entity): sprite_path = enemy_data.get("sprite_sheet", "assets/enemy/default_enemy.png") # Load sprite sheet or GIF depending on enemy type and file extension - if sprite_path.lower().endswith(".gif") and self.enemy_type == "turret": - self.load_gif_frames(sprite_path) + if sprite_path.lower().endswith(".gif"): + self.load_gif_frames(sprite_path, self.size) if self.frames: self.surf = self.frames[0] else: # Default sprite - self.surf = pygame.Surface((40, 40)) + self.surf = pygame.Surface(self.size) self.surf.fill((255, 0, 0)) else: try: @@ -44,7 +45,7 @@ class Enemy(Entity): self.surf = pygame.transform.scale(self.surf, self.size) except: # Default sprite - self.surf = pygame.Surface((40, 40)) + self.surf = pygame.Surface(self.size) self.surf.fill((255, 0, 0)) # Initial rectangle @@ -63,7 +64,7 @@ class Enemy(Entity): self.is_attacking = False self.detected_player = False - def load_gif_frames(self, gif_path): + def load_gif_frames(self, gif_path, size=(80, 80)): """Load frames from a GIF file""" try: gif = Image.open(gif_path) @@ -73,7 +74,7 @@ class Enemy(Entity): frame_surface = pygame.image.fromstring( frame.convert("RGBA").tobytes(), frame.size, "RGBA" ) - frame_surface = pygame.transform.scale(frame_surface, (80, 80)) + frame_surface = pygame.transform.scale(frame_surface, size) self.frames.append(frame_surface) frame_count += 1 @@ -92,9 +93,11 @@ class Enemy(Entity): self.chase(player) elif self.behavior == "stationary" and player: self.stationary_attack(player) + elif self.behavior == "boss" and player: + self.boss(player) # Animation management for turret enemies - if self.enemy_type == "turret" and self.frames: + if (self.enemy_type == "turret" or self.enemy_type == "boss") and self.frames: self.animation_timer += dt if self.animation_timer >= self.animation_speed: self.animation_timer = 0 @@ -159,7 +162,7 @@ class Enemy(Entity): self.is_attacking = True # For turret-type enemies, create a projectile - if self.enemy_type == "turret": + if self.enemy_type == "turret" or self.enemy_type == "boss": # Calculate direction to player direction = vec(player.pos.x - self.pos.x, player.pos.y - self.pos.y) @@ -209,3 +212,27 @@ class Enemy(Entity): # KB LOL MINECRAFT knockback_direction = 1 if player.pos.x > self.pos.x else -1 player.vel.x = knockback_direction * 8 + + def boss(self, player, FPS=60): + """ + Boss behavior: combine horizontal chase with turret-like attacks + """ + # Follow the player horizontally (x axis) + if abs(player.pos.x - self.pos.x) > 50: + direction = 1 if player.pos.x > self.pos.x else -1 + self.pos.x += direction * self.speed + self.direction = direction + + # Attack the player if within range + distance_to_player = vec( + player.pos.x - self.pos.x, player.pos.y - self.pos.y + ).length() + + if distance_to_player <= self.attack_range: + self.attack_timer += 1 / FPS + + if self.attack_timer >= self.attack_interval: + self.attack_timer = 0 + self.attack(player) + + self.detected_player = distance_to_player <= self.detection_radius