import pygame import random import sys from pygame.locals import * # 初始化pygame pygame.init() # 游戏窗口设置 SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption('植物大战僵尸简化版') # 颜色定义 WHITE = (255, 255, 255) BLACK = (0, 0, 0) GREEN = (0, 255, 0) BROWN = (139, 69, 19) YELLOW = (255, 255, 0) BLUE = (0, 0, 255) # 游戏参数 FPS = 60 clock = pygame.time.Clock() # 游戏资源 font = pygame.font.SysFont('Arial', 24) class Sun: def __init__(self): self.x = random.randint(50, SCREEN_WIDTH - 50) self.y = 0 self.speed = 2 self.target_y = random.randint(100, 400) self.collected = False self.value = 25 self.radius = 20 self.timer = 0 def update(self): if not self.collected and self.y < self.target_y: self.y += self.speed elif not self.collected: self.timer += 1 if self.timer > 300: # 5秒后消失 self.y = -100 def draw(self, surface): if not self.collected and self.y < SCREEN_HEIGHT: pygame.draw.circle(surface, YELLOW, (self.x, self.y), self.radius) pygame.draw.circle(surface, (255, 215, 0), (self.x, self.y), self.radius - 5) def is_clicked(self, pos): distance = ((pos[0] - self.x) ** 2 + (pos[1] - self.y) ** 2) ** 0.5 return distance <= self.radius and not self.collected class Plant: def __init__(self, x, y, plant_type): self.x = x self.y = y self.type = plant_type self.health = 100 self.attack_timer = 0 self.attack_rate = 60 # 每秒攻击一次 self.cost = 100 if plant_type == "peashooter" else 50 def update(self): self.attack_timer += 1 def draw(self, surface): if self.type == "peashooter": pygame.draw.circle(surface, GREEN, (self.x + 25, self.y + 25), 20) pygame.draw.rect(surface, GREEN, (self.x + 15, self.y + 40, 20, 10)) else: # sunflower pygame.draw.circle(surface, YELLOW, (self.x + 25, self.y + 25), 20) pygame.draw.rect(surface, GREEN, (self.x + 15, self.y + 40, 20, 10)) def can_attack(self): return self.attack_timer >= self.attack_rate and self.type == "peashooter" def reset_attack_timer(self): self.attack_timer = 0 class Pea: def __init__(self, x, y): self.x = x self.y = y + 15 self.speed = 5 self.damage = 20 self.active = True def update(self): self.x += self.speed if self.x > SCREEN_WIDTH: self.active = False def draw(self, surface): pygame.draw.circle(surface, GREEN, (self.x, self.y), 5) class Zombie: def __init__(self, row): self.x = SCREEN_WIDTH self.y = 100 + row * 100 self.speed = 1 self.health = 100 self.damage = 0.5 self.attack_timer = 0 self.attack_rate = 30 def update(self): self.x -= self.speed self.attack_timer += 1 def draw(self, surface): pygame.draw.rect(surface, (100, 100, 100), (self.x, self.y, 40, 80)) # 血条 pygame.draw.rect(surface, (255, 0, 0), (self.x, self.y - 10, 40, 5)) pygame.draw.rect(surface, (0, 255, 0), (self.x, self.y - 10, 40 * (self.health / 100), 5)) def can_attack(self): return self.attack_timer >= self.attack_rate def reset_attack_timer(self): self.attack_timer = 0 class Game: def __init__(self): self.plants = [] self.zombies = [] self.peas = [] self.suns = [] self.sun_count = 50 self.selected_plant = None self.grid = [[None for _ in range(5)] for _ in range(5)] self.zombie_timer = 0 self.zombie_rate = 300 # 每5秒出一个僵尸 self.sun_timer = 0 self.sun_rate = 200 # 每3秒出一个阳光 self.game_over = False def update(self): # 更新阳光 self.sun_timer += 1 if self.sun_timer >= self.sun_rate: self.suns.append(Sun()) self.sun_timer = 0 for sun in self.suns[:]: sun.update() if sun.y < 0: self.suns.remove(sun) # 更新植物 for plant in self.plants: plant.update() if plant.can_attack(): self.peas.append(Pea(plant.x + 40, plant.y)) plant.reset_attack_timer() # 更新豌豆 for pea in self.peas[:]: pea.update() if not pea.active: self.peas.remove(pea) # 更新僵尸 self.zombie_timer += 1 if self.zombie_timer >= self.zombie_rate and not self.game_over: self.zombies.append(Zombie(random.randint(0, 4))) self.zombie_timer = 0 for zombie in self.zombies[:]: zombie.update() # 检测僵尸是否碰到植物 for plant in self.plants[:]: if (zombie.x < plant.x + 40 and zombie.x + 40 > plant.x and zombie.y < plant.y + 80 and zombie.y + 80 > plant.y): if zombie.can_attack(): plant.health -= zombie.damage zombie.reset_attack_timer() if plant.health <= 0: self.plants.remove(plant) row = (plant.y - 100) // 100 col = (plant.x - 200) // 100 self.grid[row][col] = None break else: # 检测僵尸是否到达左边界 if zombie.x < 150: self.game_over = True # 检测豌豆是否击中僵尸 for pea in self.peas[:]: if (pea.x > zombie.x and pea.x < zombie.x + 40 and pea.y > zombie.y and pea.y < zombie.y + 80): zombie.health -= pea.damage self.peas.remove(pea) if zombie.health <= 0: self.zombies.remove(zombie) break def draw(self, surface): surface.fill((144, 238, 144)) # 浅绿色背景 # 绘制草坪网格 for row in range(5): for col in range(9): pygame.draw.rect(surface, (124, 252, 0), (150 + col * 70, 100 + row * 100, 70, 100), 1) # 绘制植物选择区域 pygame.draw.rect(surface, BROWN, (0, 0, 150, SCREEN_HEIGHT)) pygame.draw.rect(surface, GREEN, (10, 10, 130, 60)) pygame.draw.rect(surface, YELLOW, (10, 80, 130, 60)) # 绘制植物和僵尸 for plant in self.plants: plant.draw(surface) for zombie in self.zombies: zombie.draw(surface) for pea in self.peas: pea.draw(surface) for sun in self.suns: sun.draw(surface) # 绘制阳光计数 sun_text = font.render(f"阳光: {self.sun_count}", True, BLACK) surface.blit(sun_text, (10, 150)) # 绘制植物价格 pea_text = font.render("豌豆射手: 100", True, BLACK) surface.blit(pea_text, (15, 30)) sun_text = font.render("向日葵: 50", True, BLACK) surface.blit(sun_text, (15, 100)) # 游戏结束提示 if self.game_over: game_over_text = font.render("游戏结束! 按R键重新开始", True, (255, 0, 0)) surface.blit(game_over_text, (SCREEN_WIDTH // 2 - 150, SCREEN_HEIGHT // 2)) def handle_click(self, pos): # 收集阳光 for sun in self.suns[:]: if sun.is_clicked(pos): self.sun_count += sun.value self.suns.remove(sun) return # 选择植物 if 10 <= pos[0] <= 140: if 10 <= pos[1] <= 70 and self.sun_count >= 100: self.selected_plant = "peashooter" elif 80 <= pos[1] <= 140 and self.sun_count >= 50: self.selected_plant = "sunflower" # 种植植物 if self.selected_plant and 150 <= pos[0] <= SCREEN_WIDTH and 100 <= pos[1] <= 500: col = (pos[0] - 150) // 70 row = (pos[1] - 100) // 100 if 0 <= row < 5 and 0 <= col < 9 and self.grid[row][col] is None: plant_cost = 100 if self.selected_plant == "peashooter" else 50 if self.sun_count >= plant_cost: plant = Plant(150 + col * 70, 100 + row * 100, self.selected_plant) self.plants.append(plant) self.grid[row][col] = plant self.sun_count -= plant_cost self.selected_plant = None def reset(self): self.__init__() def main(): game = Game() while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == MOUSEBUTTONDOWN: if event.button == 1: # 左键点击 game.handle_click(event.pos) elif event.type == KEYDOWN: if event.key == K_r and game.game_over: game.reset() game.update() game.draw(screen) pygame.display.flip() clock.tick(FPS) if __name__ == "__main__": main()

浙公网安备 33010602011771号