《易学Python》——6.6 怪物出没

6.6 怪物出没

至此,您创建了玩家、物品以及可捡拾的财宝。在这个冒险游戏中,还未添加的元素是意外的痛苦死亡,这也被称为危险和刺激。下面在游侠中添加一些怪物,它们在洞穴迷宫中四处游荡,受到威胁时可能攻击与它身处一个洞穴的玩家,还可能捡拾洞穴中的财宝。玩家也可攻击怪物及抢夺怪物的财宝。

6.6.1 创建怪物

咱们先想一想。您对怪物不是非常熟悉吗?下表对怪物和玩家做了比较。

怪物和玩家看起来有很多相同之处。在基于函数的程序中,您看到这一点后将意识到需要避免重复,但在面向对象的程序中,如何处理这种问题呢?答案是创建Player的子类,这通常被称为继承。

继承相当于这样说:复制一个类并稍作修改,使其以不同的方式完成这个类的功能。在这个游戏中,怪物的行为与玩家很像,但不是由玩家告诉它接下来如何做,而由怪物自己决定。怪物也需要有名称和描述,这样玩家才能寻找它们。这意味着怪物的方法__init__和get_input将不同,但您将保留Player类的其他方面不变。程序清单6.13是新类Monster的初稿。

程序清单6.13 在游戏中添加怪物

至此,您编写了Monster类,它与外部世界交互的能力与玩家相同,看到的信息也与玩家相同。这很重要,其原因有几个。下面就来深入介绍这些原因及其与面向对象设计的关系。

6.6.2 一些面向对象的技巧

使用继承的第一个原因是,可将通用功能放在基类中,这减少了让程序运行需要处理的特殊情况。您不需要两个独立的游戏循环—分别用于玩家和怪物,也不需要编写类似于下面的代码:if player then: ...else if monster then: ....,相反您可以相同的方式对待玩家和 怪物。

使用继承的第二个原因是,它让程序更容易扩展;就这里而言,这相当于打造了一个接口,怪物、玩家以及您能想到的其他任何东西都可通过它来与外部世界交互。如果需要在游戏中添加第三类参与者,只需编写这类参与者特有的部分。

最后一个原因是,使用继承可极大地减少您必须编写的代码量,并让程序更容易理解得多;不管程序是不是面向对象的,更容易理解总是件好事。

需要指出的另一点是,这并非设计类的唯一方式。另一种可能更佳的方式是,创建第三个类(称之为Mobile或Actor),将玩家和怪物的通用功能都放在其中,再让玩家和怪物继承这个类。在面向对象设计中,这样的类通常被称为抽象类:您不创建其实例,而继承它并添加缺失的功能,再创建子类的实例。

注意:

面向对象术语可能令人迷惑,但见过几个示例后,您就会发现它们非常简单。只需将其与您非常熟悉的东西关联起来即可,如本章的Cave、Player和Monster类。

在这里,使用抽象类的优势并不那么明显,因为您只有两个类。然而,如果以后您发现有些功能Player类需要,而Monster类不应该有(或Monster类需要,而Player类不应该有),就可使用一个抽象类。

另一个设计要点是,到目前未知,您一直倾向于使用组合而不是继承。继承通常被称为“是一个”关系:玩家是一个参与者(actor),怪物也是。而组合是“有一个”关系:洞穴中有一个玩家,而玩家有大量物品(item)。在组合关系中,对象之间的耦合程度通常更低些:要相互交互,它们必须通过方法调用并查看对方的值;而不像继承那样自动将一个对象的方法插入到另一个对象中。在大多数情况下,都应使用组合,但在正确的情况下使用继承时,结果将大不相同。图6.3说明了本章游戏中的各种组合和继承关系。

6.6.3 组合起来

编写好Player和Monster类后,需要对游戏处理玩家的方式做些修改。您不希望只从玩家那里获取输入——也应从怪物那里获取输入!您还希望将前面使用的函数都放在一个类中,让它们更容易正确地交互。为此,编写了程序清单6.14所示的类,您可使用它来设置游戏、创建洞穴系统以及获取输入(直到游戏结束)。

程序清单6.14 Game类

您需要做的最后一项工作是,在Player类中添加一个update函数。代码检查游戏中的所有对象时,将认为玩家以及从Player派生而来的对象都需要更新:

这个方法调用process_input,传入玩家的输入,并将返回值(一个字符串列表)存储到self.result中。您还需要给Player类添加一个name属性,因为Monster试图执行命令时,将对Player调用process_input。

如果您现在运行这个程序,将在当前洞穴中看到一个兽人(orc)。按回车键多次以模拟等待一段时间,而兽人将离开当前洞穴。如果您四处搜索,将发现兽人像无头苍蝇一样在洞穴迷宫中游荡。然而,除非您希望这个游戏像欧洲艺术剧院那样做徒劳的探索,最好再添加一些有趣的游戏元素。

时间: 2024-09-28 20:10:03

《易学Python》——6.6 怪物出没的相关文章

《易学Python》——导读

前 言 自序 受邀编写本书时,我无意再编写一本介绍性图书,而想采取不同的做法.我阅读过的编程图书无不罗列功能:列表可用于存储信息,您可调用len(mylist)来获悉它包含多少项信息,调用pop()来删除末尾的元素,调用append()来添加元素,等等.这些就是您需要知道的有关列表的全部知识,接下来介绍下一项功能.在这样的图书中,即便有示例程序,也要么只包含寥寥数行代码,要么出现在最后几章,作为对全书内容的总结. 我自己在最初学习编程时,并不是先从头到尾阅读整本编程图书,等对一切都熟悉后再开始编

