Python文字游戏:升级、打怪、属性点、装备等(四)

"""
新增怪物技能系统,优化了很多地方,后面继续增加
"""


import random
import math
import os

os.system(" ")


# ################角色信息##################
class Character:
    # 属性
    def __init__(self, name, lv=0, HP=100, MP=0, STR=0, WIS=0, VIT=0, SKI=0, LUK=0, ATK=0, DEF=0, exp=0, EXP=0, ptr=0,
                 bonus=0.0, label="role"):
        # 角色信息
        self.name = name  # 名字
        self.lv = lv  # 等级
        self.exp = exp  # 当前经验值
        self.EXP = EXP  # 升级所需经验值
        # 基础属性
        self.STR = STR  # 力量
        self.WIS = WIS  # 智力
        self.VIT = VIT  # 体力
        self.SKI = SKI  # 敏捷
        self.LUK = LUK  # 幸运
        # 面板属性
        self.HP = HP + self.VIT * 2 + self.STR  # 总生命 = 基础值+2体力+1力量
        self.hp = self.HP  # 当前生命
        self.MP = MP + self.WIS * 2  # MP = 基础值+2智力
        self.mp = self.MP  # 当前MP
        self.ATK = int(ATK + self.STR * 1.5 + self.SKI)  # 攻击力 = 基础值+1.5力量+1敏捷
        self.DEF = int(DEF + self.VIT)  # 防御力 = 基础值+1体力
        self.HIT = round(self.SKI * 0.7, 2)  # 命中值 = 0.7敏捷
        self.DODGE = round(self.SKI * 0.3)  # 闪避值 = 0.3敏捷
        # 高级属性
        self.ptr = ptr  # 穿透
        self.crit = round(math.tan(self.check_luck(self.LUK + self.SKI / 5 + self.STR / 10) / 148.2), 2)  # 暴击率
        self.thump = round(math.tan(self.check_luck(self.LUK + self.SKI / 5 + self.VIT / 10) / 148.2), 2)  # 重击率
        self.bonus = bonus  # 暴伤加成
        self.Skills = []  # 技能
        self.label = label  # 标签

    def __repr__(self):  # 显示角色信息
        return f"{self.name}\n" \
               f"等级:{self.lv}\t经验:{self.exp}/{self.EXP}\n" \
               f"HP:{self.hp}/{self.HP}\tMP:{self.mp}/{self.MP}\n" \
               f"力量:{self.STR}\t智力:{self.WIS}\t体力:{self.VIT}\t敏捷:{self.SKI}\n" \
               f"攻击:{self.ATK}\t防御:{self.DEF}\n" \
               f"幸运:{self.LUK}\t穿透:{self.ptr}\t命中:{self.HIT}\t闪避:{self.DODGE}\n" \
               f"暴击率:{self.crit}\t重击率:{self.thump}\t爆伤加成:{self.bonus}\n"

    # 添加技能
    def add_skill(self):
        if self.lv == 2:
            skill = PlayerSkillOne(self)
            print(self.name, "学会了技能", skill.name)
            self.Skills.append(skill)  # 存入技能对象

    # 升级
    def lv_up(self):  # 角色升级  分配属性点
        if self.exp >= self.EXP:
            print(self.name, "升级了!!")
            self.lv += 1
            self.add_skill()
            self.exp = self.exp - self.EXP
            self.EXP = int((self.EXP + self.lv * 3))  # 升级经验增长
            self.HP += 10
            self.MP += 3
            number = 7  # 总点数
            while True:
                # number_get = input("请输入分配的点数(力量,智力,体力,敏捷,幸运):")
                number_get = "4021"
                if len(number_get) != 4:
                    print("输入有误,请重新分配!")
                    continue
                # 升级后基础属性值自动加2
                n0 = int(number_get[0]) + 2
                n1 = int(number_get[1]) + 2
                n2 = int(number_get[2]) + 2
                n3 = int(number_get[3]) + 2
                n4 = 2
                if n0 + n1 + n2 + n3 + n4 != number + 10:
                    print("输入有误,请重新分配!")
                else:
                    # 属性增加
                    self.STR += n0
                    self.WIS += n1
                    self.VIT += n2
                    self.SKI += n3
                    self.LUK += n4
                    # 关联属性值变更
                    self.HP = (self.HP + n2 * 2 + n0)  # 总生命 = 基础值+2体力+1力量
                    self.MP = self.MP + n1 * 2  # MP = 基础值+2智力
                    self.ATK = int(self.ATK + n0 * 1.5 + n3)  # 攻击力 = 基础值+1.5力量+1敏捷
                    self.DEF = int(self.DEF + n2)  # 防御力 = 基础值+1体力
                    self.HIT = round(self.HIT + n3 * 0.7)  # 命中值 = 0.7敏捷
                    self.DODGE = round(self.DODGE + n3 * 0.3)  # 闪避值 = 0.3敏捷
                    self.crit = round(math.tan(self.check_luck(self.LUK + self.SKI / 5 + self.STR / 10) / 148.2),
                                      2)  # 暴击率
                    self.thump = round(math.tan(self.check_luck(self.LUK + self.SKI / 5 + self.VIT / 10) / 148.2),
                                       2)  # 重击率
                    # 升级后血量蓝量回满
                    self.hp = self.HP
                    self.mp = self.MP
                    print(self.__repr__())  # 打印升级后信息
                    return True
        return False

    # 强化敌人
    def update(self):  # 怪物强化
        self.lv += 1
        self.HP += self.lv * 3 + 5
        self.hp = self.HP
        self.exp += int(self.lv / 3 + 1)
        # 属性增加
        n0 = 1
        n1 = 1
        n2 = 1
        n3 = 1
        n4 = 1
        self.STR += n0
        self.WIS += n1
        self.VIT += n2
        self.SKI += n3
        self.LUK = self.lv // 5
        # 关联属性值变更
        self.HP = (self.HP + n2 * 2 + n0)  # 总生命 = 基础值+2体力+1力量
        self.MP = self.MP + n1 * 2  # MP = 基础值+2智力
        self.ATK = int(self.ATK + n0 * 1.5 + n3)  # 攻击力 = 基础值+1.5力量+1敏捷
        self.DEF = int(self.DEF + n2)  # 防御力 = 基础值+1体力
        self.HIT = round(self.HIT + n3 * 0.7, 2)  # 命中值 = 0.7敏捷
        self.DODGE = round(self.DODGE + n3 * 0.3, 2)  # 闪避值 = 0.3敏捷
        self.crit = round(math.tan(self.check_luck(self.LUK + self.SKI / 5 + self.STR / 10) / 148.2), 2)  # 暴击率
        self.thump = round(math.tan(self.check_luck(self.LUK + self.SKI / 5 + self.VIT / 10) / 148.2), 2)  # 重击率
        # 升级后血量蓝量回满
        self.hp = self.HP
        self.mp = self.MP

    # 展示技能
    def show_skill(self):
        for i in range(len(self.Skills)):
            skill = self.Skills[i]
            print(f"{i + 1}\tlv{skill.lv}{skill.name}\t{skill.exp}/{skill.EXP}")

    @staticmethod
    def check_luck(num):
        """
        校准数值
        """
        if num > 100:  # 范围(0~100)
            num = 100
        return num


