More content added, weapons, coin collecting, basic combat.

This commit is contained in:
Storm Dragon
2025-01-30 19:11:33 -05:00
parent 0d115b2bef
commit 53009373c2
10 changed files with 344 additions and 63 deletions

105
src/enemy.py Normal file
View File

@@ -0,0 +1,105 @@
from libstormgames import *
from src.object import Object
import pygame
class Enemy(Object):
def __init__(self, xRange, y, enemyType, sounds, **kwargs):
# Initialize base object properties
super().__init__(
xRange,
y,
f"{enemyType}", # Base sound for ambient noise
isStatic=False,
isHazard=True
)
# Enemy specific properties
self.enemyType = enemyType
self.health = kwargs.get('health', 5) # Default 5 HP
self.damage = kwargs.get('damage', 1) # Default 1 damage
self.attackRange = kwargs.get('attack_range', 1) # Default 1 tile range
self.movementRange = kwargs.get('movement_range', 5) # Default 5 tile patrol
self.sounds = sounds # Store reference to game sounds
# Movement and behavior properties
self.movingRight = True # Initial direction
self.movementSpeed = 0.03 # Slightly slower than player
self.patrolStart = self.xRange[0]
self.patrolEnd = self.xRange[0] + self.movementRange
self.lastAttackTime = 0
self.attackCooldown = 1000 # 1 second between attacks
@property
def xPos(self):
"""Current x position"""
return self._currentX if hasattr(self, '_currentX') else self.xRange[0]
@xPos.setter
def xPos(self, value):
"""Set current x position"""
self._currentX = value
def update(self, currentTime, player):
"""Update enemy position and handle attacks"""
if not self.isActive or self.health <= 0:
return
# Update position based on patrol behavior
if self.movingRight:
self.xPos += self.movementSpeed
if self.xPos >= self.patrolEnd:
self.movingRight = False
else:
self.xPos -= self.movementSpeed
if self.xPos <= self.patrolStart:
self.movingRight = True
# Check for attack opportunity
if self.can_attack(currentTime, player):
self.attack(currentTime, player)
def can_attack(self, currentTime, player):
"""Check if enemy can attack player"""
# Must have cooled down from last attack
if currentTime - self.lastAttackTime < self.attackCooldown:
return False
# Don't attack if player is jumping
if player.isJumping:
return False
# Check if player is in range and on same side we're facing
distance = abs(player.xPos - self.xPos)
tolerance = 0.5 # Same tolerance as we used for the grave
if distance <= (self.attackRange + tolerance):
# Only attack if we're facing the right way
playerOnRight = player.xPos > self.xPos
return playerOnRight == self.movingRight
return False
def attack(self, currentTime, player):
"""Perform attack on player"""
self.lastAttackTime = currentTime
# Play attack sound
attackSound = f"{self.enemyType}_attack"
if attackSound in self.sounds:
self.sounds[attackSound].play()
# Deal damage to player
player.set_health(player.get_health() - self.damage)
speak(f"The {self.enemyType} hits you!")
def take_damage(self, amount):
"""Handle enemy taking damage"""
self.health -= amount
if self.health <= 0:
self.die()
def die(self):
"""Handle enemy death"""
self.isActive = False
if self.channel:
obj_stop(self.channel)
self.channel = None