利用python写一段植物大战僵尸的代码

62 阅读5分钟

python

运行

import random
import time

# 基础游戏配置
SCREEN_WIDTH = 10  # 游戏场地宽度(格子数)
SCREEN_HEIGHT = 5  # 游戏场地高度(行数)
SUN_INTERVAL = 5   # 阳光生成间隔(秒)
INIT_SUN = 50      # 初始阳光数量

# 植物基类
class Plant:
    def __init__(self, name, cost, hp, attack, attack_range, row):
        self.name = name    # 植物名称
        self.cost = cost    # 阳光消耗
        self.hp = hp        # 生命值
        self.attack = attack# 攻击力
        self.range = attack_range  # 攻击范围
        self.row = row      # 所在行
        self.col = None     # 所在列(种植时赋值)
        self.is_alive = True

    def take_damage(self, damage):
        """受到伤害"""
        self.hp -= damage
        if self.hp <= 0:
            self.is_alive = False

    def attack_zombie(self, zombies):
        """攻击僵尸(子类实现)"""
        pass

# 豌豆射手(具体植物)
class Peashooter(Plant):
    def __init__(self, row, col):
        super().__init__("豌豆射手", 100, 300, 20, 5, row)
        self.col = col

    def attack_zombie(self, zombies):
        """攻击前方最近的僵尸"""
        target = None
        # 查找同行了、在攻击范围内的僵尸
        for zombie in zombies:
            if (zombie.row == self.row and 
                zombie.col > self.col and 
                zombie.col - self.col <= self.range and 
                zombie.is_alive):
                target = zombie
                break
        if target:
            target.take_damage(self.attack)
            print(f"🌱 豌豆射手[{self.row},{self.col}]攻击僵尸[{target.row},{target.col}],造成{self.attack}伤害!")

# 向日葵(具体植物)
class Sunflower(Plant):
    def __init__(self, row, col):
        super().__init__("向日葵", 50, 300, 0, 0, row)
        self.col = col
        self.last_sun_time = time.time()  # 上次生产阳光时间

    def produce_sun(self, game):
        """生产阳光"""
        current_time = time.time()
        if current_time - self.last_sun_time >= SUN_INTERVAL:
            game.sun += 25
            self.last_sun_time = current_time
            print(f"🌻 向日葵[{self.row},{self.col}]生产了25阳光!当前阳光:{game.sun}")

# 僵尸基类
class Zombie:
    def __init__(self, name, hp, attack, speed, row):
        self.name = name    # 僵尸名称
        self.hp = hp        # 生命值
        self.attack = attack# 攻击力
        self.speed = speed  # 移动速度(秒/格)
        self.row = row      # 所在行
        self.col = SCREEN_WIDTH - 1  # 初始在最右侧
        self.is_alive = True
        self.last_move_time = time.time()  # 上次移动时间
        self.last_attack_time = time.time()# 上次攻击时间

    def take_damage(self, damage):
        """受到伤害"""
        self.hp -= damage
        if self.hp <= 0:
            self.is_alive = False
            print(f"🧟 僵尸[{self.row},{self.col}]被消灭!")

    def move(self):
        """移动(向左)"""
        current_time = time.time()
        if current_time - self.last_move_time >= self.speed and self.col > 0:
            self.col -= 1
            self.last_move_time = current_time
            print(f"🧟 僵尸[{self.row},{self.col}]移动了!")

    def attack_plant(self, plants):
        """攻击相邻的植物"""
        target = None
        for plant in plants:
            if (plant.row == self.row and 
                plant.col == self.col - 1 and 
                plant.is_alive):
                target = plant
                break
        if target:
            current_time = time.time()
            if current_time - self.last_attack_time >= 1:  # 1秒攻击一次
                target.take_damage(self.attack)
                self.last_attack_time = current_time
                print(f"🧟 僵尸[{self.row},{self.col}]攻击{target.name}[{target.row},{target.col}],造成{self.attack}伤害!")
                if not target.is_alive:
                    print(f"🌱 {target.name}[{target.row},{target.col}]被摧毁!")

