94 lines
3.7 KiB
Python
94 lines
3.7 KiB
Python
import pygame
|
|
import random
|
|
from settings import PLAYER_SIZE, PLAYER_SPEED, KILL_RADIUS
|
|
|
|
class Enemy:
|
|
def __init__(self, x, y, enemy_image, human_image, controlled=False):
|
|
self.x = x
|
|
self.y = y
|
|
self.rect = pygame.Rect(x, y, PLAYER_SIZE, PLAYER_SIZE)
|
|
self.dir = "up"
|
|
self.max_health = 100
|
|
self.health = 100
|
|
self.is_human = False
|
|
self.enemy_image = enemy_image
|
|
self.human_image = human_image
|
|
self.controlled = controlled
|
|
self.alive = True
|
|
|
|
def move(self, keys, player, map_w, map_h):
|
|
if self.is_human:
|
|
if random.random() < 0.02:
|
|
self.dir = random.choice(["up", "down", "left", "right"])
|
|
dx = dy = 0
|
|
if self.dir == "up":
|
|
dy -= PLAYER_SPEED // 1.5
|
|
if self.dir == "down":
|
|
dy += PLAYER_SPEED // 1.5
|
|
if self.dir == "left":
|
|
dx -= PLAYER_SPEED // 1.5
|
|
if self.dir == "right":
|
|
dx += PLAYER_SPEED // 1.5
|
|
self.x = max(0, min(map_w - PLAYER_SIZE // 2, self.x + dx))
|
|
self.y = max(0, min(map_h - PLAYER_SIZE // 2, self.y + dy))
|
|
self.rect.topleft = (self.x, self.y)
|
|
elif self.controlled:
|
|
dx = dy = 0
|
|
if keys[pygame.K_UP]:
|
|
dy -= PLAYER_SPEED
|
|
self.dir = "up"
|
|
if keys[pygame.K_DOWN]:
|
|
dy += PLAYER_SPEED
|
|
self.dir = "down"
|
|
if keys[pygame.K_LEFT]:
|
|
dx -= PLAYER_SPEED
|
|
self.dir = "left"
|
|
if keys[pygame.K_RIGHT]:
|
|
dx += PLAYER_SPEED
|
|
self.dir = "right"
|
|
self.x = max(0, min(map_w - PLAYER_SIZE // 2, self.x + dx))
|
|
self.y = max(0, min(map_h - PLAYER_SIZE // 2, self.y + dy))
|
|
self.rect.topleft = (self.x, self.y)
|
|
else:
|
|
if player and player.alive:
|
|
dx = player.x - self.x
|
|
dy = player.y - self.y
|
|
dist = max(1, (dx ** 2 + dy ** 2) ** 0.5)
|
|
speed = PLAYER_SPEED // 1.5
|
|
self.x += int(speed * dx / dist)
|
|
self.y += int(speed * dy / dist)
|
|
self.x = max(0, min(map_w - PLAYER_SIZE // 2, self.x))
|
|
self.y = max(0, min(map_h - PLAYER_SIZE // 2, self.y))
|
|
self.rect.topleft = (self.x, self.y)
|
|
|
|
def draw(self, win, ox, oy):
|
|
img = self.human_image if self.is_human else self.enemy_image
|
|
angle = {"up": 90, "right": 0, "down": -90, "left": 180}[self.dir]
|
|
color = (0, 128, 255) if self.is_human else (200, 200, 0)
|
|
if img:
|
|
rotated_img = pygame.transform.rotate(img, angle)
|
|
win.blit(rotated_img, (self.x - ox, self.y - oy))
|
|
else:
|
|
pygame.draw.rect(win, color, (self.x - ox, self.y - oy, PLAYER_SIZE // 2, PLAYER_SIZE // 2))
|
|
if not self.is_human:
|
|
bw = PLAYER_SIZE // 2
|
|
bh = 6
|
|
ratio = self.health / self.max_health
|
|
bx = self.x - ox
|
|
by = self.y - oy - bh - 2
|
|
pygame.draw.rect(win, (255, 0, 0), (bx, by, bw, bh))
|
|
pygame.draw.rect(win, (0, 255, 0), (bx, by, int(bw * ratio), bh))
|
|
|
|
def take_damage(self, amt):
|
|
if not self.is_human:
|
|
self.health = max(0, self.health - amt)
|
|
if self.health == 0:
|
|
self.alive = False
|
|
self.is_human = True
|
|
|
|
def check_kill_player(self, player):
|
|
if not self.is_human:
|
|
dx = (self.x + PLAYER_SIZE // 4) - (player.x + PLAYER_SIZE // 2)
|
|
dy = (self.y + PLAYER_SIZE // 4) - (player.y + PLAYER_SIZE // 2)
|
|
if (dx ** 2 + dy ** 2) ** 0.5 < KILL_RADIUS:
|
|
player.alive = False
|