# ################敌人技能#################
class EnemySkill:
    def __init__(self, E):
        self.E = E
        self.SKILLs = {}
        self.skill_1()  # 存入技能1
        self.skill_2()

    # 施放技能
    def cast_skill(self, skill, info, P):
        if skill.name == "蓄力一击":
            # def attack(self, HIT, CRIT, ATK, STR, s_lv, r):
            damage = skill.attack(info.E_HIT, info.E_CRIT, self.E.ATK, self.E.STR, skill.lv, info.r1)
            if damage:
                P.hp -= damage
                E_damage_str = (
                    f"{self.E.name}使用技能{skill.name}对{P.name}造成{damage}点{info.ef2}伤害")
                return E_damage_str
        if skill.name == "爪击":
            # def attack(self, HIT, CRIT, ATK, STR, s_lv, r):
            damage = skill.attack(info.E_HIT, info.E_CRIT, self.E.ATK, self.E.STR, skill.lv, info.r1)
            if damage:
                P.hp -= damage
                E_damage_str = (
                    f"{self.E.name}使用技能{skill.name}对{P.name}造成{damage}点{info.ef2}伤害")
                return E_damage_str

    # 生成技能和技能权值列表
    def generate_skill_list(self):
        skill_list = []
        w_list = []
        for skill, enemy_list in self.SKILLs.items():
            if self.E.name in enemy_list:  # 生成该敌人的技能列表
                skill_list.append(skill)
                w_list.append(skill.w)
        return skill_list, w_list

    # 根据权重概率随机获取技能
    def get_skill(self):
        skill_list, w_list = self.generate_skill_list()  # 技能列表 # 权重值列表
        s = sum(w_list)  # 权重和
        rate = random.randint(1, s)
        n = w_list[0]
        for i in range(len(w_list)):
            if rate <= n:
                return skill_list[i]
            n += w_list[i + 1]

    def skill_1(self):
        skill1 = PlayerSkillOne(self.E)  # 技能:蓄力一击
        self.SKILLs[skill1] = ["僵尸"]  # 技能适用角色

    def skill_2(self):
        skill2 = EnemySKillOne(self.E)
        self.SKILLs[skill2] = ["僵尸"]


