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  何定霓  阅读(136)  评论(0)    收藏  举报