植物大战僵尸

import pygame
import random
import sys

初始化pygame

pygame.init()

游戏窗口设置

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("植物大战僵尸简化版")

颜色定义

GREEN = (0, 255, 0)
BROWN = (139, 69, 19)
BLUE = (0, 0, 255)
RED = (255, 0, 0)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

游戏参数

FPS = 60
clock = pygame.time.Clock()

草坪网格设置

GRID_SIZE = 80
GRID_WIDTH = 9
GRID_HEIGHT = 5
LAWN_LEFT = 100
LAWN_TOP = 100

class Plant:
def init(self, row, col):
self.row = row
self.col = col
self.health = 100
self.attack_cooldown = 0
self.x = LAWN_LEFT + col * GRID_SIZE
self.y = LAWN_TOP + row * GRID_SIZE

def update(self):
    if self.attack_cooldown > 0:
        self.attack_cooldown -= 1
        
def draw(self, surface):
    pygame.draw.circle(surface, GREEN, (self.x + GRID_SIZE//2, self.y + GRID_SIZE//2), 30)
    
def can_attack(self):
    return self.attack_cooldown == 0

class Peashooter(Plant):
def init(self, row, col):
super().init(row, col)
self.attack_cooldown_max = 60 # 1秒攻击一次

def attack(self):
    if self.can_attack():
        self.attack_cooldown = self.attack_cooldown_max
        return Projectile(self.row, self.col)
    return None
    
def draw(self, surface):
    pygame.draw.circle(surface, GREEN, (self.x + GRID_SIZE//2, self.y + GRID_SIZE//2), 30)
    # 绘制豌豆射手头部
    pygame.draw.circle(surface, (100, 200, 100), (self.x + GRID_SIZE//2 + 15, self.y + GRID_SIZE//2 - 10), 15)

class Zombie:
def init(self, row):
self.row = row
self.col = GRID_WIDTH
self.x = LAWN_LEFT + self.col * GRID_SIZE
self.y = LAWN_TOP + row * GRID_SIZE
self.health = 100
self.speed = 0.5

def update(self):
    self.x -= self.speed
    self.col = int((self.x - LAWN_LEFT) / GRID_SIZE)
    
def draw(self, surface):
    pygame.draw.rect(surface, BROWN, (self.x, self.y, GRID_SIZE, GRID_SIZE))
    # 绘制僵尸头部
    pygame.draw.circle(surface, (200, 200, 100), (self.x + GRID_SIZE//2, self.y + 20), 20)
    
def is_at_house(self):
    return self.col < 0

class Projectile:
def init(self, row, col):
self.row = row
self.col = col
self.x = LAWN_LEFT + col * GRID_SIZE + GRID_SIZE
self.y = LAWN_TOP + row * GRID_SIZE + GRID_SIZE//2
self.speed = 5
self.damage = 20

def update(self):
    self.x += self.speed
    self.col = int((self.x - LAWN_LEFT) / GRID_SIZE)
    
def draw(self, surface):
    pygame.draw.circle(surface, GREEN, (int(self.x), int(self.y)), 10)
    
def is_off_screen(self):
    return self.col >= GRID_WIDTH

class Game:
def init(self):
self.plants = []
self.zombies = []
self.projectiles = []
self.sun = 50
self.zombie_spawn_timer = 0
self.sun_spawn_timer = 0
self.game_over = False

def update(self):
    if self.game_over:
        return
        
    # 更新植物
    for plant in self.plants:
        plant.update()
        if isinstance(plant, Peashooter) and plant.can_attack():
            projectile = plant.attack()
            if projectile:
                self.projectiles.append(projectile)
    
    # 更新僵尸
    for zombie in self.zombies[:]:
        zombie.update()
        if zombie.is_at_house():
            self.game_over = True
            break
            
        # 检测僵尸是否碰到植物
        for plant in self.plants[:]:
            if zombie.row == plant.row and zombie.col == plant.col:
                plant.health -= 1
                if plant.health <= 0:
                    self.plants.remove(plant)
                break
    
    # 更新投射物
    for projectile in self.projectiles[:]:
        projectile.update()
        if projectile.is_off_screen():
            self.projectiles.remove(projectile)
            continue
            
        # 检测投射物是否击中僵尸
        for zombie in self.zombies[:]:
            if projectile.row == zombie.row and projectile.col == zombie.col:
                zombie.health -= projectile.damage
                if zombie.health <= 0:
                    self.zombies.remove(zombie)
                    self.sun += 25  # 击杀僵尸获得阳光
                self.projectiles.remove(projectile)
                break
    
    # 生成僵尸
    self.zombie_spawn_timer += 1
    if self.zombie_spawn_timer >= 300:  # 每5秒生成一个僵尸
        self.zombie_spawn_timer = 0
        self.spawn_zombie()
        
    # 生成阳光
    self.sun_spawn_timer += 1
    if self.sun_spawn_timer >= 200:  # 每约3秒生成阳光
        self.sun_spawn_timer = 0
        self.sun += 25
    
def spawn_zombie(self):
    row = random.randint(0, GRID_HEIGHT-1)
    self.zombies.append(Zombie(row))
    
def add_plant(self, row, col):
    # 检查是否已经有植物在这个位置
    for plant in self.plants:
        if plant.row == row and plant.col == col:
            return False
            
    if self.sun >= 100:  # 豌豆射手花费100阳光
        self.plants.append(Peashooter(row, col))
        self.sun -= 100
        return True
    return False
    
def draw(self, surface):
    # 绘制背景
    surface.fill((200, 230, 200))
    
    # 绘制草坪网格
    for row in range(GRID_HEIGHT):
        for col in range(GRID_WIDTH):
            rect = pygame.Rect(LAWN_LEFT + col * GRID_SIZE, 
                              LAWN_TOP + row * GRID_SIZE, 
                              GRID_SIZE, GRID_SIZE)
            pygame.draw.rect(surface, (100, 200, 100), rect, 1)
    
    # 绘制植物
    for plant in self.plants:
        plant.draw(surface)
        
    # 绘制僵尸
    for zombie in self.zombies:
        zombie.draw(surface)
        
    # 绘制投射物
    for projectile in self.projectiles:
        projectile.draw(surface)
        
    # 绘制阳光数量
    font = pygame.font.SysFont(None, 36)
    sun_text = font.render(f"阳光: {self.sun}", True, BLACK)
    surface.blit(sun_text, (20, 20))
    
    # 游戏结束提示
    if self.game_over:
        font = pygame.font.SysFont(None, 72)
        game_over_text = font.render("游戏结束!", True, RED)
        surface.blit(game_over_text, (SCREEN_WIDTH//2 - 150, SCREEN_HEIGHT//2 - 36))

def main():
game = Game()

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.game_over:
            if event.button == 1:  # 左键点击
                mouse_x, mouse_y = pygame.mouse.get_pos()
                
                # 检查是否点击在草坪上
                if (LAWN_LEFT <= mouse_x < LAWN_LEFT + GRID_WIDTH * GRID_SIZE and
                    LAWN_TOP <= mouse_y < LAWN_TOP + GRID_HEIGHT * GRID_SIZE):
                    col = (mouse_x - LAWN_LEFT) // GRID_SIZE
                    row = (mouse_y - LAWN_TOP) // GRID_SIZE
                    game.add_plant(row, col)
    
    game.update()
    game.draw(screen)
    pygame.display.flip()
    clock.tick(FPS)

pygame.quit()
sys.exit()

if name == "main":
main()

posted @ 2025-06-23 14:36  cchb  阅读(45)  评论(0)    收藏  举报