# ##################技能##################
# "蓄力一击"
class PlayerSkillOne:
    def __init__(self, role, mp=5):
        self.role = role  # 角色
        self.name = "蓄力一击"
        self.lv = 1
        self.exp = 0
        self.EXP = 50
        self.mp = mp
        self.w = 5  # 概率权重  # 敌人
        self.label = "skill"

    # 技能效果
    def attack(self, HIT, CRIT, ATK, STR, s_lv, r):
        if not HIT:
            return False
        if CRIT:
            atk = 2 * int(ATK + STR * (s_lv * 0.5))  # 每级增加0.5STR的伤害
        else:
            atk = int(ATK + STR * (s_lv * 0.5))
        damage = int(atk * (1 - r))
        return damage

    def lv_up(self):
        if self.exp >= self.EXP:
            self.exp = self.exp - self.EXP
            self.EXP = int(2.5 * self.EXP)
            self.lv += 1
            print(f"技能{self.name}升级到{self.lv}级")
            return True
        return False


# 爪击
class EnemySKillOne:
    def __init__(self, role, mp=5):
        self.role = role  # 角色
        self.name = "爪击"
        self.lv = 1
        self.mp = mp
        self.w = 10  # 概率权重
        self.label = "skill"

    # 技能效果
    def attack(self, HIT, CRIT, ATK, STR, s_lv, r):
        if self.role.label == "BOSS":  # BOSS加成
            s_lv = 3
        elif self.role.label == "Elite":  # 精英加成
            s_lv = 2
        if not HIT:
            return False
        if CRIT:
            atk = 2 * int(ATK + STR * s_lv+self.role.lv)  # 每级增加1*STR的伤害
        else:
            atk = int(ATK + STR * s_lv+self.role.lv)
        damage = int(atk * (1 - r))
        return damage


# ###################普通攻击#########################
# 普通攻击
class Attack:
    def __init__(self, role):
        self.role = role
        self.name = "普攻"
        self.label = "attack"

    def attack(self, HIT, ATK, r):  # 是否命中,重击,暴击
        if not HIT:
            return False
        damage = int(ATK * (1 - r))
        return damage


# ####################战斗信息#########################
class BattleInfo:
    # 生成战斗信息
    def __init__(self, P, E):
        self.P = P
        self.E = E
        self.d1 = 100  # 玩家伤害权重
        self.d2 = 100  # 敌人伤害权重  # 数值越大减伤越低
        self.hit_rate = random.randint(1, 100) / 100  # 命中率
        self.crit_rate = random.randint(1, 100) / 100  # 暴击率
        self.ptr_rate = random.randint(1, 100) / 100  # 重击率
        self.DEF1 = 0 if self.E.thump > self.ptr_rate else self.P.DEF  # 玩家受到重击后防御为0
        self.DEF2 = 0 if self.P.thump > self.ptr_rate else self.E.DEF  # 敌人受到重击后防御为0
        self.ATK1 = self.P.ATK * 2 if self.P.crit > self.crit_rate else self.P.ATK  # 玩家暴击后攻击翻倍
        self.ATK2 = self.E.ATK * 2 if self.E.crit > self.crit_rate else self.E.ATK  # 敌人暴击后攻击翻倍
        self.r1 = self.DEF1 / (self.DEF1 + self.d1)  # 玩家减伤率
        self.r2 = self.DEF2 / (self.DEF2 + self.d2)  # 敌人减伤率
        self.ef1 = self.ef_str(self.P.thump > self.ptr_rate, self.P.crit > self.crit_rate)  # 玩家伤害效果
        self.ef2 = self.ef_str(self.E.thump > self.ptr_rate, self.E.crit > self.crit_rate)  # 敌人伤害效果
        self.HIT1 = ((self.P.lv - self.E.lv) / (self.P.lv + self.E.lv) + 1) * (self.P.HIT + 100) / (
                self.E.DODGE + 100)  # 玩家命中率
        self.HIT2 = ((self.E.lv - self.P.lv) / (self.P.lv + self.E.lv) + 1) * (self.E.HIT + 100) / (
                self.P.DODGE + 100)  # 敌人命中率
        self.P_HIT = True if self.HIT1 > self.hit_rate else False  # 玩家是否命中
        self.P_CRIT = True if self.P.crit > self.crit_rate else False  # 玩家是否暴击
        self.P_THUMP = True if self.P.thump > self.ptr_rate else False  # 玩家是否重击
        self.E_HIT = True if self.HIT2 > self.hit_rate else False  # 敌人是否命中
        self.E_CRIT = True if self.E.crit > self.crit_rate else False  # 敌人是否暴击
        self.E_THUMP = True if self.E.thump > self.ptr_rate else False  # 敌人是否重击

    @staticmethod
    def ef_str(con1, con2):  # 战斗效果文本
        # print('\033[33;36;32m 字体8隐藏有色,且有背景色 \033[0m')  # 绿色字
        # {Total_P_damage}点{ef1}伤害
        if con1 and con2:
            return "\033[33;36;35m重暴击\033[0m"
        elif con1:
            return "\033[8;33;31m重击\033[0m"  # 红色
        elif con2:
            return "\033[33;36;31m暴击\033[0m"
        else:
            return ""