《易学Python》——第6章 类与面向对象编程 6.1 类是什么

第6章 类与面向对象编程 本章介绍如下内容: 一种看待类的更简单方式: 如何使用类来设计程序. 在本书前面,始终未涉及Python中组织程序的基本方式之一:类.类和面向对象编程通常被认为是一个庞大而吓人的主题,仅供真正的程序员用来编写程序,因此您可能认为,要正确地使用它们,需要大量的理论知识.没有比这种看法更离谱的了.在Python中,使用类和面向编程易如反掌. 在本章中,您将首先复习第2章为游戏Hunt the Wumpus编写的洞穴生成代码,并了解到使用类编写这些代码容易得多:然后,您将以此

《易学Python》——6.3 玩家输入

6.3 玩家输入 大多数冒险游戏的玩法都是这样的:玩家输入指令,如往北走.拾剑.杀怪物和检宝,游戏再显示操作结果,以及有关玩家所处房间和房间中物件的描述.这里采取同样的方法,并利用一些对象的属性简化程序的扩展工作.别忘了,您还需让代码易于测试,因此将把处理用户输入的代码放在独立的函数中. 6.3.1 名词的动词化 您将首先寻找一种不错的方式,在类结构中编写将名词转换为动词的接口.通常情况下,对象为名词,而操作对象的方法为动词,因此命令GET SWORD应在当前房间找到Sword对象,并调用其Ge

《易学Python》——1.2 是什么让Python如此杰出

1.2 是什么让Python如此杰出 本书介绍Python,这也是我最喜欢的编程语言.对刚开始学习编程的初学者来说,Python是理想选择,其中的原因很多. 1.2.1 Python简单易学 如果将Python与其他编程语言进行比较,您首先将注意到它易于理解.Python的语法清晰得不能再清晰.下述特征让Python对用户非常友好. 它没有使用{.}.$./和等标点符号字符. Python使用缩进(而不是大括号)将程序分块. Python提倡程序员确保其程序清晰易读. Python支持很多程序结

《易学Python》—— 1.2 是什么让Python如此杰出

1.2 是什么让Python如此杰出 本书介绍Python,这也是我最喜欢的编程语言.对刚开始学习编程的初学者来说,Python是理想选择,其中的原因很多. 1.2.1 Python简单易学 如果将Python与其他编程语言进行比较,您首先将注意到它易于理解.Python的语法清晰得不能再清晰.下述特征让Python对用户非常友好. 它没有使用{.}.$./和等标点符号字符. Python使用缩进(而不是大括号)将程序分块. Python提倡程序员确保其程序清晰易读. Python支持很多程序结

《易学Python》——6.8 接下来如何做

6.8 接下来如何做 本章介绍了一些类和方法,这些只是可加入到游戏中的类和方法的冰山一角.您可根据喜好,沿任何方向进一步开发这个游戏,下面是一些有关如何扩展该游戏的想法. 6.8.1 增加怪物和财宝 当前,只有一个兽人和两个物品.您可添加其他类型的怪物和财宝(威力更大的武器或以不同方式影响怪物的武器).您还可以存储得分(该得分可通过Player类的score方法进行访问),并在玩家结束游戏或死亡时将得分打印出来. 6.8.2 扩展格斗方式和物品 您可以扩展Item类或方法Player.attac

《易学Python》——1.6 排除故障

1.6 排除故障 如果运行Python程序时没有看到窗口,问题可能出在几个地方.在您学习编程的过程中,可能经常遇到类似这样的错误.要解决问题,一个不错的做法是,将运行程序时出现的错误消息或症状作为关键字,在网上进行搜索.另外,深陷困境时,要大胆地寻求帮助,如通过Python邮件列表.下面介绍一些常见问题. 1.6.1 语法错误 如果您输入的程序代码有误,可能看到窗口出现后迅速消失.请核查输入的代码,确保所有代码都准确无误后,再次运行程序.如果程序依然不能正确运行,可尝试从命令行运行它,这让您能够

《易学Python》——1.4 Linux

1.4 Linux 如何在Linux系统上使用Python呢?这介绍起来比较麻烦,因为有很多不同的Linux版本,它们的工作方式存在细微差别.这里以Gnome和Ubuntu为例,其他Linux版本的情况与之类似. 1.4.1 在Linux系统上安装Python 在Linux系统上,并非必须手动安装Python,这取决于您使用的是哪种版本.大多数Linux版本都默认安装了Python,但通常不是最新版本.要获悉当前安装的是哪个版本,可使用命令python -V. 在Linux系统上安装Python

《易学Python》——6.7 危险与刺激

6.7 危险与刺激 本章游戏的最后一部分是让玩家和怪物相互攻击.对游戏来说,竞争氛围必不可少:格斗能力.速度.谁建造的城市最大.谁建造的房子最好等.在这里,您编写的是一个地下城冒险游戏,因此格斗必不可少:<龙与地下城>玩家都希望能够痛击兽人.鉴于格斗将在玩家和怪物之间展开,您首先给Player类添加一个attack方法,如程序清单6.15所示. 程序清单6.15 攻击其他参与者 这就是在游戏中支持格斗所需做的全部工作!鉴于妥善地封装了所有类,因此不需要对Cave.Item和Game类做任何修改