python之植物大战僵尸

`import pygame
import random
import sys
import os

全局常量定义素材路径(确保有 imgs 文件夹存放对应图片)

MAP_IMAGE = "E:/python代码/imgs/map1.png"
SUNFLOWER_IMAGE = "E:/python代码/imgs/map2.png"
PEASHOOTER_IMAGE = "E:/python代码/imgs/map3.png"
ZOMBIE_IMAGE = "E:/python代码/imgs/map4.png"
BULLET_IMAGE = "E:/python代码/imgs/map5.png"
SUN_IMAGE = "E:/python代码/imgs/map6.png"

初始化 Pygame

pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("植物大战僵尸")
clock = pygame.time.Clock()

全局变量

sunshine = 200 # 初始阳光数量
zombie_list = []
plant_list = []
bullet_list = []
sun_list = []
zombie_spawn_timer = 0 # 僵尸生成计时器,提前初始化

地图类

class Map:
def init(self, image_path):
try:
self.image = pygame.image.load(image_path).convert()
except:
self.image = pygame.Surface((800, 600))
self.image.fill((0, 128, 0)) # 绿色背景替代
self.rect = self.image.get_rect()

def display(self):
    screen.blit(self.image, self.rect)

植物基类

class Plant(pygame.sprite.Sprite):
def init(self, x, y, image_path, cost, health):
super().init()
try:
self.image = pygame.image.load(image_path).convert_alpha()
except:
self.image = pygame.Surface((50, 50))
self.image.fill((255, 0, 0))
self.rect = self.image.get_rect(topleft=(x, y))
self.cost = cost
self.health = health
self.is_alive = True

def update(self):
    if self.health <= 0:
        self.is_alive = False
        self.kill()

向日葵类

class Sunflower(Plant):
def init(self, x, y):
super().init(x, y, SUNFLOWER_IMAGE, 50, 100)
self.production_timer = 0

def produce_sunshine(self):
    self.production_timer += 1
    if self.production_timer >= 100:
        new_sun = Sun(self.rect.centerx, self.rect.centery)
        sun_list.append(new_sun)
        self.production_timer = 0

def display(self):
    if self.is_alive:
        screen.blit(self.image, self.rect)

豌豆射手类

class PeaShooter(Plant):
def init(self, x, y):
super().init(x, y, PEASHOOTER_IMAGE, 50, 100)
self.shoot_timer = 0

def shoot(self):
    self.shoot_timer += 1
    if self.shoot_timer >= 100:
        new_bullet = PeaBullet(self.rect.centerx + 30, self.rect.centery)
        bullet_list.append(new_bullet)
        self.shoot_timer = 0

def display(self):
    if self.is_alive:
        screen.blit(self.image, self.rect)

僵尸类

class Zombie(pygame.sprite.Sprite):
def init(self, x, y):
super().init()
try:
self.image = pygame.image.load(ZOMBIE_IMAGE).convert_alpha()
except:
self.image = pygame.Surface((60, 100))
self.image.fill((128, 128, 128))
self.rect = self.image.get_rect(topleft=(x, y))
self.health = 100
self.speed = 1
self.is_alive = True

def move(self):
    if self.is_alive:
        self.rect.x -= self.speed
        if self.rect.x < -self.rect.width:
            self.is_alive = False
            self.kill()

def display(self):
    if self.is_alive:
        screen.blit(self.image, self.rect)

子弹类

class PeaBullet(pygame.sprite.Sprite):
def init(self, x, y):
super().init()
try:
self.image = pygame.image.load(BULLET_IMAGE).convert_alpha()
except:
self.image = pygame.Surface((10, 5))
self.image.fill((255, 255, 0))
self.rect = self.image.get_rect(topleft=(x, y))
self.speed = 5
self.is_alive = True

def move(self):
    if self.is_alive:
        self.rect.x += self.speed
        if self.rect.x > 800:
            self.is_alive = False
            self.kill()

def hit(self):
    for zombie in zombie_list:
        if pygame.sprite.collide_rect(self, zombie):
            zombie.health -= 50
            self.is_alive = False
            self.kill()

def display(self):
    if self.is_alive:
        screen.blit(self.image, self.rect)

阳光类

class Sun(pygame.sprite.Sprite):
def init(self, x, y):
super().init()
try:
self.image = pygame.image.load(SUN_IMAGE).convert_alpha()
except:
self.image = pygame.Surface((30, 30), pygame.SRCALPHA)
pygame.draw.circle(self.image, (255, 215, 0), (15, 15), 15)
self.rect = self.image.get_rect(center=(x, y))
self.speed = 1
self.is_alive = True

def fall(self):
    if self.is_alive:
        self.rect.y += self.speed
        if self.rect.y > 600:
            self.is_alive = False
            self.kill()

def display(self):
    if self.is_alive:
        screen.blit(self.image, self.rect)

主游戏逻辑函数

def main():
global sunshine, zombie_spawn_timer
game_map = Map(MAP_IMAGE)
running = True
while running:
# 处理事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
# 判断种植向日葵
if sunshine >= 50 and y > 100:
clicked_plant = Sunflower(x - 25, y - 25)
plant_list.append(clicked_plant)
sunshine -= 50
# 判断种植豌豆射手
elif sunshine >= 100 and y > 100:
clicked_plant = PeaShooter(x - 25, y - 25)
plant_list.append(clicked_plant)
sunshine -= 100
# 收集阳光
for sun in sun_list:
if sun.rect.collidepoint(x, y):
sunshine += 25
sun.is_alive = False
sun.kill()

    # 生成僵尸
    zombie_spawn_timer += 1
    if zombie_spawn_timer >= 300:
        zombie_y = random.randint(100, 400)
        new_zombie = Zombie(800, zombie_y)
        zombie_list.append(new_zombie)
        zombie_spawn_timer = 0

    # 更新植物
    for plant in plant_list:
        if isinstance(plant, Sunflower):
            plant.produce_sunshine()
        elif isinstance(plant, PeaShooter):
            plant.shoot()
        plant.update()

    # 更新僵尸
    for zombie in zombie_list:
        zombie.move()

    # 更新子弹
    for bullet in bullet_list:
        bullet.move()
        bullet.hit()

    # 更新阳光
    for sun in sun_list:
        sun.fall()

    # 绘制地图
    game_map.display()
    # 绘制植物
    for plant in plant_list:
        plant.display()
    # 绘制僵尸
    for zombie in zombie_list:
        zombie.display()
    # 绘制子弹
    for bullet in bullet_list:
        bullet.display()
    # 绘制阳光
    for sun in sun_list:
        sun.display()

    # 显示阳光数量
    font = pygame.font.SysFont(None, 36)
    sunshine_text = font.render(f"阳光: {sunshine}", True, (255, 255, 0))
    screen.blit(sunshine_text, (10, 10))

    # 控制帧率
    clock.tick(30)
    pygame.display.flip()

pygame.quit()
sys.exit()

if name == "main":
main()`

posted @ 2025-06-23 13:29  何定霓  阅读(23)  评论(0)    收藏  举报