# 游戏核心类
class PVZGame:
    def __init__(self):
        self.sun = INIT_SUN                # 当前阳光数量
        self.plants = []                   # 所有植物
        self.zombies = []                  # 所有僵尸
        self.game_over = False             # 游戏结束标记
        self.last_zombie_spawn = time.time()  # 上次生成僵尸时间

    def spawn_zombie(self):
        """随机生成僵尸"""
        current_time = time.time()
        # 每3-5秒生成一个普通僵尸
        if current_time - self.last_zombie_spawn >= random.randint(3, 5):
            row = random.randint(0, SCREEN_HEIGHT - 1)
            zombie = Zombie("普通僵尸", 200, 50, 2, row)  # 血量200,攻击50,2秒移一格
            self.zombies.append(zombie)
            self.last_zombie_spawn = current_time
            print(f"🧟 新僵尸生成在[{row},{zombie.col}]!")

    def plant_plant(self, plant_type, row, col):
        """种植植物"""
        # 检查位置是否合法
        if row < 0 or row >= SCREEN_HEIGHT or col < 0 or col >= SCREEN_WIDTH:
            print("❌ 位置超出范围!")
            return
        # 检查位置是否已有植物
        for plant in self.plants:
            if plant.row == row and plant.col == col and plant.is_alive:
                print("❌ 该位置已有植物!")
                return
        
        # 检查阳光是否足够
        if plant_type == "peashooter":
            plant = Peashooter(row, col)
        elif plant_type == "sunflower":
            plant = Sunflower(row, col)
        else:
            print("❌ 未知植物类型!")
            return
        
        if self.sun < plant.cost:
            print(f"❌ 阳光不足!需要{plant.cost},当前{self.sun}")
            return
        
        # 种植植物
        self.sun -= plant.cost
        self.plants.append(plant)
        print(f"✅ 成功种植{plant.name}[{row},{col}]!剩余阳光:{self.sun}")

    def check_game_over(self):
        """检查游戏是否结束(僵尸到达最左侧)"""
        for zombie in self.zombies:
            if zombie.col == 0 and zombie.is_alive:
                self.game_over = True
                print("💀 游戏结束!僵尸突破防线了!")
                return True
        return False

    def clean_dead_units(self):
        """清理死亡的植物和僵尸"""
        self.plants = [p for p in self.plants if p.is_alive]
        self.zombies = [z for z in self.zombies if z.is_alive]

    def game_loop(self):
        """游戏主循环"""
        print("🌿 植物大战僵尸(简化版)开始!")
        print(f"🎮 操作说明:")
        print(f"  1. 输入 'plant 豌豆射手 行 列' 种植豌豆射手(消耗100阳光)")
        print(f"  2. 输入 'plant 向日葵 行 列' 种植向日葵(消耗50阳光)")
        print(f"  3. 输入 'exit' 退出游戏")
        print(f"初始阳光:{self.sun}\n")

        while not self.game_over:
            # 1. 生成僵尸
            self.spawn_zombie()

            # 2. 植物行动(向日葵产阳光、豌豆射手攻击)
            for plant in self.plants:
                if isinstance(plant, Sunflower):
                    plant.produce_sun(self)
                elif isinstance(plant, Peashooter):
                    plant.attack_zombie(self.zombies)

            # 3. 僵尸行动(移动、攻击)
            for zombie in self.zombies:
                if zombie.is_alive:
                    zombie.move()
                    zombie.attack_plant(self.plants)

            # 4. 检查游戏结束
            if self.check_game_over():
                break

            # 5. 清理死亡单位
            self.clean_dead_units()

            # 6. 玩家输入
            try:
                user_input = input("请输入操作:").strip()
                if user_input.lower() == "exit":
                    print("👋 游戏退出!")
                    self.game_over = True
                elif user_input.startswith("plant"):
                    # 解析输入:plant 豌豆射手 0 1
                    parts = user_input.split()
                    if len(parts) != 4:
                        print("❌ 格式错误!正确格式:plant 豌豆射手 行 列")
                        continue
                    plant_type = parts[1]
                    try:
                        row = int(parts[2])
                        col = int(parts[3])
                        if plant_type == "豌豆射手":
                            self.plant_plant("peashooter", row, col)
                        elif plant_type == "向日葵":
                            self.plant_plant("sunflower", row, col)
                        else:
                            print("❌ 仅支持种植:豌豆射手、向日葵")
                    except ValueError:
                        print("❌ 行和列必须是数字!")
                else:
                    print("❌ 无效操作!")
            except KeyboardInterrupt:
                print("\n👋 游戏强制退出!")
                self.game_over = True

            # 游戏循环间隔(降低CPU占用)
            time.sleep(0.5)

# 启动游戏
if __name__ == "__main__":
    game = PVZGame()
    game.game_loop()

代码说明

1. 核心模块

  • 植物类:基类Plant定义通用属性,Peashooter(豌豆射手)实现攻击逻辑,Sunflower(向日葵)实现阳光生产逻辑。
  • 僵尸类Zombie实现移动、攻击植物的核心逻辑。
  • 游戏类PVZGame管理游戏状态(阳光、植物、僵尸),处理种植、生成僵尸、游戏循环等核心流程。

2. 游戏规则

  • 初始阳光:50
  • 向日葵:消耗 50 阳光,每 5 秒生产 25 阳光
  • 豌豆射手:消耗 100 阳光,攻击前方 5 格内的最近僵尸(每轮攻击 20 伤害)
  • 普通僵尸:血量 200,攻击 50(1 秒一次),2 秒移动一格
  • 游戏结束条件:僵尸到达最左侧(列 0)

3. 操作说明

运行代码后,在控制台输入以下指令:

  • 种植向日葵:plant 向日葵 行 列(例如:plant 向日葵 0 0
  • 种植豌豆射手:plant 豌豆射手 行 列(例如:plant 豌豆射手 0 1
  • 退出游戏:exit

扩展方向

这个简化版可以进一步扩展:

  1. 增加更多植物(坚果墙、寒冰射手等)和僵尸类型(路障僵尸、铁桶僵尸)
  2. 实现图形界面(使用 Pygame 库)
  3. 增加阳光掉落机制(随机生成阳光,玩家点击收集)
  4. 加入关卡系统、僵尸波次
  5. 实现植物冷却时间、僵尸攻击动画等细节