植物大战僵尸简易版小游戏

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

posted @ 2025-06-17 15:36  kk/  阅读(47)  评论(0)    收藏  举报