# ###################战斗#########################
class Battle:
    def __init__(self, P, E):  # 初始化战斗数据  P:Player  E:Enemy
        self.P = P  # 把玩家传入战斗中
        self.E = E  # 把敌人传入战斗中
        self.d1 = 100  # 玩家伤害权重
        self.d2 = 100  # 敌人伤害权重  # 数值越大减伤越低
        self.start_rate = random.randint(1, 100) / 100  # 先后手概率参数
        self.p_rate = self.P.SKI / (self.P.SKI + self.E.SKI)  # 玩家先手概率

    def get_input(self, data):
        if data == "":
            self.battle_field()
        else:
            return int(data)

    # 战斗界面
    def battle_field(self):
        while True:
            num = input("1.攻击\t2.技能\n3.物品\t4.状态\n5.逃跑\n请选择:")
            num = self.get_input(num)
            if num == 1:
                attack = Attack(self.P)  # 每次攻击创建普攻对象
                return attack
            elif num == 2:
                self.P.show_skill()  # 展示技能
                while True:
                    if len(self.P.Skills) == 0:
                        print("还未学习任何技能")
                    self.P.Skills.append("退出技能")
                    print(f"{len(self.P.Skills)}\t退出技能")
                    s = input("请选择:")
                    s = self.get_input(s)
                    if 0 < s <= len(self.P.Skills):
                        if s == len(self.P.Skills):
                            self.P.Skills.pop()
                            break
                        skill = self.P.Skills[s - 1]  # 获取技能
                        self.P.Skills.pop()
                        return skill  # 返回技能对象
            elif num == 3:
                return
            elif num == 4:
                role = input("1.查看自己\t2.查看敌人\n请选择:")
                role = self.get_input(role)
                if role == 1:
                    print(self.P)
                if role == 2:
                    print(self.E)
                pass  # 查看后重新进入战斗界面

    # 使用技能
    def using_skills(self, skill):  # 传入技能
        info = BattleInfo(self.P, self.E)  # 每次使用技能重新生成信息
        if self.P.mp < skill.mp:
            print("\033[8;33;36mmp不足\033[0m")
            return self.player_round()  # 返回玩家回合
        self.P.mp -= skill.mp  # 使用技能减少mp
        skill.exp += 1  # 每次使用成功技能经验加1
        if skill.name == "蓄力一击":
            damage = skill.attack(info.P_HIT, info.P_CRIT, self.P.ATK, self.P.STR, skill.lv, info.r2)
            if damage:
                self.E.hp -= damage
                P_damage_str = (
                    f"{self.P.name}使用技能{skill.name}对{self.E.name}造成{damage}点{info.ef1}伤害")
                return P_damage_str
            else:
                print(f"{self.P.name}技能未命中")
                return False

    # 玩家回合
    def player_round(self):
        info = BattleInfo(self.P, self.E)
        choice = self.battle_field()  # 战斗界面
        while True:
            if choice.label == "attack":  # 使用普通攻击
                attack = Attack(self.P)
                damage = attack.attack(info.HIT1, info.ATK1, info.r2)
                self.E.hp -= damage
                if damage:
                    P_damage_str = f"{self.P.name}对{self.E.name}造成了{damage}点{info.ef1}伤害"  # 伤害播报
                    return P_damage_str
                else:
                    print(f"{self.P.name}未命中{self.E.name}")
                    return False
            elif choice.label == "skill":  # 使用技能
                # 此时的choice是准确的技能对象
                skill_effect = self.using_skills(choice)
                return skill_effect

    # 敌人回合
    def enemy_round(self):
        info = BattleInfo(self.P, self.E)
        # 普通攻击
        rate = random.randint(1, 100)
        E_rate = self.E.WIS * 2
        if rate < E_rate:
            # 普通攻击
            attack = Attack(self.E)
            damage = attack.attack(info.HIT2, info.ATK2, info.r1)
            if damage:
                self.P.hp = self.P.hp - damage
                E_damage_str = f"{self.E.name}对{self.P.name}造成了{damage}点{info.ef2}伤害"
                return E_damage_str
            else:
                print(f"{self.E.name}未命中{self.P.name}")
                return False
        else:
            # 使用技能
            enemy_skill = EnemySkill(self.E)
            skill = enemy_skill.get_skill()
            E_str = enemy_skill.cast_skill(skill, info, self.P)
            return E_str

    # 战斗结算
    def battle_account(self):
        for skill in self.P.Skills:
            skill.lv_up()  # 技能等级结算
        self.P.lv_up()  # 玩家等级结算
        return True

    # 玩家阵亡
    def player_die(self):
        print(f"{self.P.name}已阵亡")
        self.P.exp = 0  # 玩家阵亡经验归零
        self.P.hp = self.P.HP  # 阵亡后HP回满
        self.P.mp = self.P.MP  # 阵亡后MP回满
        print(self.P)

    # 敌人阵亡
    def enemy_die(self):
        print(self.E.name, "死亡")
        self.P.exp += self.E.exp  # 玩家获得经验
        print(f"{self.P.name}获得{self.E.exp}经验")

    # 战斗
    def battle(self):
        if self.p_rate > self.start_rate:  # 玩家先手
            print(f"你遭遇了{self.E.name}")
            ROUND = 1
            while True:
                info = BattleInfo(self.P, self.E)  # 生成战斗信息
                print(f"\033[1;30;43m 回合{ROUND} \033[0m")
                # 玩家回合
                p_round = self.player_round()
                if p_round:
                    print(p_round)
                if self.E.hp < 0:
                    self.enemy_die()
                    self.battle_account()  # 结算
                    break
                # 敌人回合
                e_round = self.enemy_round()
                if e_round:
                    print(e_round)
                if self.P.hp < 0:
                    self.player_die()
                    break
                ROUND += 1

        else:  # 后手
            print(f"你遭遇{self.E.name}偷袭!!!!!!")
            ROUND = 1
            while True:
                info = BattleInfo(self.P, self.E)
                print(f"\033[1;30;43m 回合{ROUND} \033[0m")
                # 敌人回合
                e_round = self.enemy_round()
                if e_round:
                    print(e_round)
                if self.P.hp < 0:
                    self.player_die()
                    break
                # 玩家回合
                p_round = self.player_round()
                if p_round:
                    print(p_round)
                if self.E.hp < 0:
                    self.enemy_die()
                    self.battle_account()  # 结算
                    break
                ROUND += 1
            self.E.update()  # 强化一下敌人
        # 战斗结束
        self.E.hp = self.E.HP  # 怪物血量更新
        print("**" * 22)


