制作一个简单的基于Python的基于文本的游戏
#初学者 #python #oop #gamedev

制作一个简单的基于文本的游戏是初学者致力于其编程技能并接触面向对象的编程(OOP)的好方法。一旦有了基本的设计,就很容易进一步扩展它并使您的游戏更加复杂。这篇文章向您展示了一个简单的基于文本的游戏,并解释了您如何创建自己的游戏。

地精和角斗士让玩家可以创建妖精和角斗士类型的角色,并使他们战斗(有点像口袋妖怪)。您可以找到游戏here的GitHub存储库,请随时将其用作您自己的游戏的灵感。

您可以看到游戏具有由虚幻引擎5:
开发的高度复杂的行业领先图形。

# A Goblin
               ||                                ||
               ||||                            ||||
               |||||                          |||||
               ||||||                        ||||||
               |||||||                      |||||||
               ||||||||||||||||||||||||||||||||||||
               ||||||||||||||||||||||||||||||||||||
               ||||||||||||||||||||||||||||||||||||
                ||||||||||||||||||||||||||||||||||
                 |||||||     ||||||||     |||||||
                 ||||||||||||||||||||||||||||||||
                 ||||||||||||||||||||||||||||||||
                 ||||||||||||||||||||||||||||||||
                 ||||||||||            ||||||||||
                 ||||||||||||||||||||||||||||||||
                   ||||||||||||||||||||||||||||
                      ||||||||||||||||||||||
                         ||||||||||||||||
                              ||||||

使您的游戏的步骤
设计和制作游戏遵循3个简单步骤:

  1. 头脑风暴
  2. 模型
  3. Coding

步骤1-头脑风暴
在开始使用写作代码之前,您想了解您的游戏的样子以及如何玩游戏。按照的方式思考游戏中的角色是什么样的?他们会做什么?他们会彼此互动吗?

我个人发现使用笔和纸可能非常适合勾勒出最初的想法。您可能会想出这样的图:

A simple sketch of the game

步骤2-模型
创建模型是过程的下一步。这通常是使用统一的标记语言(UML)完成的。这使您可以拿出草图并描述游戏,并展示不同组件如何相互作用。它类似于草图,但更详细,并且与游戏的编码方式更加紧密相关。

我在下面包括了Goblins&Gladiators的一个例子。您会注意到,设计从草图有所改变。这完全可以,设计和建模游戏的过程应该是迭代的,因此不必担心您是否必须回去进行更改。我不会详细解释我的图表,我只是想对自己的外观大致了解。

您会注意到哥布林和角斗士都从字符中继承了。从本质上讲,这意味着它们是一种角色,并共享其一些特征。如果这对您来说是新的,我鼓励您了解有关OOP的一些知识,我在下面提供了资源。

UML of the game

步骤3-代码
最后一步是实际编写您的游戏。同样,这可能是迭代的,您可能会提出新的想法,并重新审视更改设计的前一步。我在游戏中包括了一个角色类的示例,它是妖精和角斗士的基础。

class Character(ABC):
    __character_list = None  # Used in static method to return created characters

    def __init__(self, name, attack_strength, defence_strength, max_hp, item=""):
        """
        Constructor class that initiates Character objects
        """
        self.name = name
        self.attack_strength = attack_strength
        self.defence_strength = defence_strength
        self.max_hp = max_hp
        self.hp = max_hp  # Current hp can be equal to or less than max hp
        self.item = (
            item  # The character has no item as default but can equip up to 1 item
        )

    def attack(self, opponent):
        """
        Deals damage to opponent, note attack has random chance of missing and dealing 0 damage

        Parameters
        ----------
        opponent
            The character affected (Character)

        Returns
        --------
            If the attack is successfull, opponent receives damage from the attack. The amount of 
            damage dealt is equal to the attack_strength attacking character + randomized value 
            - defence_strength of defending chatacter. If the attack misses a string is printed to 
            notify attack has missed and no damage is dealt 
        """
        if self == opponent:
            print(f"{self.name} cannot attack itself, enter a different target")
            return None
        else:
            attack_hit_or_miss = randint(0, 4)  # Attack has random chance of missing
            if attack_hit_or_miss == 0:
                print("attack missed")
            else:
                random_damage_value = randint(
                    -1, 2
                )  # Random number altering the strength of attack

                opponent.receive_damage(
                    self.attack_strength
                    + random_damage_value
                    - opponent.defence_strength
                )
                if opponent.hp > 0:
                    print(
                        f"{self.name} attacked {opponent.name} who now has {opponent.hp} hp"
                    )
                elif opponent.hp <= 0:
                    print(
                        f"{self.name} defeated {opponent.name} who is now dead. {self.name} has won the contest"
                    )
                    visuals.win_visual()

    def equip_item(self, attatch_item):
        """
        Equips selected item to character

        Parameters
        ----------
        attatch_item
            The item the character is equipping (Item)

        Returns
        -------
            The character with its equipped item local parameter equal to the item name. This allows
            the character to use the equipped item
        """
        self.item = attatch_item.name
        print(f"{self.name} has now equipped {attatch_item.name}")

    def receive_damage(self, damage_amount):
        """
        Removes amount of damage recieved from own hp

        Parameters
        ----------
        damage_amount
            The amount of damage to recieve (int)

        Returns
        -------
            The character with damage_amount subtracted from its hp
        """
        self.hp = self.hp - damage_amount

    def character_details(self):
        """
        Gives key character details in a human readable sentence (more information than __str__)

        Returns
        --------
            The name, hp, attack_strength and defence_strength of the character 
        """
        return f"{self.name} has {self.hp} hp, {self.attack_strength} attack_strength and {self.defence_strength} defence_strength"

    @staticmethod
    def get_character_list():
        """
        Ensures only a singleton list of characters 

        Example
        -------
            the_characters = Character.get_character_list()
            the_characters.append(new_goblin_character)
            the_characters.append(new_gladiator_character)
            print(the_characters)
        """
        if Character.__character_list == None:
            Character.__character_list = []
        return Character.__character_list

再次不会陷入详细信息中。

已将其包括在内。

玩游戏
现在,这当然是重要的部分。实际上玩游戏。 repo中有详细的说明,但我想给您快速预览。基本上创建字符看起来有点像这样:

flame_goblin = characters.Goblin('flame goblin', 'fire')
fighter = characters.Gladiator('fighter')

您可以让他们相互攻击(或使用治愈法术和其他特殊能力):

flame_goblin.attack(fighter)
flame goblin attacked fighter who now has 8 hp"

战斗一直持续到一个角色死亡并失败。该游戏还显示了我之前显示的一些图形。

资源

  • Olivia Chiu Stone和Baron Stone的这款course非常适合学习面向对象的设计(请注意,它是为了支付的)
  • video是一个简单的基于口袋妖怪文本游戏的很好的例子
  • page有一些更多示例项目设计