From cd6534f1ba2b5e2c9d5d52e85812f384c4a947c2 Mon Sep 17 00:00:00 2001 From: phe65kjig <2567779553@qq.com> Date: Sat, 25 May 2024 18:10:10 +0800 Subject: [PATCH] ADD file via upload --- player.py | 323 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 323 insertions(+) create mode 100644 player.py diff --git a/player.py b/player.py new file mode 100644 index 0000000..0f9d32e --- /dev/null +++ b/player.py @@ -0,0 +1,323 @@ +import pygame +from settings import * +from support import import_folder +from entity import Entity + +class Player(Entity): + def __init__(self,pos,groups,obstacle_sprites,create_attack,destroy_attack,create_magic): + # 调用父类的初始化方法 + super().__init__(groups) + # 设置玩家图像和位置 + self.image = pygame.image.load('../graphics/test/player.png').convert_alpha() + self.rect = self.image.get_rect(topleft = pos) + # 设置玩家的碰撞框 + self.hitbox = self.rect.inflate(-6,HITBOX_OFFSET['player']) + + # 图形设置 + # 导入玩家的其他图形资源 + self.import_player_assets() + # 状态设置 + # 玩家初始状态朝向下 + self.status = 'down' + + # 移动和攻击相关设置 + self.attacking = False + # 攻击冷却时间 + self.attack_cooldown = 400 + # 攻击时间 + self.attack_time = None + # 障碍物精灵组 + self.obstacle_sprites = obstacle_sprites + + + + # 武器设置 + self.create_attack = create_attack + self.destroy_attack = destroy_attack + self.weapon_index = 0 + self.weapon = list(weapon_data.keys())[self.weapon_index] + # 初始武器 + self.can_switch_weapon = True + self.weapon_switch_time = None + # 切换武器的冷却时间 + self.switch_duration_cooldown = 200 + + # 魔法设置 + self.create_magic = create_magic + self.magic_index = 0 + self.magic = list(magic_data.keys())[self.magic_index] + # 初始魔法 + self.can_switch_magic = True + self.magic_switch_time = None + # 玩家属性设置 + # 初始属性 + self.stats = {'health': 100,'energy':60,'attack': 10,'magic': 4,'speed': 5} + # 最大属性 + self.max_stats = {'health': 300, 'energy': 140, 'attack': 20, 'magic' : 10, 'speed': 10} + # 升级消耗 + self.upgrade_cost = {'health': 100, 'energy': 100, 'attack': 100, 'magic' : 100, 'speed': 100} + # 当前生命值 + self.health = self.stats['health'] * 1.0 + # 当前能量值 + self.energy = self.stats['energy'] * 0.8 + # 初始经验值 + self.exp = 5000 + # 移动速度 + self.speed = self.stats['speed'] + + # 伤害计时器和无敌状态设置 + # 是否可以受到伤害 + self.vulnerable = True + # 受伤时间 + self.hurt_time = None + # 无敌持续时间 + self.invulnerability_duration = 500 + + # 导入武器攻击音效 + self.weapon_attack_sound = pygame.mixer.Sound('../audio/sword.wav') + # 设置音量 + self.weapon_attack_sound.set_volume(0.4) + + def import_player_assets(self): + # 设置玩家动画资源的文件路径 + character_path = '../graphics/player/' + # 初始化玩家动画字典,包含不同方向和状态的动画列表 + self.animations = {'up': [],'down': [],'left': [],'right': [], + 'right_idle':[],'left_idle':[],'up_idle':[],'down_idle':[], + 'right_attack':[],'left_attack':[],'up_attack':[],'down_attack':[]} + # 遍历动画字典,加载对应路径下的动画帧 + for animation in self.animations.keys(): + full_path = character_path + animation + # 调用函数导入文件夹中的动画帧 + self.animations[animation] = import_folder(full_path) + + def input(self): + # 如果玩家当前未处于攻击状态 + if not self.attacking: + # 获取当前按下的键 + keys = pygame.key.get_pressed() + + # 处理移动输入 + # 按下向上键 + if keys[pygame.K_UP]: + # 设置垂直方向向上移动 + self.direction.y = -1 + # 设置玩家状态为向上 + self.status = 'up' + # 按下向下键 + elif keys[pygame.K_DOWN]: + # 设置垂直方向向下移动 + self.direction.y = 1 + # 设置玩家状态为向下 + self.status = 'down' + else: + # 停止垂直移动 + self.direction.y = 0 + # 按下向右键 + if keys[pygame.K_RIGHT]: + # 设置水平方向向右移动 + self.direction.x = 1 + # 设置玩家状态为向右 + self.status = 'right' + # 按下向左键 + elif keys[pygame.K_LEFT]: + # 设置水平方向向左移动 + self.direction.x = -1 + # 设置玩家状态为向左 + self.status = 'left' + else: + # 停止水平移动 + self.direction.x = 0 + + # 处理攻击输入 + # 按下空格键 + if keys[pygame.K_SPACE]: + # 玩家开始攻击 + self.attacking = True + # 记录攻击时间 + self.attack_time = pygame.time.get_ticks() + # 创建攻击对象 + self.create_attack() + # 播放武器攻击音效 + self.weapon_attack_sound.play() + + # 处理魔法输入 + # 按下左Ctrl键 + if keys[pygame.K_LCTRL]: + # 玩家开始攻击 + self.attacking = True + # 记录攻击时间 + self.attack_time = pygame.time.get_ticks() + # 获取当前魔法类型 + style = list(magic_data.keys())[self.magic_index] + # 计算魔法强度 + strength = list(magic_data.values())[self.magic_index]['strength'] + self.stats['magic'] + # 获取魔法消耗 + cost = list(magic_data.values())[self.magic_index]['cost'] + # 创建魔法效果 + self.create_magic(style,strength,cost) + # 处理切换武器输入 + # 按下Q键且可以切换武器 + if keys[pygame.K_q] and self.can_switch_weapon: + # 设置切换武器冷却状态为False + self.can_switch_weapon = False + # 记录切换武器时间 + self.weapon_switch_time = pygame.time.get_ticks() + + if self.weapon_index < len(list(weapon_data.keys())) - 1: + # 切换至下一个武器 + self.weapon_index += 1 + else: + # 回到第一个武器 + self.weapon_index = 0 + # 更新当前武器 + self.weapon = list(weapon_data.keys())[self.weapon_index] + # 处理切换魔法输入 + # 按下E键且可以切换魔法 + if keys[pygame.K_e] and self.can_switch_magic: + # 设置切换魔法冷却状态为False + self.can_switch_magic = False + # 记录切换魔法时间 + self.magic_switch_time = pygame.time.get_ticks() + + if self.magic_index < len(list(magic_data.keys())) - 1: + # 切换至下一个魔法 + self.magic_index += 1 + else: + # 回到第一个魔法 + self.magic_index = 0 + # 更新当前魔法 + self.magic = list(magic_data.keys())[self.magic_index] + + def get_status(self): + + # 空闲状态 + # 如果角色没有移动且不在攻击状态下 + if self.direction.x == 0 and self.direction.y == 0: + # 如果当前状态不包含 'idle' 和 'attack' + if not 'idle' in self.status and not 'attack' in self.status: + # 添加 '_idle' 到状态末尾,表示空闲状态 + self.status = self.status + '_idle' + # 如果角色正在攻击 + if self.attacking: + # 停止移动 + self.direction.x = 0 + self.direction.y = 0 + # 如果当前状态不包含 'attack' + if not 'attack' in self.status: + # 如果当前状态包含 'idle' + if 'idle' in self.status: + # 将 'idle' 替换为 'attack' + self.status = self.status.replace('_idle','_attack') + else: + # 在当前状态末尾添加 '_attack' + self.status = self.status + '_attack' + # 如果角色不在攻击状态下 + else: + # 如果当前状态包含 'attack' + if 'attack' in self.status: + # 移除 'attack',恢复到移动状态 + self.status = self.status.replace('_attack','') + + def cooldowns(self): + # 处理攻击冷却 + current_time = pygame.time.get_ticks() + # 如果当前时间超过攻击冷却时间,则停止攻击 + if self.attacking: + if current_time - self.attack_time >= self.attack_cooldown + weapon_data[self.weapon]['cooldown']: + self.attacking = False + self.destroy_attack() + # 处理武器切换冷却 + if not self.can_switch_weapon: + # 如果当前时间超过武器切换冷却时间,则允许切换武器 + if current_time - self.weapon_switch_time >= self.switch_duration_cooldown: + self.can_switch_weapon = True + # 处理魔法切换冷却 + if not self.can_switch_magic: + # 如果当前时间超过魔法切换冷却时间,则允许切换魔法 + if current_time - self.magic_switch_time >= self.switch_duration_cooldown: + self.can_switch_magic = True + # 处理受伤后的无敌时间 + if not self.vulnerable: + # 如果当前时间超过无敌时间,则角色恢复可受伤状态 + if current_time - self.hurt_time >= self.invulnerability_duration: + self.vulnerable = True + + def animate(self): + # 获取当前状态对应的动画列表 + animation = self.animations[self.status] + + # 更新帧索引 + self.frame_index += self.animation_speed + # 如果帧索引超过动画长度,则重置为0,实现循环播放 + if self.frame_index >= len(animation): + self.frame_index = 0 + + # 根据帧索引设置当前图像 + self.image = animation[int(self.frame_index)] + # 更新图像的位置 + self.rect = self.image.get_rect(center = self.hitbox.center) + + # 无敌状态下的闪烁效果 + if not self.vulnerable: + # 使用波动值计算透明度 + alpha = self.wave_value() + # 设置图像的透明度 + self.image.set_alpha(alpha) + else: + # 恢复图像完全可见(不透明) + self.image.set_alpha(255) + + def get_full_weapon_damage(self): + # 获取角色基础攻击力 + base_damage = self.stats['attack'] + # 获取当前武器的伤害值 + weapon_damage = weapon_data[self.weapon]['damage'] + # 返回角色使用当前武器的总伤害值 + return base_damage + weapon_damage + + def get_full_magic_damage(self): + # 获取角色基础魔法伤害 + base_damage = self.stats['magic'] + # 获取当前魔法的伤害值 + spell_damage = magic_data[self.magic]['strength'] + # 返回角色使用当前魔法的总伤害值 + return base_damage + spell_damage + + def get_value_by_index(self,index): + return list(self.stats.values())[index] + + def get_cost_by_index(self,index): + return list(self.upgrade_cost.values())[index] + + def energy_recovery(self): + if self.energy < self.stats['energy']: + # 根据魔法属性恢复能量 + self.energy += 0.01 * self.stats['magic'] + else: + # 能量恢复到最大值 + self.energy = self.stats['energy'] + + + def check_death(self): + # 如果敌人角色的生命值小于等于 0,表示角色已经死亡 + if self.health <= 0: + # 从精灵组中移除角色,通常用于删除角色或停止其更新和渲染 + self.kill() + + + def update(self): + # 处理用户输入 + self.input() + # 处理冷却时间 + self.cooldowns() + # 更新角色状态 + self.get_status() + # 更新角色动画 + self.animate() + # 移动角色 + self.move(self.stats['speed']) + # 恢复能量 + self.energy_recovery() + #死亡判断 + self.check_death() \ No newline at end of file