《扫雷:病毒蔓延》- 颠覆传统的动态扫雷游戏

"你以为的安全区,下一秒就可能变成死亡陷阱!"

厌倦了传统扫雷的固定模式?来体验这款彻底颠覆扫雷玩法的动态病毒扫雷游戏!

💥 核心创新:病毒传播机制

在《扫雷:病毒蔓延》中,当你点击安全格子时,有20%的概率将其周围8格中未打开的格子"感染"成新的地雷!

游戏特色亮点:

  • 🔄 动态地图:地图不再是静态的,每一步都可能改变整个局势
  • ⚠️ 安全区危机:刚刚确认的安全区域,下一秒可能就布满了新的地雷
  • 🧠 极致心理博弈:你是在与一个会"生长"的智能雷区作斗争
  • 💣 实时反馈:病毒雷出现时有炫酷的飘屏提示和特殊视觉效果

🎯 游戏玩法

基础操作:

  • 左键点击揭开格子
  • 右键标记/取消标记地雷
  • 空格键重新开始游戏
  • ESC键退出游戏

策略革新:

传统的扫雷策略在这里可能失效!你需要随时准备应对突如其来的病毒传播,在开拓安全区的同时,警惕周边潜在的变异风险。

🌟 玩家评价

"刚刚还是安全的区域,转眼间就布满了地雷...这个游戏让我重新学会了什么叫做'步步惊心'!" --- 资深玩家
"传统扫雷玩的是记忆和逻辑,这个版本玩的是心跳和勇气!" --- 游戏评测

🚀 立即体验

准备好迎接这场心理与运气的终极考验了吗?《扫雷:病毒蔓延》将带给你前所未有的紧张刺激体验!

游戏格言:在这里,唯一的确定性就是不确定性!


欢迎在评论区分享你的游戏心得和高分记录!

python 复制代码
import pygame
import random
import sys
import time

# 初始化pygame
pygame.init()

# 游戏常量
GRID_SIZE = 30  # 每个格子的大小
GRID_WIDTH = 20  # 横向格子数
GRID_HEIGHT = 16  # 纵向格子数
MARGIN = 50  # 边距
WINDOW_WIDTH = GRID_WIDTH * GRID_SIZE + 2 * MARGIN
WINDOW_HEIGHT = GRID_HEIGHT * GRID_SIZE + 2 * MARGIN + 100  # 额外空间用于显示信息
VIRUS_PROBABILITY = 0.2  # 病毒传播概率

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (200, 200, 200)
DARK_GRAY = (120, 120, 120)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
PURPLE = (255, 0, 255)
CYAN = (0, 255, 255)
ORANGE = (255, 165, 0)
BACKGROUND = (40, 40, 60)
GRID_COLOR = (80, 80, 100)
HIGHLIGHT = (100, 100, 140, 150)  # 添加透明度

# 数字颜色
NUMBER_COLORS = {
    1: BLUE,
    2: GREEN,
    3: RED,
    4: PURPLE,
    5: ORANGE,
    6: CYAN,
    7: BLACK,
    8: DARK_GRAY
}

# 创建游戏窗口
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("扫雷:病毒蔓延")

# 加载字体
try:
    font = pygame.font.SysFont('simhei', 24)
    large_font = pygame.font.SysFont('simhei', 36)
except:
    font = pygame.font.SysFont(None, 24)
    large_font = pygame.font.SysFont(None, 36)


