diff --git a/enemy.py b/enemy.py index be9599b..7ad35fa 100644 --- a/enemy.py +++ b/enemy.py @@ -1,17 +1,124 @@ import pygame from settings import * + class Enemy: def __init__(self, x, y): self.rect = pygame.Rect(x, y, 28, 48) self.velocity = pygame.Vector2(0, 0) + self.pos = pygame.Vector2(x, y) + self.health = ENEMY_HEALTH + self.max_health = ENEMY_HEALTH + self.knockback_timer = 0 + self.invulnerable_timer = 0 + + # Attack hitbox + self.attack_rect = pygame.Rect(x, y, 60, 60) def update(self, dt, world, player): + dt = min(dt, 0.05) + + # Apply gravity (FIX for flying) + self.velocity.y += ENEMY_GRAVITY * dt + if self.velocity.y > MAX_FALL_SPEED: + self.velocity.y = MAX_FALL_SPEED + # Basic AI: follow player - if player.rect.x < self.rect.x: - self.rect.x -= ENEMY_SPEED * dt + if self.knockback_timer <= 0: + if player.rect.x < self.rect.x: + self.velocity.x = -ENEMY_SPEED + else: + self.velocity.x = ENEMY_SPEED else: - self.rect.x += ENEMY_SPEED * dt + self.knockback_timer -= dt + + # Update position + self.pos.x += self.velocity.x * dt + self.rect.x = round(self.pos.x) + self.handle_horizontal_collisions(world) + + self.pos.y += self.velocity.y * dt + self.rect.y = round(self.pos.y) + self.handle_vertical_collisions(world) + + # Update attack rect position + self.attack_rect.centerx = self.rect.centerx + self.attack_rect.centery = self.rect.centery + + # Decay invulnerability + if self.invulnerable_timer > 0: + self.invulnerable_timer -= dt + + def handle_horizontal_collisions(self, world): + """Handle horizontal collision""" + for tile in world.get_nearby_tiles(self.rect): + if tile["solid"] and self.rect.colliderect(tile["rect"]): + if self.velocity.x > 0: + self.rect.right = tile["rect"].left + elif self.velocity.x < 0: + self.rect.left = tile["rect"].right + + self.pos.x = self.rect.x + self.velocity.x = 0 + + def handle_vertical_collisions(self, world): + """Handle vertical collision""" + for tile in world.get_nearby_tiles(self.rect): + if tile["solid"] and self.rect.colliderect(tile["rect"]): + if self.velocity.y > 0: + self.rect.bottom = tile["rect"].top + elif self.velocity.y < 0: + self.rect.top = tile["rect"].bottom + + self.pos.y = self.rect.y + self.velocity.y = 0 + + def take_damage(self, damage, direction): + """Take damage and apply knockback""" + if self.invulnerable_timer > 0: + return + + self.health -= damage + self.invulnerable_timer = 0.3 + self.knockback_timer = 0.15 + + # Apply knockback (affected by resistance) + knockback_force = 400 * ENEMY_KNOCKBACK_RESISTANCE + self.velocity.x = direction * knockback_force + self.velocity.y = -300 # Slight upward knockback def draw(self, screen, camera): - pygame.draw.rect(screen, (0, 0, 255), camera.apply(self.rect)) + draw_rect = camera.apply(self.rect) + + # Flash when invulnerable + if self.invulnerable_timer > 0: + color = (100, 100, 255) # Light blue + else: + color = (0, 0, 255) # Blue + + pygame.draw.rect(screen, color, draw_rect) + + if SHOW_COLLIDERS: + pygame.draw.rect(screen, (0, 255, 0), draw_rect, 2) + # Draw attack hitbox + attack_draw_rect = camera.apply(self.attack_rect) + pygame.draw.rect(screen, (255, 0, 0), attack_draw_rect, 1) + + # Draw health bar + health_bar_width = 28 + health_bar_height = 4 + health_percent = self.health / self.max_health + + health_bar_rect = pygame.Rect( + draw_rect.x, + draw_rect.y - 8, + health_bar_width * health_percent, + health_bar_height + ) + pygame.draw.rect(screen, (0, 255, 0), health_bar_rect) + pygame.draw.rect(screen, (255, 0, 0), pygame.Rect( + draw_rect.x, + draw_rect.y - 8, + health_bar_width, + health_bar_height + ), 1) \ No newline at end of file