从0开始用python写一个命令行小游戏(一)
最近在用python写一个命令行游戏:升(jian)级(hua)版植物大战僵尸,顺便巩固一下python编程技巧。在这个过程中,也收获(cai)了不少乐趣(keng)。目前1.0版已经在GitHub上发布,这是链接。今天就把全过程与大家分享~~~
既然是植物大战僵尸,肯定要有游戏盘。我想在一开始尽量简化游戏,所以用了一个一维数组:
# game.py board = [0] * 10
我想先不管阳光的问题,用一个类实现基础的植物大战僵尸角色的功能。
基础类
先上代码,基本功能都有了:
# game.py board = [0] * 10 class GameObject: indicating_char = 'o' # 在命令行显示的字符 def __init__(self, pos): """ 初始化,并把自己放上游戏盘 """ if pos in range(10): self.pos = pos if board[self.pos] == 0: board[self.pos] = self else: print("Position already used.") def __str__(self): """ 字符串表示 """ return self.indicating_char def __repr__(self): """ Python shell/print显示 """ return self.__str__()
嗯,去IPython里面试试看!
In [1]: import game as g In [2]: g.board Out[2]: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] In [3]: g.GameObject(0) Out[3]: o In [4]: g.board Out[4]: [o, 0, 0, 0, 0, 0, 0, 0, 0, 0]
不错!但是,也该为后续程序想想呀。比如,要让向日葵每步生产一定的阳光,或让最后一个僵尸死去时结束游戏,这些方法都应该在基础类中定义。于是,我在GameObject
类中追加了这些代码:
def step(self): """ 每步执行的操作 """ pass def die(self): """ 死掉时的操作 """ pass
好吧,两个空方法,但很快,GameObject
的子类们就会重写它们,使它们变得有意义的!
对了,说到子类,我们就先从植物开始吧!
植物基础类
先想想一株《植物大战僵尸》里的植物该有什么属性和行为吧。除了基础类里定义好的之外······阳光!种植植物需要阳光,这不就是属性吗?还有,当初始化一株植物时,扣除一定的阳光,不就是行为吗?来,先把这些实现了!
先在游戏盘定义的后面加上一行:
sunlight = 50
然后就是植物基础类Plant
:
class Plant(GameObject): indicating_char = 'p' def __init__(self, pos, sun_required): super().__init__(pos) global sunlight if sunlight >= sun_required: sunlight -= sun_required else: print("Sunlight not enough.")
好,这就成了。按照惯例,到IPython里试一试(注意!第一个坑):
In [1]: from game import * # 坑! In [2]: Plant(0, 50) Out[2]: p In [3]: sunlight Out[3]: 50
TMD怎么可能!!!难道sunlight不应该是0吗?!自己debug半天无果后我决定上思否提问。感谢思否!我上午提的问,下午就有了答案。于是,我赶快又去试了试:
In [1]: import game as g # 命名空间问题!!! In [2]: g.Plant(0, 50) Out[2]: p In [3]: g.sunlight Out[3]: 0
成功!
下集预告
下次,我将秀出真正“看得见”、也一直沿用至今的两个类:Sunflower
和Peashooter
。还有,我们的敌人:僵尸的基础类也该出场了!欢迎来看哦!