class Cell:
    def __init__(self, row, col):
        self.row = row
        self.col = col
        self.is_mine = False
        self.is_revealed = False
        self.is_flagged = False
        self.is_virus_mine = False  # 是否是病毒生成的地雷
        self.neighbor_mines = 0
        self.x = MARGIN + col * GRID_SIZE
        self.y = MARGIN + row * GRID_SIZE
        self.highlight = False
        self.reveal_animation = 0  # 用于揭开动画

    def draw(self):
        rect = pygame.Rect(self.x, self.y, GRID_SIZE, GRID_SIZE)

        # 先绘制格子的基本状态
        if not self.is_revealed:
            pygame.draw.rect(screen, GRID_COLOR, rect)
            pygame.draw.rect(screen, DARK_GRAY, rect, 1)
            if self.is_flagged:
                # 绘制旗帜
                pygame.draw.polygon(screen, RED, [
                    (self.x + GRID_SIZE // 2, self.y + 5),
                    (self.x + GRID_SIZE // 2, self.y + GRID_SIZE - 5),
                    (self.x + GRID_SIZE - 5, self.y + GRID_SIZE // 2)
                ])
        else:
            # 如果有揭开动画,计算动画效果
            if self.reveal_animation > 0:
                progress = self.reveal_animation / 10.0
                animated_size = int(GRID_SIZE * progress)
                offset = (GRID_SIZE - animated_size) // 2
                animated_rect = pygame.Rect(self.x + offset, self.y + offset, animated_size, animated_size)
                pygame.draw.rect(screen, GRID_COLOR, rect)
                pygame.draw.rect(screen, WHITE, animated_rect)
                pygame.draw.rect(screen, DARK_GRAY, animated_rect, 1)
            else:
                pygame.draw.rect(screen, WHITE, rect)
                pygame.draw.rect(screen, DARK_GRAY, rect, 1)

            if self.is_mine:
                # 绘制地雷
                pygame.draw.circle(screen, BLACK,
                                   (self.x + GRID_SIZE // 2, self.y + GRID_SIZE // 2),
                                   GRID_SIZE // 3)
                # 如果是病毒地雷,绘制特殊效果
                if self.is_virus_mine:
                    pygame.draw.circle(screen, GREEN,
                                       (self.x + GRID_SIZE // 2, self.y + GRID_SIZE // 2),
                                       GRID_SIZE // 3, 2)
                    # 绘制病毒效果
                    for i in range(8):
                        angle = i * 45
                        end_x = self.x + GRID_SIZE // 2 + int(
                            GRID_SIZE // 2 * pygame.math.Vector2(1, 0).rotate(angle).x)
                        end_y = self.y + GRID_SIZE // 2 + int(
                            GRID_SIZE // 2 * pygame.math.Vector2(1, 0).rotate(angle).y)
                        pygame.draw.line(screen, GREEN,
                                         (self.x + GRID_SIZE // 2, self.y + GRID_SIZE // 2),
                                         (end_x, end_y), 2)
            elif self.neighbor_mines > 0:
                # 绘制数字
                text = font.render(str(self.neighbor_mines), True, NUMBER_COLORS.get(self.neighbor_mines, BLACK))
                text_rect = text.get_rect(center=(self.x + GRID_SIZE // 2, self.y + GRID_SIZE // 2))
                screen.blit(text, text_rect)

        # 最后绘制高亮效果(使用半透明效果,不覆盖内容)
        if self.highlight:
            # 创建半透明表面
            highlight_surface = pygame.Surface((GRID_SIZE, GRID_SIZE), pygame.SRCALPHA)
            pygame.draw.rect(highlight_surface, HIGHLIGHT, (0, 0, GRID_SIZE, GRID_SIZE))
            screen.blit(highlight_surface, (self.x, self.y))


class FloatingText:
    def __init__(self, text, x, y, color=GREEN):
        self.text = text
        self.x = x
        self.y = y
        self.color = color
        self.alpha = 255
        self.speed = 1
        self.creation_time = time.time()

    def update(self):
        self.y -= self.speed
        self.alpha -= 3
        return self.alpha > 0

    def draw(self):
        text_surface = large_font.render(self.text, True, self.color)
        text_surface.set_alpha(self.alpha)
        screen.blit(text_surface, (self.x, self.y))


class Game:
    def __init__(self):
        self.reset()

    def reset(self):
        self.board = [[Cell(row, col) for col in range(GRID_WIDTH)] for row in range(GRID_HEIGHT)]
        self.game_over = False
        self.game_won = False
        self.first_click = True
        self.mines_count = 40
        self.flags_count = 0
        self.floating_texts = []
        self.start_time = time.time()
        self.elapsed_time = 0
        self.pending_virus_spread = []  # 存储待处理的病毒传播
        self.animation_timer = 0  # 动画计时器

    def place_mines(self, first_row, first_col):
        # 确保第一次点击不是地雷
        safe_cells = [(first_row, first_col)]
        for dr in [-1, 0, 1]:
            for dc in [-1, 0, 1]:
                r, c = first_row + dr, first_col + dc
                if 0 <= r < GRID_HEIGHT and 0 <= c < GRID_WIDTH:
                    safe_cells.append((r, c))

        # 随机放置地雷
        mines_placed = 0
        while mines_placed < self.mines_count:
            row = random.randint(0, GRID_HEIGHT - 1)
            col = random.randint(0, GRID_WIDTH - 1)
            if (row, col) not in safe_cells and not self.board[row][col].is_mine:
                self.board[row][col].is_mine = True
                mines_placed += 1

        # 计算每个格子的周围地雷数
        for row in range(GRID_HEIGHT):
            for col in range(GRID_WIDTH):
                self.calculate_neighbor_mines(row, col)

    def calculate_neighbor_mines(self, row, col):
        count = 0
        for dr in [-1, 0, 1]:
            for dc in [-1, 0, 1]:
                if dr == 0 and dc == 0:
                    continue
                r, c = row + dr, col + dc
                if 0 <= r < GRID_HEIGHT and 0 <= c < GRID_WIDTH and self.board[r][c].is_mine:
                    count += 1
        self.board[row][col].neighbor_mines = count

    def reveal(self, row, col):
        if not (0 <= row < GRID_HEIGHT and 0 <= col < GRID_WIDTH):
            return

        cell = self.board[row][col]

        if cell.is_revealed or cell.is_flagged:
            return

        if self.first_click:
            self.first_click = False
            self.place_mines(row, col)
            self.start_time = time.time()

        cell.is_revealed = True
        cell.reveal_animation = 10  # 开始揭开动画

        if cell.is_mine:
            self.game_over = True
            return

        # 如果是空白格子,递归揭开周围的格子
        if cell.neighbor_mines == 0:
            for dr in [-1, 0, 1]:
                for dc in [-1, 0, 1]:
                    if dr != 0 or dc != 0:  # 跳过自身
                        self.reveal(row + dr, col + dc)

        # 在安全格子上标记可能的病毒传播
        if not cell.is_mine and random.random() < VIRUS_PROBABILITY:
            self.pending_virus_spread.append((row, col))

        # 检查是否获胜
        self.check_win()

    def process_virus_spread(self):
        # 处理所有待处理的病毒传播
        if self.pending_virus_spread:
            row, col = self.pending_virus_spread.pop(0)
            self.virus_spread(row, col)
            return True
        return False

    def virus_spread(self, row, col):
        # 找到周围未揭开且不是地雷的格子
        candidates = []
        for dr in [-1, 0, 1]:
            for dc in [-1, 0, 1]:
                if dr == 0 and dc == 0:
                    continue
                r, c = row + dr, col + dc
                if 0 <= r < GRID_HEIGHT and 0 <= c < GRID_WIDTH:
                    cell = self.board[r][c]
                    if not cell.is_revealed and not cell.is_mine and not cell.is_flagged:
                        candidates.append((r, c))

        # 如果找到候选格子,随机选择一个变成地雷
        if candidates:
            r, c = random.choice(candidates)
            self.board[r][c].is_mine = True
            self.board[r][c].is_virus_mine = True
            self.mines_count += 1

            # 更新周围格子的数字
            for dr in [-1, 0, 1]:
                for dc in [-1, 0, 1]:
                    nr, nc = r + dr, c + dc
                    if 0 <= nr < GRID_HEIGHT and 0 <= nc < GRID_WIDTH:
                        self.calculate_neighbor_mines(nr, nc)

            # 添加飘屏提示
            text = "病毒雷出现!安全区变雷区!"
            text_width = large_font.size(text)[0]
            x = (WINDOW_WIDTH - text_width) // 2
            y = WINDOW_HEIGHT - 100
            self.floating_texts.append(FloatingText(text, x, y, GREEN))

    def toggle_flag(self, row, col):
        if not (0 <= row < GRID_HEIGHT and 0 <= col < GRID_WIDTH):
            return

        cell = self.board[row][col]
        if not cell.is_revealed:
            if cell.is_flagged:
                cell.is_flagged = False
                self.flags_count -= 1
            else:
                cell.is_flagged = True
                self.flags_count += 1

    def check_win(self):
        for row in range(GRID_HEIGHT):
            for col in range(GRID_WIDTH):
                cell = self.board[row][col]
                if not cell.is_mine and not cell.is_revealed:
                    return
        self.game_won = True

    def highlight_cell(self, row, col):
        # 清除所有高亮
        for r in range(GRID_HEIGHT):
            for c in range(GRID_WIDTH):
                self.board[r][c].highlight = False

        # 高亮当前单元格
        if 0 <= row < GRID_HEIGHT and 0 <= col < GRID_WIDTH:
            self.board[row][col].highlight = True

    def update_animations(self):
        # 更新所有格子的动画
        animation_active = False
        for row in range(GRID_HEIGHT):
            for col in range(GRID_WIDTH):
                cell = self.board[row][col]
                if cell.reveal_animation > 0:
                    cell.reveal_animation -= 1
                    animation_active = True
        return animation_active

    def draw(self):
        screen.fill(BACKGROUND)

        # 绘制格子
        for row in range(GRID_HEIGHT):
            for col in range(GRID_WIDTH):
                self.board[row][col].draw()

        # 绘制飘屏文字
        for text in self.floating_texts[:]:
            if not text.update():
                self.floating_texts.remove(text)
            text.draw()

        # 绘制游戏信息
        info_y = MARGIN + GRID_HEIGHT * GRID_SIZE + 10

        # 地雷计数
        mines_text = font.render(f"地雷: {self.mines_count - self.flags_count}", True, WHITE)
        screen.blit(mines_text, (MARGIN, info_y))

        # 时间
        if not self.game_over and not self.game_won:
            self.elapsed_time = int(time.time() - self.start_time)
        time_text = font.render(f"时间: {self.elapsed_time}秒", True, WHITE)
        screen.blit(time_text, (WINDOW_WIDTH - MARGIN - 100, info_y))

        # 游戏状态
        if self.game_over:
            status_text = large_font.render("游戏结束!按空格重新开始", True, RED)
            screen.blit(status_text, (WINDOW_WIDTH // 2 - status_text.get_width() // 2, info_y + 40))
        elif self.game_won:
            status_text = large_font.render("恭喜获胜!按空格重新开始", True, GREEN)
            screen.blit(status_text, (WINDOW_WIDTH // 2 - status_text.get_width() // 2, info_y + 40))
        else:
            status_text = font.render("左键点击揭开格子,右键标记地雷", True, WHITE)
            screen.blit(status_text, (WINDOW_WIDTH // 2 - status_text.get_width() // 2, info_y + 40))

        # 绘制操作提示
        controls_text = font.render("空格: 重新开始  ESC: 退出游戏", True, YELLOW)
        screen.blit(controls_text, (WINDOW_WIDTH // 2 - controls_text.get_width() // 2, WINDOW_HEIGHT - 30))

    def reveal_all_mines(self):
        # 游戏结束时显示所有地雷
        for row in range(GRID_HEIGHT):
            for col in range(GRID_WIDTH):
                if self.board[row][col].is_mine:
                    self.board[row][col].is_revealed = True


def main():
    game = Game()
    clock = pygame.time.Clock()

    while True:
        # 处理事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    game.reset()
                elif event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()

            if event.type == pygame.MOUSEMOTION:
                pos = pygame.mouse.get_pos()
                col = (pos[0] - MARGIN) // GRID_SIZE
                row = (pos[1] - MARGIN) // GRID_SIZE
                game.highlight_cell(row, col)

            if event.type == pygame.MOUSEBUTTONDOWN and not game.game_over and not game.game_won:
                pos = pygame.mouse.get_pos()
                col = (pos[0] - MARGIN) // GRID_SIZE
                row = (pos[1] - MARGIN) // GRID_SIZE

                if 0 <= row < GRID_HEIGHT and 0 <= col < GRID_WIDTH:
                    if event.button == 1:  # 左键
                        game.reveal(row, col)
                        if game.game_over:
                            game.reveal_all_mines()
                    elif event.button == 3:  # 右键
                        game.toggle_flag(row, col)

        # 更新动画
        animation_active = game.update_animations()

        # 如果没有动画在进行,处理病毒传播
        if not animation_active and not game.game_over and not game.game_won:
            game.process_virus_spread()

        # 绘制游戏
        game.draw()
        pygame.display.flip()
        clock.tick(60)


if __name__ == "__main__":
    main()
相关推荐
Minecraft红客21 小时前
火柴人遗产战争五
c++·游戏·青少年编程·电脑·娱乐
StarPrayers.21 小时前
用 PyTorch 搭建 CIFAR10 线性分类器:从数据加载到模型推理全流程解析
人工智能·pytorch·python
程序员杰哥21 小时前
UI自动化测试实战:从入门到精通
自动化测试·软件测试·python·selenium·测试工具·ui·职场和发展
SunnyRivers1 天前
通俗易懂理解python yield
python
mortimer1 天前
Python 进阶:彻底理解类属性、类方法与静态方法
后端·python
wanhengidc1 天前
操作简单稳定选巨 椰 云手机
运维·服务器·游戏·智能手机·云计算
小叮当⇔1 天前
PYcharm——获取天气
ide·python·pycharm
wanhengidc1 天前
云手机公认的优势有什么
运维·服务器·游戏·智能手机·玩游戏
霍志杰1 天前
记一次csv和xlsx之间的转换处理
python
测试19981 天前
Jmeter是如何实现接口关联的?
自动化测试·软件测试·python·测试工具·jmeter·职场和发展·接口测试