"你以为的安全区,下一秒就可能变成死亡陷阱!"
厌倦了传统扫雷的固定模式?来体验这款彻底颠覆扫雷玩法的动态病毒扫雷游戏!
💥 核心创新:病毒传播机制
在《扫雷:病毒蔓延》中,当你点击安全格子时,有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()