Finished refactoring code
This commit is contained in:
parent
cd0333cbff
commit
b0a925292e
25 changed files with 429 additions and 194 deletions
BIN
assets/audio/attack/claw.wav
Normal file
BIN
assets/audio/attack/claw.wav
Normal file
Binary file not shown.
BIN
assets/audio/attack/fireball.wav
Normal file
BIN
assets/audio/attack/fireball.wav
Normal file
Binary file not shown.
BIN
assets/audio/attack/slash.wav
Normal file
BIN
assets/audio/attack/slash.wav
Normal file
Binary file not shown.
BIN
assets/audio/death.wav
Normal file
BIN
assets/audio/death.wav
Normal file
Binary file not shown.
BIN
assets/audio/flame.wav
Normal file
BIN
assets/audio/flame.wav
Normal file
Binary file not shown.
BIN
assets/audio/heal.wav
Normal file
BIN
assets/audio/heal.wav
Normal file
Binary file not shown.
BIN
assets/audio/hit.wav
Normal file
BIN
assets/audio/hit.wav
Normal file
Binary file not shown.
BIN
assets/audio/main.ogg
Normal file
BIN
assets/audio/main.ogg
Normal file
Binary file not shown.
BIN
assets/audio/sword.wav
Normal file
BIN
assets/audio/sword.wav
Normal file
Binary file not shown.
|
@ -1,5 +1,12 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
asset_path = os.path.join(
|
||||||
|
script_dir, '../../..', 'assets')
|
||||||
|
|
||||||
monster_data = {
|
monster_data = {
|
||||||
'squid': {'health': 100,'exp':100,'damage':20,'attack_type': 'slash', 'attack_sound':'../Graphics/audio/attack/slash.wav', 'speed': 3, 'resistance': 3, 'attack_radius': 80, 'notice_radius': 360},
|
'squid': {'health': 100, 'exp': 100, 'attack': 20, 'attack_type': 'slash', 'attack_sound': f'{asset_path}/audio/attack/slash.wav', 'speed': 3, 'knockback': 20, 'attack_radius': 80, 'notice_radius': 360},
|
||||||
'raccoon': {'health': 300,'exp':250,'damage':40,'attack_type': 'claw', 'attack_sound':'../Graphics/audio/attack/claw.wav','speed': 2, 'resistance': 3, 'attack_radius': 120, 'notice_radius': 400},
|
'raccoon': {'health': 300, 'exp': 250, 'attack': 40, 'attack_type': 'claw', 'attack_sound': f'{asset_path}/audio/attack/claw.wav', 'speed': 2, 'knockback': 20, 'attack_radius': 120, 'notice_radius': 400},
|
||||||
'spirit': {'health': 100,'exp':110,'damage':8,'attack_type': 'thunder', 'attack_sound':'../Graphics/audio/attack/fireball.wav', 'speed': 4, 'resistance': 3, 'attack_radius': 60, 'notice_radius': 350},
|
'spirit': {'health': 100, 'exp': 110, 'attack': 8, 'attack_type': 'thunder', 'attack_sound': f'{asset_path}/audio/attack/fireball.wav', 'speed': 4, 'knockback': 20, 'attack_radius': 60, 'notice_radius': 350},
|
||||||
'bamboo': {'health': 70,'exp':120,'damage':6,'attack_type': 'leaf_attack', 'attack_sound':'../Graphics/audio/attack/slash.wav', 'speed': 3, 'resistance': 3, 'attack_radius': 50, 'notice_radius': 300}}
|
'bamboo': {'health': 70, 'exp': 120, 'attack': 6, 'attack_type': 'leaf_attack', 'attack_sound': f'{asset_path}/audio/attack/slash.wav', 'speed': 3, 'knockback': 20, 'attack_radius': 50, 'notice_radius': 300}}
|
||||||
|
|
23
game/configs/game/player_config.py
Normal file
23
game/configs/game/player_config.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
stats = {
|
||||||
|
'health': 100,
|
||||||
|
'energy': 60,
|
||||||
|
'attack': 10,
|
||||||
|
'magic': 4,
|
||||||
|
'speed': 5
|
||||||
|
}
|
||||||
|
|
||||||
|
max_stats = {
|
||||||
|
'health': 300,
|
||||||
|
'energy': 150,
|
||||||
|
'attack': 20,
|
||||||
|
'magic': 10,
|
||||||
|
'speed': 10
|
||||||
|
}
|
||||||
|
|
||||||
|
upgrade_costs = {
|
||||||
|
'health': 100,
|
||||||
|
'energy': 100,
|
||||||
|
'attack': 100,
|
||||||
|
'magic': 100,
|
||||||
|
'speed': 100
|
||||||
|
}
|
|
@ -13,37 +13,3 @@ HITBOX_OFFSET = {
|
||||||
|
|
||||||
# general colors
|
# general colors
|
||||||
WATER_COLOR = '#71ddee'
|
WATER_COLOR = '#71ddee'
|
||||||
UI_BG_COLOR = '#222222'
|
|
||||||
UI_BORDER_COLOR = '#111111'
|
|
||||||
TEXT_COLOR = '#EEEEEE'
|
|
||||||
|
|
||||||
# ui colors
|
|
||||||
HEALTH_COLOR = 'red'
|
|
||||||
ENERGY_COLOR = 'blue'
|
|
||||||
UI_BORDER_COLOR_ACTIVE = 'gold'
|
|
||||||
|
|
||||||
# Upgrade menu
|
|
||||||
TEXT_COLOR_SELECTED = '#111111'
|
|
||||||
BAR_COLOR = '#EEEEEE'
|
|
||||||
BAR_COLOR_SELECTED = '#111111'
|
|
||||||
UPGRADE_BG_COLOR_SELECTED = '#EEEEEE'
|
|
||||||
|
|
||||||
# # weapons
|
|
||||||
# weapon_data = {
|
|
||||||
# 'sword': {'cooldown': 100, 'damage': 15,'graphic':'../Graphics/graphics/weapons/sword/full.png'},
|
|
||||||
# 'lance': {'cooldown': 400, 'damage': 30,'graphic':'../Graphics/graphics/weapons/lance/full.png'},
|
|
||||||
# 'axe': {'cooldown': 300, 'damage': 20, 'graphic':'../Graphics/graphics/weapons/axe/full.png'},
|
|
||||||
# 'rapier':{'cooldown': 50, 'damage': 8, 'graphic':'../Graphics/graphics/weapons/rapier/full.png'},
|
|
||||||
# 'sai':{'cooldown': 80, 'damage': 10, 'graphic':'../Graphics/graphics/weapons/sai/full.png'}}
|
|
||||||
#
|
|
||||||
# # magic
|
|
||||||
# magic_data = {
|
|
||||||
# 'flame': {'strength': 5,'cost': 20,'graphic':'../Graphics/graphics/particles/flame/fire.png'},
|
|
||||||
# 'heal' : {'strength': 20,'cost': 10,'graphic':'../Graphics/graphics/particles/heal/heal.png'}}
|
|
||||||
#
|
|
||||||
# # enemy
|
|
||||||
# monster_data = {
|
|
||||||
# 'squid': {'health': 100,'exp':100,'damage':20,'attack_type': 'slash', 'attack_sound':'../Graphics/audio/attack/slash.wav', 'speed': 3, 'resistance': 3, 'attack_radius': 80, 'notice_radius': 360},
|
|
||||||
# 'raccoon': {'health': 300,'exp':250,'damage':40,'attack_type': 'claw', 'attack_sound':'../Graphics/audio/attack/claw.wav','speed': 2, 'resistance': 3, 'attack_radius': 120, 'notice_radius': 400},
|
|
||||||
# 'spirit': {'health': 100,'exp':110,'damage':8,'attack_type': 'thunder', 'attack_sound':'../Graphics/audio/attack/fireball.wav', 'speed': 4, 'resistance': 3, 'attack_radius': 60, 'notice_radius': 350},
|
|
||||||
# 'bamboo': {'health': 70,'exp':120,'damage':6,'attack_type': 'leaf_attack', 'attack_sound':'../Graphics/audio/attack/slash.wav', 'speed': 3, 'resistance': 3, 'attack_radius': 50, 'notice_radius': 300}}
|
|
||||||
|
|
|
@ -1,24 +1,26 @@
|
||||||
|
import os
|
||||||
import pygame
|
import pygame
|
||||||
from random import randint
|
from random import randint
|
||||||
|
|
||||||
from configs.system.window_config import TILESIZE
|
from configs.system.window_config import TILESIZE
|
||||||
|
|
||||||
from configs.game.spell_config import *
|
|
||||||
|
|
||||||
|
|
||||||
class MagicPlayer:
|
class MagicPlayer:
|
||||||
def __init__(self, animation_player):
|
def __init__(self, animation_player):
|
||||||
self.animation_player = animation_player
|
self.animation_player = animation_player
|
||||||
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
asset_path = os.path.join(
|
||||||
|
script_dir, '../..', 'assets')
|
||||||
|
|
||||||
# Sound Setup
|
# Sound Setup
|
||||||
# self.sounds = {
|
self.sounds = {
|
||||||
# 'heal': pygame.mixer.Sound('../Graphics/audio/heal.wav'),
|
'heal': pygame.mixer.Sound(f'{asset_path}/audio/heal.wav'),
|
||||||
# 'flame': pygame.mixer.Sound('../Graphics/audio/flame.wav')
|
'flame': pygame.mixer.Sound(f'{asset_path}/audio/flame.wav')
|
||||||
# }
|
}
|
||||||
|
|
||||||
def heal(self, player, strength, cost, groups):
|
def heal(self, player, strength, cost, groups):
|
||||||
if player.stats.energy >= cost:
|
if player.stats.energy >= cost:
|
||||||
# self.sounds['heal'].play()
|
self.sounds['heal'].play()
|
||||||
player.stats.health += strength
|
player.stats.health += strength
|
||||||
player.stats.energy -= cost
|
player.stats.energy -= cost
|
||||||
if player.stats.health >= player.stats.stats['health']:
|
if player.stats.health >= player.stats.stats['health']:
|
||||||
|
@ -31,13 +33,13 @@ class MagicPlayer:
|
||||||
def flame(self, player, cost, groups):
|
def flame(self, player, cost, groups):
|
||||||
if player.stats.energy >= cost:
|
if player.stats.energy >= cost:
|
||||||
player.stats.energy -= cost
|
player.stats.energy -= cost
|
||||||
# self.sounds['flame'].play()
|
self.sounds['flame'].play()
|
||||||
|
|
||||||
if player.status.split('_')[0] == 'right':
|
if player._input.status.split('_')[0] == 'right':
|
||||||
direction = pygame.math.Vector2(1, 0)
|
direction = pygame.math.Vector2(1, 0)
|
||||||
elif player.status.split('_')[0] == 'left':
|
elif player._input.status.split('_')[0] == 'left':
|
||||||
direction = pygame.math.Vector2(-1, 0)
|
direction = pygame.math.Vector2(-1, 0)
|
||||||
elif player.status.split('_')[0] == 'up':
|
elif player._input.status.split('_')[0] == 'up':
|
||||||
direction = pygame.math.Vector2(0, -1)
|
direction = pygame.math.Vector2(0, -1)
|
||||||
else:
|
else:
|
||||||
direction = pygame.math.Vector2(0, 1)
|
direction = pygame.math.Vector2(0, 1)
|
||||||
|
|
|
@ -12,7 +12,7 @@ class Weapon(pygame.sprite.Sprite):
|
||||||
script_dir, '../..', 'assets')
|
script_dir, '../..', 'assets')
|
||||||
|
|
||||||
self.sprite_type = 'weapon'
|
self.sprite_type = 'weapon'
|
||||||
direction = player.status.split('_')[0]
|
direction = player._input.status.split('_')[0]
|
||||||
|
|
||||||
# Graphic
|
# Graphic
|
||||||
full_path = f"{asset_path}/graphics/weapons/{player._input.combat.weapon}/{direction}.png"
|
full_path = f"{asset_path}/graphics/weapons/{player._input.combat.weapon}/{direction}.png"
|
||||||
|
|
|
@ -10,21 +10,22 @@ from .combat import CombatHandler
|
||||||
|
|
||||||
class InputHandler:
|
class InputHandler:
|
||||||
|
|
||||||
def __init__(self, sprite_type, status):
|
# , status):
|
||||||
self.status = status
|
def __init__(self, sprite_type, animation_player):
|
||||||
|
self.status = 'down'
|
||||||
|
self.sprite_type = sprite_type
|
||||||
|
|
||||||
# Setup Movement
|
# Setup Movement
|
||||||
self.movement = MovementHandler(sprite_type)
|
self.movement = MovementHandler(self.sprite_type)
|
||||||
self.move_cooldown = 15
|
self.move_cooldown = 15
|
||||||
self.can_move = True
|
self.can_move = True
|
||||||
self.move_time = None
|
self.move_time = None
|
||||||
|
|
||||||
# Setup Combat
|
# Setup Combat
|
||||||
self.combat = CombatHandler()
|
self.combat = CombatHandler(animation_player)
|
||||||
self.attacking = False
|
self.attacking = False
|
||||||
self.attack_cooldown = 400
|
self.attack_cooldown = 400
|
||||||
self.attack_time = None
|
self.attack_time = None
|
||||||
self.can_move = True
|
|
||||||
|
|
||||||
# Setup Special Actions
|
# Setup Special Actions
|
||||||
self.can_rotate_weapon = True
|
self.can_rotate_weapon = True
|
||||||
|
@ -37,28 +38,30 @@ class InputHandler:
|
||||||
def check_input(self, speed, hitbox, obstacle_sprites, rect, player):
|
def check_input(self, speed, hitbox, obstacle_sprites, rect, player):
|
||||||
|
|
||||||
if not self.attacking and self.can_move:
|
if not self.attacking and self.can_move:
|
||||||
|
|
||||||
keys = pygame.key.get_pressed()
|
keys = pygame.key.get_pressed()
|
||||||
button = randint(0, 7)
|
|
||||||
|
# button = randint(0, 5)
|
||||||
|
|
||||||
self.move_time = pygame.time.get_ticks()
|
self.move_time = pygame.time.get_ticks()
|
||||||
|
|
||||||
# Movement Input
|
# Movement Input
|
||||||
if button == 0: # keys[pygame.K_w]:
|
if keys[pygame.K_w]: # button == 0: # keys[pygame.K_w]:
|
||||||
self.movement.direction.y = -1
|
self.movement.direction.y = -1
|
||||||
self.status = 'up'
|
self.status = 'up'
|
||||||
self.can_move = False
|
self.can_move = False
|
||||||
elif button == 1: # keys[pygame.K_s]:
|
elif keys[pygame.K_s]: # button == 1: # keys[pygame.K_s]:
|
||||||
self.movement.direction.y = 1
|
self.movement.direction.y = 1
|
||||||
self.status = 'down'
|
self.status = 'down'
|
||||||
self.can_move = False
|
self.can_move = False
|
||||||
else:
|
else:
|
||||||
self.movement.direction.y = 0
|
self.movement.direction.y = 0
|
||||||
|
|
||||||
if button == 2: # keys[pygame.K_a]:
|
if keys[pygame.K_a]: # button == 2: # keys[pygame.K_a]:
|
||||||
self.movement.direction.x = -1
|
self.movement.direction.x = -1
|
||||||
self.status = 'left'
|
self.status = 'left'
|
||||||
self.can_move = False
|
self.can_move = False
|
||||||
elif button == 3: # keys[pygame.K_d]:
|
elif keys[pygame.K_d]: # keys[pygame.K_d]:
|
||||||
self.movement.direction.x = 1
|
self.movement.direction.x = 1
|
||||||
self.status = 'right'
|
self.status = 'right'
|
||||||
self.can_move = False
|
self.can_move = False
|
||||||
|
@ -67,15 +70,16 @@ class InputHandler:
|
||||||
|
|
||||||
self.movement.move(speed, hitbox, obstacle_sprites, rect)
|
self.movement.move(speed, hitbox, obstacle_sprites, rect)
|
||||||
|
|
||||||
|
if self.sprite_type == 'player':
|
||||||
# Combat Input
|
# Combat Input
|
||||||
if button == 4 and not self.attacking: # keys[pygame.K_e]
|
if keys[pygame.K_e] and not self.attacking: # keys[pygame.K_e]
|
||||||
self.attacking = True
|
self.attacking = True
|
||||||
self.attack_time = pygame.time.get_ticks()
|
self.attack_time = pygame.time.get_ticks()
|
||||||
self.combat.create_attack_sprite(player)
|
self.combat.create_attack_sprite(player)
|
||||||
# self.weapon_attack_sound.play()
|
self.combat.weapon_attack_sound.play()
|
||||||
|
|
||||||
# Magic Input
|
# Magic Input
|
||||||
if button == 5: # keys[pygame.K_q]:
|
if keys[pygame.K_q]: # keys[pygame.K_q]:
|
||||||
self.attacking = True
|
self.attacking = True
|
||||||
self.attack_time = pygame.time.get_ticks()
|
self.attack_time = pygame.time.get_ticks()
|
||||||
|
|
||||||
|
@ -87,12 +91,12 @@ class InputHandler:
|
||||||
|
|
||||||
cost = list(magic_data.values())[
|
cost = list(magic_data.values())[
|
||||||
self.combat.magic_index]['cost']
|
self.combat.magic_index]['cost']
|
||||||
print(self.combat.magic)
|
|
||||||
self.combat.create_magic_sprite(
|
self.combat.create_magic_sprite(
|
||||||
player, self.combat.magic, strength, cost)
|
player, self.combat.magic, strength, cost)
|
||||||
|
|
||||||
# Rotating Weapons
|
# Rotating Weapons
|
||||||
if button == 6 and self.can_rotate_weapon: # keys[pygame.K_LSHIFT]
|
# keys[pygame.K_LSHIFT]
|
||||||
|
if keys[pygame.K_LSHIFT] and self.can_rotate_weapon:
|
||||||
self.can_rotate_weapon = False
|
self.can_rotate_weapon = False
|
||||||
self.weapon_rotation_time = pygame.time.get_ticks()
|
self.weapon_rotation_time = pygame.time.get_ticks()
|
||||||
if self.combat.weapon_index < len(list(weapon_data.keys())) - 1:
|
if self.combat.weapon_index < len(list(weapon_data.keys())) - 1:
|
||||||
|
@ -104,7 +108,8 @@ class InputHandler:
|
||||||
self.combat.weapon_index]
|
self.combat.weapon_index]
|
||||||
|
|
||||||
# Swap Spells
|
# Swap Spells
|
||||||
if button == 7 and self.can_swap_magic: # keys[pygame.K_LCTRL] :
|
# keys[pygame.K_LCTRL] :
|
||||||
|
if keys[pygame.K_LCTRL] and self.can_swap_magic:
|
||||||
self.can_swap_magic = False
|
self.can_swap_magic = False
|
||||||
self.magic_swap_time = pygame.time.get_ticks()
|
self.magic_swap_time = pygame.time.get_ticks()
|
||||||
if self.combat.magic_index < len(list(magic_data.keys())) - 1:
|
if self.combat.magic_index < len(list(magic_data.keys())) - 1:
|
||||||
|
@ -114,6 +119,7 @@ class InputHandler:
|
||||||
|
|
||||||
def cooldowns(self, vulnerable):
|
def cooldowns(self, vulnerable):
|
||||||
current_time = pygame.time.get_ticks()
|
current_time = pygame.time.get_ticks()
|
||||||
|
self.vulnerable = vulnerable
|
||||||
|
|
||||||
if self.attacking:
|
if self.attacking:
|
||||||
if current_time - self.attack_time > self.attack_cooldown + weapon_data[self.combat.weapon]['cooldown']:
|
if current_time - self.attack_time > self.attack_cooldown + weapon_data[self.combat.weapon]['cooldown']:
|
||||||
|
@ -130,8 +136,8 @@ class InputHandler:
|
||||||
self.can_swap_magic = True
|
self.can_swap_magic = True
|
||||||
|
|
||||||
if not vulnerable:
|
if not vulnerable:
|
||||||
if current_time - self.hurt_time >= self.invulnerability_duration:
|
if current_time - self.combat.hurt_time >= self.combat.invulnerability_duration:
|
||||||
vulnerable = True
|
self.combat.vulnerable = True
|
||||||
|
|
||||||
if not self.can_move:
|
if not self.can_move:
|
||||||
if current_time - self.move_time >= self.move_cooldown:
|
if current_time - self.move_time >= self.move_cooldown:
|
||||||
|
|
|
@ -3,20 +3,25 @@ import pygame
|
||||||
from math import sin
|
from math import sin
|
||||||
|
|
||||||
from utils.resource_loader import import_folder
|
from utils.resource_loader import import_folder
|
||||||
|
|
||||||
from configs.system.window_config import HITBOX_OFFSET
|
from configs.system.window_config import HITBOX_OFFSET
|
||||||
|
|
||||||
|
|
||||||
class AnimationHandler:
|
class AnimationHandler:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, sprite_type, name=None):
|
||||||
self.frame_index = 0
|
self.frame_index = 0
|
||||||
self.animation_speed = 0.15
|
self.animation_speed = 0.15
|
||||||
|
|
||||||
def import_assets(self, sprite_type, position, name=None):
|
self.sprite_type = sprite_type
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def import_assets(self, position):
|
||||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
asset_path = os.path.join(
|
asset_path = os.path.join(
|
||||||
script_dir, '../../..', 'assets', 'graphics')
|
script_dir, '../../..', 'assets', 'graphics')
|
||||||
if sprite_type == 'player':
|
|
||||||
|
if self.sprite_type == 'player':
|
||||||
|
|
||||||
character_path = f"{asset_path}/player"
|
character_path = f"{asset_path}/player"
|
||||||
|
|
||||||
|
@ -24,7 +29,8 @@ class AnimationHandler:
|
||||||
self.image = pygame.image.load(
|
self.image = pygame.image.load(
|
||||||
f"{character_path}/down/down_0.png").convert_alpha()
|
f"{character_path}/down/down_0.png").convert_alpha()
|
||||||
self.rect = self.image.get_rect(topleft=position)
|
self.rect = self.image.get_rect(topleft=position)
|
||||||
self.hitbox = self.rect.inflate(HITBOX_OFFSET[sprite_type])
|
self.hitbox = self.rect.inflate(HITBOX_OFFSET[self.sprite_type])
|
||||||
|
|
||||||
self.animations = {
|
self.animations = {
|
||||||
'up': [], 'down': [], 'left': [], 'right': [],
|
'up': [], 'down': [], 'left': [], 'right': [],
|
||||||
'up_idle': [], 'down_idle': [], 'left_idle': [], 'right_idle': [],
|
'up_idle': [], 'down_idle': [], 'left_idle': [], 'right_idle': [],
|
||||||
|
@ -34,21 +40,30 @@ class AnimationHandler:
|
||||||
full_path = f"{character_path}/{animation}"
|
full_path = f"{character_path}/{animation}"
|
||||||
self.animations[animation] = import_folder(full_path)
|
self.animations[animation] = import_folder(full_path)
|
||||||
|
|
||||||
elif sprite_type == 'enemy':
|
elif self.sprite_type == 'enemy':
|
||||||
|
|
||||||
|
self.status = 'idle'
|
||||||
|
|
||||||
|
character_path = f"{asset_path}/monsters/{self.name}"
|
||||||
|
|
||||||
character_path = f"{asset_path}/monsters/{name}"
|
|
||||||
self.animations = {'idle': [], 'move': [], 'attack': []}
|
self.animations = {'idle': [], 'move': [], 'attack': []}
|
||||||
main_path = f"{asset_path}/monsters/{name}"
|
|
||||||
|
|
||||||
for animation in self.animations.keys():
|
for animation in self.animations.keys():
|
||||||
self.animations[animation] = import_folder(
|
self.animations[animation] = import_folder(
|
||||||
f"{main_path}/{animation}")
|
f"{character_path}/{animation}")
|
||||||
|
|
||||||
|
self.image = self.animations[self.status][self.frame_index]
|
||||||
|
self.rect = self.image.get_rect(topleft=position)
|
||||||
|
self.hitbox = self.rect.inflate(0, -10)
|
||||||
|
|
||||||
|
def animate(self, status, vulnerable=True, can_attack=False):
|
||||||
|
|
||||||
def animate(self, status, vulnerable):
|
|
||||||
animation = self.animations[status]
|
animation = self.animations[status]
|
||||||
|
|
||||||
self.frame_index += self.animation_speed
|
self.frame_index += self.animation_speed
|
||||||
if self.frame_index >= len(animation):
|
if self.frame_index >= len(animation):
|
||||||
|
if self.sprite_type == 'enemy':
|
||||||
|
if status == 'attack':
|
||||||
|
self.can_attack = False
|
||||||
self.frame_index = 0
|
self.frame_index = 0
|
||||||
|
|
||||||
# Set the image
|
# Set the image
|
||||||
|
@ -61,6 +76,10 @@ class AnimationHandler:
|
||||||
else:
|
else:
|
||||||
self.image.set_alpha(255)
|
self.image.set_alpha(255)
|
||||||
|
|
||||||
|
def trigger_death_particles(self, animation_player, position, particle_type, groups):
|
||||||
|
animation_player.generate_particles(
|
||||||
|
particle_type, position, groups)
|
||||||
|
|
||||||
def wave_value(self):
|
def wave_value(self):
|
||||||
value = sin(pygame.time.get_ticks())
|
value = sin(pygame.time.get_ticks())
|
||||||
if value >= 0:
|
if value >= 0:
|
||||||
|
|
27
game/entities/components/audio.py
Normal file
27
game/entities/components/audio.py
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import os
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
from configs.game.monster_config import monster_data
|
||||||
|
|
||||||
|
|
||||||
|
class AudioHandler:
|
||||||
|
|
||||||
|
def __init__(self, sprite_type, monster_name=None):
|
||||||
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
asset_path = os.path.join(
|
||||||
|
script_dir, '../../..', 'assets', 'audio')
|
||||||
|
|
||||||
|
if sprite_type == 'player':
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif sprite_type == 'enemy':
|
||||||
|
|
||||||
|
# Sounds
|
||||||
|
self.attack_sound = pygame.mixer.Sound(
|
||||||
|
monster_data[monster_name]['attack_sound'])
|
||||||
|
self.death_sound = pygame.mixer.Sound(
|
||||||
|
f'{asset_path}/death.wav')
|
||||||
|
self.hit_sound = pygame.mixer.Sound(f'{asset_path}/hit.wav')
|
||||||
|
self.death_sound.set_volume(0.2)
|
||||||
|
self.hit_sound.set_volume(0.2)
|
||||||
|
self.attack_sound.set_volume(0.2)
|
|
@ -3,7 +3,6 @@ import pygame
|
||||||
|
|
||||||
from effects.weapon_effects import Weapon
|
from effects.weapon_effects import Weapon
|
||||||
from effects.magic_effects import MagicPlayer
|
from effects.magic_effects import MagicPlayer
|
||||||
from effects.particle_effects import AnimationPlayer
|
|
||||||
|
|
||||||
from configs.game.weapon_config import weapon_data
|
from configs.game.weapon_config import weapon_data
|
||||||
from configs.game.spell_config import magic_data
|
from configs.game.spell_config import magic_data
|
||||||
|
@ -11,11 +10,12 @@ from configs.game.spell_config import magic_data
|
||||||
|
|
||||||
class CombatHandler:
|
class CombatHandler:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, animation_player):
|
||||||
|
|
||||||
|
self.animation_player = animation_player
|
||||||
|
|
||||||
# Setup Combat
|
# Setup Combat
|
||||||
self.animation_player = AnimationPlayer()
|
self.magic_player = MagicPlayer(animation_player)
|
||||||
self.magic_player = MagicPlayer(self.animation_player)
|
|
||||||
self.current_attack = None
|
self.current_attack = None
|
||||||
|
|
||||||
# Spell and Weapon Rotation
|
# Spell and Weapon Rotation
|
||||||
|
@ -31,13 +31,13 @@ class CombatHandler:
|
||||||
self.invulnerability_duration = 300
|
self.invulnerability_duration = 300
|
||||||
|
|
||||||
# Import Sounds
|
# Import Sounds
|
||||||
# script_dir = os.path.dirname(os.path.abspath(__file__))
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
# asset_path = os.path.join(
|
asset_path = os.path.join(
|
||||||
# script_dir, '../../..', 'assets', 'audio')
|
script_dir, '../../..', 'assets', 'audio')
|
||||||
#
|
|
||||||
# self.weapon_attack_sound = pygame.mixer.Sound(
|
self.weapon_attack_sound = pygame.mixer.Sound(
|
||||||
# f"{asset_path}/sword.wav")
|
f"{asset_path}/sword.wav")
|
||||||
# self.weapon_attack_sound.set_volume(0.2)
|
self.weapon_attack_sound.set_volume(0.2)
|
||||||
|
|
||||||
def create_attack_sprite(self, player):
|
def create_attack_sprite(self, player):
|
||||||
self.current_attack = Weapon(
|
self.current_attack = Weapon(
|
||||||
|
@ -49,7 +49,6 @@ class CombatHandler:
|
||||||
self.current_attack = None
|
self.current_attack = None
|
||||||
|
|
||||||
def create_magic_sprite(self, player, style, strength, cost):
|
def create_magic_sprite(self, player, style, strength, cost):
|
||||||
print(style)
|
|
||||||
if style == 'heal':
|
if style == 'heal':
|
||||||
self.magic_player.heal(player, strength, cost, [
|
self.magic_player.heal(player, strength, cost, [
|
||||||
player.visible_sprites])
|
player.visible_sprites])
|
||||||
|
|
|
@ -1,29 +1,18 @@
|
||||||
|
from configs.game.player_config import stats, max_stats, upgrade_costs
|
||||||
|
from configs.game.monster_config import monster_data
|
||||||
|
|
||||||
|
|
||||||
class StatsHandler:
|
class StatsHandler:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, sprite_type, monster_name=None):
|
||||||
self.stats = {
|
|
||||||
'health': 100,
|
|
||||||
'energy': 60,
|
|
||||||
'attack': 10,
|
|
||||||
'magic': 4,
|
|
||||||
'speed': 5
|
|
||||||
}
|
|
||||||
|
|
||||||
self.max_stats = {
|
if sprite_type == 'player':
|
||||||
'health': 300,
|
|
||||||
'energy': 150,
|
|
||||||
'attack': 20,
|
|
||||||
'magic': 10,
|
|
||||||
'speed': 10
|
|
||||||
}
|
|
||||||
|
|
||||||
self.upgrade_costs = {
|
self.stats = stats
|
||||||
'health': 100,
|
|
||||||
'energy': 100,
|
self.max_stats = max_stats
|
||||||
'attack': 100,
|
|
||||||
'magic': 100,
|
self.upgrade_costs = upgrade_costs
|
||||||
'speed': 100
|
|
||||||
}
|
|
||||||
|
|
||||||
self.health = self.stats['health']
|
self.health = self.stats['health']
|
||||||
self.energy = self.stats['energy']
|
self.energy = self.stats['energy']
|
||||||
|
@ -32,9 +21,21 @@ class StatsHandler:
|
||||||
self.speed = self.stats['speed']
|
self.speed = self.stats['speed']
|
||||||
self.exp = 10000
|
self.exp = 10000
|
||||||
|
|
||||||
|
if sprite_type == 'enemy':
|
||||||
|
|
||||||
|
self.monster_info = monster_data[monster_name]
|
||||||
|
self.health = self.monster_info['health']
|
||||||
|
self.attack = self.monster_info['attack']
|
||||||
|
self.attack_type = self.monster_info['attack_type']
|
||||||
|
self.attack_radius = self.monster_info['attack_radius']
|
||||||
|
self.speed = self.monster_info['speed']
|
||||||
|
self.knockback = self.monster_info['knockback']
|
||||||
|
self.notice_radius = self.monster_info['notice_radius']
|
||||||
|
self.exp = self.monster_info['exp']
|
||||||
|
|
||||||
def energy_recovery(self):
|
def energy_recovery(self):
|
||||||
if self.energy < self.stats['energy']:
|
if self.energy < self.stats['energy']:
|
||||||
self.energy += 0.01 * self.stats['magic']
|
self.energy += 0.01 * self.magic
|
||||||
else:
|
else:
|
||||||
self.energy = self.stats['energy']
|
self.energy = self.stats['energy']
|
||||||
|
|
||||||
|
|
92
game/entities/enemy.py
Normal file
92
game/entities/enemy.py
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
from .components.animaton import AnimationHandler
|
||||||
|
from .components.stats import StatsHandler
|
||||||
|
from .components._input import InputHandler
|
||||||
|
|
||||||
|
from effects.particle_effects import AnimationPlayer
|
||||||
|
|
||||||
|
from .components.audio import AudioHandler
|
||||||
|
|
||||||
|
|
||||||
|
class Enemy(pygame.sprite.Sprite):
|
||||||
|
|
||||||
|
def __init__(self, name, position, groups, visible_sprites, obstacle_sprites):
|
||||||
|
super().__init__(groups)
|
||||||
|
self.sprite_type = "enemy"
|
||||||
|
self.name = name
|
||||||
|
self.visible_sprites = visible_sprites
|
||||||
|
|
||||||
|
# Setup Graphics
|
||||||
|
self.audio = AudioHandler(self.sprite_type, self.name)
|
||||||
|
self.animation_player = AnimationPlayer()
|
||||||
|
self.animation = AnimationHandler(self.sprite_type, self.name)
|
||||||
|
self.animation.import_assets(position)
|
||||||
|
self.status = self.animation.status
|
||||||
|
self.image = self.animation.image
|
||||||
|
self.rect = self.animation.rect
|
||||||
|
|
||||||
|
# Setup Inputs
|
||||||
|
self._input = InputHandler(
|
||||||
|
self.sprite_type, self.animation_player)
|
||||||
|
|
||||||
|
# Setup Stats
|
||||||
|
self.stats = StatsHandler(self.sprite_type, self.name)
|
||||||
|
self.obstacle_sprites = obstacle_sprites
|
||||||
|
|
||||||
|
self.distance_direction_from_player = None
|
||||||
|
|
||||||
|
self.kills = 0
|
||||||
|
|
||||||
|
def get_action(self):
|
||||||
|
player_distance = sorted(
|
||||||
|
self.distance_direction_from_player, key=lambda x: x[0])[0]
|
||||||
|
|
||||||
|
if player_distance[0] < self.stats.notice_radius and player_distance[0] >= self.stats.attack_radius:
|
||||||
|
self._input.movement.direction = player_distance[1]
|
||||||
|
self.animation.status = "move"
|
||||||
|
self._input.movement.move(
|
||||||
|
self.stats.speed, self.animation.hitbox, self.obstacle_sprites, self.animation.rect)
|
||||||
|
elif player_distance[0] <= self.stats.attack_radius:
|
||||||
|
self.animation.status = 'attack'
|
||||||
|
else:
|
||||||
|
self.animation.status = 'idle'
|
||||||
|
|
||||||
|
def add_exp(self, player):
|
||||||
|
player.stats.exp += self.stats.exp
|
||||||
|
|
||||||
|
def check_death(self, player):
|
||||||
|
if self.stats.health <= 0:
|
||||||
|
self.add_exp(player)
|
||||||
|
self.animation.trigger_death_particles(
|
||||||
|
self.animation_player, self.rect.center, self.name, self.visible_sprites)
|
||||||
|
self.audio.death_sound.play()
|
||||||
|
self.kill()
|
||||||
|
|
||||||
|
def get_damaged(self, player, attack_type):
|
||||||
|
if self._input.combat.vulnerable:
|
||||||
|
self.audio.hit_sound.play()
|
||||||
|
for _, direction, attacking_player in self.distance_direction_from_player:
|
||||||
|
if attacking_player == player:
|
||||||
|
self._input.movement.direction = -direction
|
||||||
|
self._input.movement.move(
|
||||||
|
self.stats.speed * self.stats.knockback, self.animation.hitbox, self.obstacle_sprites, self.animation.rect)
|
||||||
|
break
|
||||||
|
if attack_type == 'weapon':
|
||||||
|
self.stats.health -= player.get_full_weapon_damage()
|
||||||
|
else:
|
||||||
|
self.stats.health -= player.get_full_magic_damage()
|
||||||
|
self.check_death(player)
|
||||||
|
self._input.combat.hurt_time = pygame.time.get_ticks()
|
||||||
|
self._input.combat.vulnerable = False
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
|
||||||
|
self.get_action()
|
||||||
|
self.status = self.animation.status
|
||||||
|
|
||||||
|
self.animation.animate(self.status, self._input.combat.vulnerable)
|
||||||
|
self.image = self.animation.image
|
||||||
|
self.rect = self.animation.rect
|
||||||
|
|
||||||
|
self._input.cooldowns(self._input.combat.vulnerable)
|
|
@ -1,14 +1,19 @@
|
||||||
import pygame
|
import pygame
|
||||||
|
from random import randint
|
||||||
|
|
||||||
|
from configs.game.weapon_config import weapon_data
|
||||||
|
from configs.game.spell_config import magic_data
|
||||||
|
|
||||||
from .components.combat import CombatHandler
|
|
||||||
from .components.stats import StatsHandler
|
from .components.stats import StatsHandler
|
||||||
from .components._input import InputHandler
|
from .components._input import InputHandler
|
||||||
from .components.animaton import AnimationHandler
|
from .components.animaton import AnimationHandler
|
||||||
|
|
||||||
|
from effects.particle_effects import AnimationPlayer
|
||||||
|
|
||||||
|
|
||||||
class Player(pygame.sprite.Sprite):
|
class Player(pygame.sprite.Sprite):
|
||||||
|
|
||||||
def __init__(self, position, groups, obstacle_sprites, visible_sprites, attack_sprites):
|
def __init__(self, position, groups, obstacle_sprites, visible_sprites, attack_sprites, attackable_sprites):
|
||||||
super().__init__(groups)
|
super().__init__(groups)
|
||||||
|
|
||||||
# Setup Sprites
|
# Setup Sprites
|
||||||
|
@ -16,32 +21,33 @@ class Player(pygame.sprite.Sprite):
|
||||||
self.visible_sprites = visible_sprites
|
self.visible_sprites = visible_sprites
|
||||||
self.attack_sprites = attack_sprites
|
self.attack_sprites = attack_sprites
|
||||||
self.obstacle_sprites = obstacle_sprites
|
self.obstacle_sprites = obstacle_sprites
|
||||||
self.status = 'down'
|
self.attackable_sprites = attackable_sprites
|
||||||
|
|
||||||
|
# Setup Graphics
|
||||||
|
self.animation_player = AnimationPlayer()
|
||||||
|
self.animation = AnimationHandler(self.sprite_type)
|
||||||
|
self.animation.import_assets(position)
|
||||||
|
self.image = self.animation.image
|
||||||
|
self.rect = self.animation.rect
|
||||||
|
|
||||||
# Setup Inputs
|
# Setup Inputs
|
||||||
self._input = InputHandler(
|
self._input = InputHandler(
|
||||||
self.sprite_type, self.status)
|
self.sprite_type, self.animation_player) # , self.status)
|
||||||
|
|
||||||
# Setup Graphics
|
|
||||||
self.animation = AnimationHandler()
|
|
||||||
self.animation.import_assets(self.sprite_type, position)
|
|
||||||
self.animate = self.animation.animate
|
|
||||||
self.image = self.animation.image
|
|
||||||
self.animate(self.status, self._input.combat.vulnerable)
|
|
||||||
self.rect = self.animation.rect
|
|
||||||
|
|
||||||
# Setup Stats
|
# Setup Stats
|
||||||
self.stats = StatsHandler()
|
self.stats = StatsHandler(self.sprite_type)
|
||||||
|
|
||||||
|
self.distance_direction_from_enemy = None
|
||||||
|
|
||||||
def get_status(self):
|
def get_status(self):
|
||||||
if self._input.movement.direction.x == 0 and self._input.movement.direction.y == 0:
|
if self._input.movement.direction.x == 0 and self._input.movement.direction.y == 0:
|
||||||
if not 'idle' in self.status and not 'attack' in self.status:
|
if 'idle' not in self.status and 'attack' not in self.status:
|
||||||
self.status += '_idle'
|
self.status += '_idle'
|
||||||
|
|
||||||
if self._input.attacking:
|
if self._input.attacking:
|
||||||
self._input.movement.direction.x = 0
|
self._input.movement.direction.x = 0
|
||||||
self._input.movement.direction.y = 0
|
self._input.movement.direction.y = 0
|
||||||
if not 'attack' in self.status:
|
if 'attack' not in self.status:
|
||||||
if 'idle' in self.status:
|
if 'idle' in self.status:
|
||||||
self.status = self.status.replace('idle', 'attack')
|
self.status = self.status.replace('idle', 'attack')
|
||||||
else:
|
else:
|
||||||
|
@ -50,10 +56,38 @@ class Player(pygame.sprite.Sprite):
|
||||||
if 'attack' in self.status:
|
if 'attack' in self.status:
|
||||||
self.status = self.status.replace('_attack', '')
|
self.status = self.status.replace('_attack', '')
|
||||||
|
|
||||||
|
def attack_logic(self):
|
||||||
|
if self.attack_sprites:
|
||||||
|
for attack_sprite in self.attack_sprites:
|
||||||
|
collision_sprites = pygame.sprite.spritecollide(
|
||||||
|
attack_sprite, self.attackable_sprites, False)
|
||||||
|
if collision_sprites:
|
||||||
|
for target_sprite in collision_sprites:
|
||||||
|
if target_sprite.sprite_type == 'grass':
|
||||||
|
pos = target_sprite.rect.center
|
||||||
|
offset = pygame.math.Vector2(0, 75)
|
||||||
|
for leaf in range(randint(3, 6)):
|
||||||
|
self.animation_player.create_grass_particles(
|
||||||
|
position=pos - offset, groups=[self.visible_sprites])
|
||||||
|
target_sprite.kill()
|
||||||
|
else:
|
||||||
|
target_sprite.get_damaged(
|
||||||
|
self, attack_sprite.sprite_type)
|
||||||
|
|
||||||
|
def get_full_weapon_damage(self):
|
||||||
|
base_damage = self.stats.attack
|
||||||
|
weapon_damage = weapon_data[self._input.combat.weapon]['damage']
|
||||||
|
return (base_damage + weapon_damage)
|
||||||
|
|
||||||
|
def get_full_magic_damage(self):
|
||||||
|
base_damage = self.stats.magic
|
||||||
|
spell_damage = magic_data[self._input.combat.magic]['strength']
|
||||||
|
return (base_damage + spell_damage)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
# Refresh objects based on input
|
# Refresh objects based on input
|
||||||
self._input.check_input(
|
self._input.check_input(
|
||||||
self.stats.stats['speed'], self.animation.hitbox, self.obstacle_sprites, self.animation.rect, self)
|
self.stats.speed, self.animation.hitbox, self.obstacle_sprites, self.animation.rect, self)
|
||||||
self.status = self._input.status
|
self.status = self._input.status
|
||||||
|
|
||||||
# Animate
|
# Animate
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import pygame
|
import pygame
|
||||||
|
|
||||||
from .ui_settings import *
|
from .ui_settings import UI_FONT, UI_FONT_SIZE, TEXT_COLOR, TEXT_COLOR_SELECTED, UPGRADE_BG_COLOR_SELECTED, UI_BORDER_COLOR, UI_BG_COLOR, BAR_COLOR_SELECTED, BAR_COLOR
|
||||||
|
|
||||||
|
|
||||||
class Upgrade:
|
class Upgrade:
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
import os
|
import os
|
||||||
import pygame
|
import pygame
|
||||||
|
|
||||||
from random import choice, randint
|
from random import choice
|
||||||
|
|
||||||
from configs.game.spell_config import magic_data
|
|
||||||
from configs.game.weapon_config import weapon_data
|
|
||||||
from configs.game.monster_config import monster_data
|
|
||||||
from configs.system.window_config import TILESIZE
|
from configs.system.window_config import TILESIZE
|
||||||
|
|
||||||
from utils.debug import debug
|
from utils.debug import debug
|
||||||
|
@ -14,12 +11,9 @@ from utils.resource_loader import import_csv_layout, import_folder
|
||||||
from interface.ui import UI
|
from interface.ui import UI
|
||||||
from interface.upgrade import Upgrade
|
from interface.upgrade import Upgrade
|
||||||
|
|
||||||
from effects.magic_effects import MagicPlayer
|
|
||||||
from effects.particle_effects import AnimationPlayer
|
|
||||||
from effects.weapon_effects import Weapon
|
|
||||||
|
|
||||||
from entities.observer import Observer
|
from entities.observer import Observer
|
||||||
from entities.player import Player
|
from entities.player import Player
|
||||||
|
from entities.enemy import Enemy
|
||||||
|
|
||||||
from .terrain import Tile
|
from .terrain import Tile
|
||||||
from .camera import Camera
|
from .camera import Camera
|
||||||
|
@ -48,6 +42,9 @@ class Level:
|
||||||
self.ui = UI()
|
self.ui = UI()
|
||||||
self.upgrade = Upgrade(self.player)
|
self.upgrade = Upgrade(self.player)
|
||||||
|
|
||||||
|
self.get_players_enemies()
|
||||||
|
self.get_distance_direction()
|
||||||
|
|
||||||
def create_map(self):
|
def create_map(self):
|
||||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
asset_path = os.path.join(
|
asset_path = os.path.join(
|
||||||
|
@ -92,28 +89,85 @@ class Level:
|
||||||
elif col == '394':
|
elif col == '394':
|
||||||
# Player Generation
|
# Player Generation
|
||||||
self.player = Player(
|
self.player = Player(
|
||||||
(x, y), [self.visible_sprites], self.obstacle_sprites, self.visible_sprites, self.attack_sprites)
|
(x, y), [self.visible_sprites], self.obstacle_sprites, self.visible_sprites, self.attack_sprites, self.attackable_sprites)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
pass
|
# Monster Generation
|
||||||
# monster generation
|
if col == '390':
|
||||||
|
monster_name = 'bamboo'
|
||||||
|
elif col == '391':
|
||||||
|
monster_name = 'spirit'
|
||||||
|
elif col == '392':
|
||||||
|
monster_name = 'raccoon'
|
||||||
|
else:
|
||||||
|
monster_name = 'squid'
|
||||||
|
|
||||||
|
Enemy(monster_name, (x, y), [
|
||||||
|
self.visible_sprites, self.attackable_sprites], self.visible_sprites, self.obstacle_sprites)
|
||||||
|
|
||||||
|
def get_players_enemies(self):
|
||||||
|
self.player_sprites = [sprite for sprite in self.visible_sprites.sprites(
|
||||||
|
) if hasattr(sprite, 'sprite_type') and sprite.sprite_type in ('player')]
|
||||||
|
|
||||||
|
self.enemy_sprites = [sprite for sprite in self.visible_sprites.sprites(
|
||||||
|
) if hasattr(sprite, 'sprite_type') and sprite.sprite_type in ('enemy')]
|
||||||
|
|
||||||
|
def get_distance_direction(self):
|
||||||
|
for player in self.player_sprites:
|
||||||
|
player.distance_direction_from_enemy = []
|
||||||
|
|
||||||
|
for enemy in self.enemy_sprites:
|
||||||
|
enemy.distance_direction_from_player = []
|
||||||
|
|
||||||
|
for player in self.player_sprites:
|
||||||
|
player_vector = pygame.math.Vector2(player.rect.center)
|
||||||
|
for enemy in self.enemy_sprites:
|
||||||
|
enemy_vector = pygame.math.Vector2(enemy.rect.center)
|
||||||
|
distance = (player_vector - enemy_vector).magnitude()
|
||||||
|
|
||||||
|
if distance > 0:
|
||||||
|
direction = (player_vector - enemy_vector).normalize()
|
||||||
|
else:
|
||||||
|
direction = pygame.math.Vector2()
|
||||||
|
|
||||||
|
enemy.distance_direction_from_player.append(
|
||||||
|
(distance, direction, player))
|
||||||
|
player.distance_direction_from_enemy.append(
|
||||||
|
(distance, -direction, enemy))
|
||||||
|
|
||||||
|
def apply_damage_to_player(self):
|
||||||
|
for enemy in self.enemy_sprites:
|
||||||
|
for distance, _, player in enemy.distance_direction_from_player:
|
||||||
|
if distance < enemy.stats.attack_radius and player._input.combat.vulnerable:
|
||||||
|
player.stats.health -= enemy.stats.attack
|
||||||
|
player._input.combat.vulnerable = False
|
||||||
|
player._input.combat.hurt_time = pygame.time.get_ticks()
|
||||||
|
|
||||||
def toggle_menu(self):
|
def toggle_menu(self):
|
||||||
self.game_paused = not self.game_paused
|
self.game_paused = not self.game_paused
|
||||||
|
|
||||||
def run(self):
|
def run(self, who='observer'):
|
||||||
# Draw the game
|
# Draw the game
|
||||||
|
if who == 'observer':
|
||||||
|
self.visible_sprites.custom_draw(self.observer)
|
||||||
|
self.ui.display(self.observer)
|
||||||
|
elif who == 'player':
|
||||||
self.visible_sprites.custom_draw(self.player)
|
self.visible_sprites.custom_draw(self.player)
|
||||||
self.ui.display(self.player)
|
self.ui.display(self.player)
|
||||||
debug(self.player.status)
|
debug('v0.5')
|
||||||
if not self.game_paused:
|
if not self.game_paused:
|
||||||
# Update the game
|
# Update the game
|
||||||
# self.player.distance_direction_to_player = self.get_state()
|
for player in self.player_sprites:
|
||||||
|
player.attack_logic()
|
||||||
|
|
||||||
|
self.get_players_enemies()
|
||||||
|
self.get_distance_direction()
|
||||||
|
self.apply_damage_to_player()
|
||||||
self.visible_sprites.update()
|
self.visible_sprites.update()
|
||||||
|
|
||||||
# self.visible_sprites.enemy_update(self.player)
|
# self.visible_sprites.enemy_update(self.player)
|
||||||
# self.player_attack_logic()
|
# self.player_attack_logic()
|
||||||
else:
|
else:
|
||||||
if self.visible_sprites.sprite_type == 'player':
|
|
||||||
self.upgrade.display()
|
self.upgrade.display()
|
||||||
|
|
||||||
if self.player.stats.health <= 0:
|
if self.player.stats.health <= 0:
|
||||||
|
|
17
game/main.py
17
game/main.py
|
@ -2,10 +2,12 @@ import pygame
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from configs.system.window_config import WIDTH, HEIGHT, WATER_COLOR, FPS
|
from configs.system.window_config import WIDTH, HEIGHT, WATER_COLOR, FPS
|
||||||
from utils.debug import debug
|
|
||||||
|
|
||||||
from level.level import Level
|
from level.level import Level
|
||||||
|
|
||||||
|
import os
|
||||||
|
import psutil
|
||||||
|
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
|
|
||||||
|
@ -13,16 +15,17 @@ class Game:
|
||||||
|
|
||||||
pygame.init()
|
pygame.init()
|
||||||
|
|
||||||
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
self.screen = pygame.display.set_mode(
|
||||||
|
(WIDTH, HEIGHT))
|
||||||
pygame.display.set_caption('Pneuma')
|
pygame.display.set_caption('Pneuma')
|
||||||
self.clock = pygame.time.Clock()
|
self.clock = pygame.time.Clock()
|
||||||
|
|
||||||
self.level = Level()
|
self.level = Level()
|
||||||
|
|
||||||
# # Sound
|
# Sound
|
||||||
# main_sound = pygame.mixer.Sound('../assets/audio/main.ogg')
|
main_sound = pygame.mixer.Sound('../assets/audio/main.ogg')
|
||||||
# main_sound.set_volume(0.4)
|
main_sound.set_volume(0.4)
|
||||||
# main_sound.play(loops=-1)
|
main_sound.play(loops=-1)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
|
||||||
|
@ -35,7 +38,7 @@ class Game:
|
||||||
self.level.toggle_menu()
|
self.level.toggle_menu()
|
||||||
|
|
||||||
self.screen.fill(WATER_COLOR)
|
self.screen.fill(WATER_COLOR)
|
||||||
self.level.run()
|
self.level.run('player')
|
||||||
pygame.display.update()
|
pygame.display.update()
|
||||||
self.clock.tick(FPS)
|
self.clock.tick(FPS)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import pygame
|
import pygame
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
from utils.settings import *
|
from utils.settings import *
|
||||||
from utils.debug import debug
|
from utils.debug import debug
|
||||||
|
@ -7,13 +8,15 @@ from utils.debug import debug
|
||||||
from objects.level import Level
|
from objects.level import Level
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
pygame.init()
|
pygame.init()
|
||||||
|
|
||||||
self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
self.screen = pygame.display.set_mode(
|
||||||
|
(WIDTH, HEIGHT))
|
||||||
pygame.display.set_caption('Pneuma')
|
pygame.display.set_caption('Pneuma')
|
||||||
self.clock = pygame.time.Clock()
|
self.clock = pygame.time.Clock()
|
||||||
|
|
||||||
|
@ -43,6 +46,5 @@ class Game:
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
game = Game()
|
game = Game()
|
||||||
figure_file = 'rl/plots/pneuma.png'
|
|
||||||
while True:
|
while True:
|
||||||
game.run()
|
game.run()
|
||||||
|
|
Loading…
Reference in a new issue