Python技术迷

用Python写了一个植物大战僵尸

聊聊我最近做的一个小项目——用 Python 和 Pygame 写的一个“植物大战僵尸”游戏。
没错,和那个经典的塔防游戏一样,我们得种植植物来防御一波波的僵尸攻击,挺简单的思路,做起来却特别有趣。既能回味童年,又能锻炼编程技能,双赢!
于是我就决定写个小游戏,顺便学习一下Pygame库,顺便把游戏设计的逻辑捋一捋。今天就来跟大家分享一下这个简单但好玩的项目吧,看看我在做这款游戏时的经历和一些细节实现。

游戏结构的设计

在写这款游戏时,我主要分成几个模块来开发。首先就是引入的必要模块。我们都知道,做游戏用 Pygame 是非常合适的,它为我们提供了很多功能,像是处理图像、音效、事件响应等。其次,游戏中植物和僵尸的设计也需要一些类来管理它们的状态和行为。

1. 引入模块和配置

首先,我们要引入一些基础模块,比如 pygame 和 random 。前者用来处理图形和用户输入,后者用来随机生成僵尸和阳光之类的元素。
import pygame
import random

# 设置屏幕大小
scrrr_width = 800
scrrr_height = 560
IMAGE_PATH = 'imgs/'  # 图片路径

# 游戏结束标志
GAMEOVER = False

# 游戏初始化
pygame.init()
screen = pygame.display.set_mode((scrrr_width, scrrr_height))
pygame.display.set_caption("植物大战僵尸")
这块代码负责初始化游戏窗口和图像路径, pygame.display.set_caption 用来设置窗口标题,确保我们启动时看到的是《植物大战僵尸》。

2. 设计游戏类

地图类 Map
地图类的作用是管理每个格子是否可以种植植物,以及显示当前地图状态。我们可以通过图像来加载和显示地图上的每个格子。
class Map(pygame.sprite.Sprite):
    def __init__(self, x, y, img_index):
        super().__init__()
        self.x = x
        self.y = y
        self.img_index = img_index  # 地图格子的图片索引
        self.image = pygame.image.load(IMAGE_PATH + "map" + str(img_index) + ".png")
        self.rect = self.image.get_rect()
        self.rect.topleft = (x, y)
        self.can_grow = True  # 是否可以种植植物

    def load_map(self):
        screen.blit(self.image, (self.x, self.y))
这个类通过 pygame.sprite.Sprite 来继承精灵类,简单地加载和显示地图格子。
植物类 Plant
植物类是所有植物的基类,它负责一些通用的功能,比如加载植物图像和显示植物。具体的植物(像向日葵和豌豆射手)会继承这个类并添加特有的属性和方法。
class Plant(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.hp = 100  # 生命值
        self.price = 50  # 价格
        self.image = None
        self.rect = None

    def load_image(self):
        # 这里可以加载植物图像
        pass

    def display_plant(self):
        # 显示植物的逻辑
        screen.blit(self.image, self.rect)
向日葵类 Sunflower
向日葵是基础的植物,用来生成阳光来购买更多的植物。
class Sunflower(Plant):
    def __init__(self):
        super().__init__()
        self.price = 50  # 向日葵的价格
        self.hp = 100  # 向日葵的生命值
        self.time_count = 0  # 用来计时生成阳光的间隔
        self.image = pygame.image.load(IMAGE_PATH + "sunflower.png")
        self.rect = self.image.get_rect()

    def produce_money(self):
        # 每隔一段时间生成阳光
        if self.time_count % 300 == 0:
            return 25  # 生成25个阳光
        return 0

    def display_sunflower(self):
        screen.blit(self.image, self.rect)
向日葵的 produce_money() 方法实现了定时生成阳光的功能,游戏中的阳光会不断积累,玩家可以用它来购买更多植物。
豌豆射手类 PeaShooter
豌豆射手是攻击性植物,用来发射豌豆攻击僵尸。
class PeaShooter(Plant):
    def __init__(self):
        super().__init__()
        self.price = 50
        self.hp = 200
        self.shot_count = 0  # 发射的豌豆数量
        self.image = pygame.image.load(IMAGE_PATH + "peashooter.png")
        self.rect = self.image.get_rect()

    def shot(self):
        # 发射豌豆
        pass

    def display_peashooter(self):
        screen.blit(self.image, self.rect)
豌豆射手有一个 shot() 方法,用来处理豌豆的发射,碰到僵尸时会造成伤害。

3. 游戏逻辑

游戏的核心就是植物与僵尸之间的互动。植物会发射子弹(豌豆)攻击前进的僵尸,而僵尸会向植物靠近并吃掉它们。每个类的功能非常模块化,维护起来比较容易。
僵尸类 Zombie
僵尸类则负责描述僵尸的行为,比如移动、吃植物等。
class Zombie(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.hp = 1000  # 僵尸的生命值
        self.speed = 1  # 僵尸的移动速度
        self.image = pygame.image.load(IMAGE_PATH + "zombie.png")
        self.rect = self.image.get_rect()

    def move_zombie(self):
        # 僵尸移动的逻辑
        self.rect.x -= self.speed

    def eat_plant(self, plant):
        # 僵尸吃植物的逻辑
        pass

    def display_zombie(self):
        screen.blit(self.image, self.rect)
僵尸会根据自己的速度往左边移动,一旦接触到植物就开始攻击它们。

游戏主逻辑

在 MainGame 类中,我们管理游戏的状态、植物和僵尸的生成与更新。每一帧都会刷新界面,响应玩家的输入。
class MainGame:
    def __init__(self):
        self.game_over = False
        self.plants_list = []
        self.zombies_list = []
        self.score = 0
        self.money = 100
        self.time_count = 0

    def start_game(self):
        while not self.game_over:
            self.time_count += 1
            self.deal_events()
            self.update_game_state()
            pygame.display.update()

    def deal_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.game_over = True
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # 根据点击的位置种植物
                pass

    def update_game_state(self):
        # 更新植物、僵尸等状态
        pass

结束语

这样,我们就有了一个简单的“植物大战僵尸”游戏框架,当然细节还需要进一步完善,比如碰撞检测、植物的升级、更多的僵尸类型等。
总的来说,这个游戏项目不仅有趣而且充满挑战,我觉得它很适合用来练习 Python 编程和 Pygame 库的使用。


如果你也有兴趣做类似的游戏,不妨试试自己写一个简单的版本,保证能从中获得不少乐趣!
对编程、职场感兴趣的同学,大家可以联系我微信: golang404 ,拉你进入“程序员交流群”。
🔥 虎哥私藏精品 热门推荐 🔥 虎哥作为一名老码农,整理了全网最全 《python高级架构师资料合集》 。 资料包含了 《IDEA视频教程》 、 《最全python面试题库》 、 《最全项目实战源码及视频》 及 《毕业设计系统源码》 ,总量高达 650GB , 全部 免费领取 。