# ##################初始化角色##################
def init_player(name):  # 初始化玩家
    name = name
    lv = 1
    hp, mp = 20, 5
    STR, WIS, VIT, SPD, LUK = 2, 2, 2, 2, 2
    ATK = 10
    DEF = 5
    EXP = 7
    label = "player"
    # (self, name, lv, HP, MP, STR, WIS, VIT, SPD, ATK, DEF, exp, EXP=0, ptr=0, luck=0, bonus=0.0)
    P = Character(name, lv, hp, mp, STR=STR, WIS=WIS, VIT=VIT, SKI=SPD, ATK=ATK, DEF=DEF, EXP=EXP, LUK=LUK, label=label)
    return P


def init_enemy(name):  # 初始化敌人
    name = name
    lv = 1
    hp = random.randint(10, 15)
    mp = random.randint(5, 15)
    ATK = random.randint(3, 8)
    DEF = random.randint(1, 3)
    SPD = 1
    LUK = 1
    WIS = 30
    exp = 3
    rate = random.randint(1, 100)
    if rate > 99:
        label = "boss"  # BOSS
    elif rate > 90:
        label = "elite"  # 精英怪
    else:
        label = "normal"  # 普通怪
    E = Character(name, lv, hp, mp, WIS=WIS, ATK=ATK, DEF=DEF, exp=exp, SKI=SPD, LUK=LUK, label=label)
    return E


if __name__ == '__main__':
    Aron = init_player("奈非天")
    Zom = init_enemy("僵尸")
    print(Aron)
    print(Zom)

    for i in range(1, 2000):
        B = Battle(Aron, Zom)
        B.battle()
    print(Aron)
    print(Zom)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值