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()

 

posted on 2025-06-23 12:07  1235yyq  阅读(13)  评论(0)    收藏  举报