植物大战僵尸简易版小游戏
import pygame
import random
import sys
初始化pygame
pygame.init()
屏幕设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("植物大战僵尸简化版 - 3012")
颜色定义
GREEN = (0, 255, 0)
BROWN = (139, 69, 19)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
游戏参数
FPS = 60
clock = pygame.time.Clock()
草坪网格
GRID_SIZE = 80
GRID_ROWS = 5
GRID_COLS = 9
GRID_OFFSET_X = 50
GRID_OFFSET_Y = 100
植物类
class Plant:
def init(self, row, col):
self.row = row
self.col = col
self.health = 100
self.x = GRID_OFFSET_X + col * GRID_SIZE + GRID_SIZE//2
self.y = GRID_OFFSET_Y + row * GRID_SIZE + GRID_SIZE//2
self.shoot_timer = 0
self.shoot_delay = 60 # 每秒发射一次
def update(self):
self.shoot_timer += 1
if self.shoot_timer >= self.shoot_delay:
self.shoot_timer = 0
return True # 可以发射豌豆
return False
def draw(self):
# 绘制植物主体
pygame.draw.circle(screen, GREEN, (self.x, self.y), 30)
# 绘制健康条
health_width = 60 * (self.health / 100)
pygame.draw.rect(screen, (255, 0, 0), (self.x - 30, self.y - 45, 60, 5))
pygame.draw.rect(screen, (0, 255, 0), (self.x - 30, self.y - 45, health_width, 5))
豌豆类
class Pea:
def init(self, x, y):
self.x = x
self.y = y
self.speed = 7
self.damage = 20
def update(self):
self.x += self.speed
def draw(self):
pygame.draw.circle(screen, GREEN, (self.x, self.y), 10)
def is_off_screen(self):
return self.x > WIDTH
僵尸类
class Zombie:
def init(self, row):
self.row = row
self.x = WIDTH
self.y = GRID_OFFSET_Y + row * GRID_SIZE + GRID_SIZE//2
self.speed = 0.1
self.health = 100
self.damage = 0.5
def update(self):
self.x -= self.speed
def draw(self):
# 绘制僵尸主体
pygame.draw.rect(screen, BROWN, (self.x - 20, self.y - 40, 40, 80))
# 绘制健康条
health_width = 40 * (self.health / 100)
pygame.draw.rect(screen, (255, 0, 0), (self.x - 20, self.y - 50, 40, 5))
pygame.draw.rect(screen, (0, 255, 0), (self.x - 20, self.y - 50, health_width, 5))
def is_at_house(self):
return self.x < 50
def is_dead(self):
return self.health <= 0
阳光类
class Sun:
def init(self, x, y):
self.x = x
self.y = y
self.target_y = y + random.randint(100, 200)
self.speed = 1
self.life = 300 # 5秒存在时间
self.collected = False
def update(self):
if self.y < self.target_y:
self.y += self.speed
self.life -= 1
def draw(self):
pygame.draw.circle(screen, YELLOW, (self.x, self.y), 20)
def is_expired(self):
return self.life <= 0 or self.collected
游戏状态
plants = []
peas = []
zombies = []
suns = []
sun = 100 # 初始阳光
game_over = False
score = 0
zombie_spawn_timer = 0
sun_spawn_timer = 0
游戏主循环
running = True
while running:
# 事件处理
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN and not game_over:
mouse_x, mouse_y = pygame.mouse.get_pos()
# 检查是否点击了阳光
for sun_obj in suns[:]:
if ((sun_obj.x - mouse_x)**2 + (sun_obj.y - mouse_y)**2) < 400: # 20px半径
sun_obj.collected = True
suns.remove(sun_obj)
sun += 25
break
# 检查是否点击了网格放置植物
if (GRID_OFFSET_X <= mouse_x <= GRID_OFFSET_X + GRID_COLS * GRID_SIZE and
GRID_OFFSET_Y <= mouse_y <= GRID_OFFSET_Y + GRID_ROWS * GRID_SIZE):
col = (mouse_x - GRID_OFFSET_X) // GRID_SIZE
row = (mouse_y - GRID_OFFSET_Y) // GRID_SIZE
# 检查是否已经有植物在这个位置
plant_exists = False
for plant in plants:
if plant.row == row and plant.col == col:
plant_exists = True
break
if not plant_exists and sun >= 100:
plants.append(Plant(row, col))
sun -= 100
if event.type == pygame.KEYDOWN and game_over:
if event.key == pygame.K_r:
# 重置游戏
plants = []
peas = []
zombies = []
suns = []
sun = 100
game_over = False
score = 0
zombie_spawn_timer = 0
sun_spawn_timer = 0
if not game_over:
# 生成阳光
sun_spawn_timer += 1
if sun_spawn_timer >= 300: # 每5秒生成一个阳光
sun_spawn_timer = 0
suns.append(Sun(
random.randint(GRID_OFFSET_X, GRID_OFFSET_X + GRID_COLS * GRID_SIZE),
GRID_OFFSET_Y - 50
))
# 生成僵尸
zombie_spawn_timer += 1
if zombie_spawn_timer >= 450: # 每7.5秒生成一个僵尸
zombie_spawn_timer = 0
zombies.append(Zombie(random.randint(0, GRID_ROWS - 1)))
# 更新植物
for plant in plants:
if plant.update(): # 如果植物可以发射豌豆
peas.append(Pea(plant.x + 30, plant.y))
# 更新豌豆
for pea in peas[:]:
pea.update()
if pea.is_off_screen():
peas.remove(pea)
continue
# 检测豌豆是否击中僵尸
for zombie in zombies[:]:
if (zombie.row == (pea.y - GRID_OFFSET_Y) // GRID_SIZE and
abs(zombie.x - pea.x) < 30):
zombie.health -= pea.damage
if zombie.is_dead():
zombies.remove(zombie)
score += 10
sun += 5
peas.remove(pea)
break
# 更新僵尸
for zombie in zombies[:]:
zombie.update()
# 检测僵尸是否到达房子
if zombie.is_at_house():
game_over = True
# 检测僵尸是否在吃植物
for plant in plants[:]:
if (zombie.row == plant.row and
abs(zombie.x - plant.x) < 30):
plant.health -= zombie.damage
if plant.health <= 0:
plants.remove(plant)
break
# 更新阳光
for sun_obj in suns[:]:
sun_obj.update()
if sun_obj.is_expired():
suns.remove(sun_obj)
# 绘制
screen.fill(BLACK)
# 绘制草坪网格
for row in range(GRID_ROWS):
for col in range(GRID_COLS):
rect = pygame.Rect(
GRID_OFFSET_X + col * GRID_SIZE,
GRID_OFFSET_Y + row * GRID_SIZE,
GRID_SIZE, GRID_SIZE
)
pygame.draw.rect(screen, (0, 100, 0) if (row + col) % 2 == 0 else (0, 120, 0), rect)
pygame.draw.rect(screen, (50, 50, 50), rect, 1)
# 绘制植物
for plant in plants:
plant.draw()
# 绘制豌豆
for pea in peas:
pea.draw()
# 绘制僵尸
for zombie in zombies:
zombie.draw()
# 绘制阳光
for sun_obj in suns:
sun_obj.draw()
# 绘制阳光数量
font = pygame.font.SysFont(None, 36)
sun_text = font.render(f"阳光: {sun}", True, WHITE)
screen.blit(sun_text, (20, 20))
# 绘制分数
score_text = font.render(f"分数: {score}", True, WHITE)
screen.blit(score_text, (20, 60))
# 绘制提示
hint_text = font.render("点击格子放置豌豆(100阳光)", True, WHITE)
screen.blit(hint_text, (20, HEIGHT - 40))
# 绘制游戏结束信息
if game_over:
game_over_text = font.render("游戏结束! 按R键重新开始", True, (255, 0, 0))
screen.blit(game_over_text, (WIDTH//2 - 150, HEIGHT//2))
# 3012特殊标志 - 在右下角显示
signature = font.render("PVZ Simple by 3012", True, YELLOW)
screen.blit(signature, (WIDTH - 180, HEIGHT - 30))
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
sys.exit()


浙公网安备 33010602011771号