从0开始用python写一个命令行小游戏(二)

我回来了!今天,我们真正会亮相的植物要出来了哦!还有,我们敌人的基础类(我叫它BaseZombie)也会闪亮登(lai)场(xi)。很期待?那就开始吧!

注:我使用的是Python 3.7(但只要是3,变化应该都不大)。还有,这是第二篇。没看过上篇的话,这是链接。闲话少说,进入正题!

两种植物:SunflowerPeashooter

向日葵是Sunflower,豌豆射手是Peashooter。好,上代码!

向日葵

board = [0] * 10
sunlight = 50

class GameObject:
    indicating_char = ''       # 子类已经出现,所以把基础类的显示字符删除
    pass                       # 剩余部分同前

class Plant(GameObject):
    pass                       # 同前,但将显示字符删除

class Sunflower(Plant):
    """ 向日葵 """
    indicating_char = 's'
    
    def __init__(self, pos):
        """ 初始化,阳光50 """
        super().__init__(pos, 50)
    
    def step(self):
        """ 生产阳光 """
        global sunlight
        sunlight += 25

嗯,向日葵编好了。IPython(注:增强版Python shell),你怎么看?

In [1]: import game as g

In [2]: g.sunlight
Out[2]: 50

In [3]: g.Sunflower(0)
Out[3]: s

In [4]: g.board[0].step()

In [5]: g.sunlight
Out[5]: 25                    # 种植向日葵损失50,它又产生25

成功!现在,该编豌豆射手了。

豌豆射手

class Peashooter(Plant):
    indicating_char = 'p'
    
    def __init__(self, pos):
        super().__init__(pos, 100)           # 豌豆射手需要100阳光
    
    def step(self):
        for obj in board[self.pos:]:
            if isinstance(obj, BaseZombie):  # 就当BaseZombie存在
                pass                         # 哎呀!

好好编程,“哎呀”什么?因为我突然发现,目前还没有定义角色的生命值(你们尽情吐槽吧)!于是,在GameObject__init__方法前面追加:

class GameObject:
    blood = 10             # 初始生命值
    pass                   # 剩余同前

然后又突然想到,角色死没死不也是用这个定义的吗?于是加了几个方法和属性:

class GameObject:
    indicating_char = ''
    blood = 10
    alive = True
    
    def __init__(self, pos):
        pass                   # 同前
    
    def step(self):
        pass
    
    def die(self):
        pass
    
    def check(self):
        if self.blood < 1:
            self.alive = False
    
    def full_step(self):
        self.check()
        if not self.alive:
            board[self.pos] = 0
            self.die()
        else:
            self.step()

好,现在把豌豆射手里的那个pass改成:

for obj in board[self.pos:]:
    if isinstance(obj, BaseZombie):
        obj.blood -= 1.5            # 这里原来是pass

但是因为没有BaseZombie,我们也不能使用Peashooter。好,现在,3,2,1,放僵尸!

僵尸基础类

我们即将亲手创造游戏中的大坏蛋:僵尸!来吧,面对这个基础类······

class BaseZombie(GameObject):
    indicating_char = 'b'
    
    def __init__(self, pos, speed, harm, die_to_exit=False):
        super().__init__(pos)
        self.speed = speed
        self.harm = harm
        self.die_to_exit = die_to_exit
    
    def step(self):
        if board[self.pos - self.speed] == 0:
            orig_pos = self.pos
            self.pos -= self.speed
            board[orig_pos] = 0
            board[self.pos] = self
        elif isinstance(board[self.pos - 1], Plant):
            board[self.pos - 1].blood -= 1
        else:
            self.pos -= 1
            board[self.pos + 1] = 0
            board[self.pos] = self
    
    def die(self):
        if self.die_to_exit:
            import sys
            sys.exit()

好,让我们的新类们去IPython里大展身手吧!

In [1]: import game as g

In [2]: def step():
   ...:     for obj in g.board:
   ...:         if isinstance(obj, g.GameObject):
   ...:             obj.step()
   ...: 

In [3]: g.Sunflower(0)

In [4]: step()

In [5]: step()

In [6]: step()

In [7]: step()

In [8]: g.sunlight
Out[8]: 100

In [9]: g.Peashooter(1)

In [10]: g.BaseZombie(9, 1, 1)

In [11]: step()

In [12]: step()

......
In [18]: step()

In [19]: g.board
Out[19]: [s, p, 0, 0, 0, 0, 0, 0, 0, 0]

看来,豌豆射手打败僵尸了!

下集预告

下次,赶快把BaseZombie的子类编出来后,我们就要开始开发用户界面了!欢迎来看!

相关推荐