大家好!今天给你们带来了使用pygame写的扫雷游戏。
完整实例:
import pygame
import random
import sys
from collections import deque
# 游戏初始化
pygame.init()
# 设置窗口大小和标题
cell_size = 20
cols, rows = 20, 15
width = cols * cell_size
height = rows * cell_size + 40# 额外空间用于显示信息
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Minesweeper")
# 颜色定义
WHITE = (255, 255, 255)
GRAY = (192, 192, 192)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
# 地雷数量和字体设置
mines_count = 40
font = pygame.font.SysFont("SimHei", 24) # 支持中文的字体
defplace_mines():
mines = set()
while len(mines) < mines_count:
mine = (random.randint(0, cols - 1), random.randint(0, rows - 1))
mines.add(mine)
return mines
defcalculate_hints(mines):
hints = [[0for _ in range(cols)] for _ in range(rows)]
for mine in mines:
x, y = mine
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
nx, ny = x + dx, y + dy
if0 <= nx < cols and0 <= ny < rows and (nx, ny) notin mines:
hints[ny][nx] += 1
return hints
defdraw_grid():
for x in range(0, width, cell_size):
pygame.draw.line(screen, GRAY, (x, 40), (x, height))
for y in range(40, height, cell_size):
pygame.draw.line(screen, GRAY, (0, y), (width, y))
defdraw_cells(hints, revealed, flags, mines, show_mines):
for y in range(rows):
for x in range(cols):
rect = pygame.Rect(x * cell_size, y * cell_size + 40, cell_size, cell_size)
if (x, y) in revealed or (x, y) in show_mines:
color = RED if (x, y) in mines else WHITE
pygame.draw.rect(screen, color, rect)
if hints[y][x] > 0and (x, y) notin mines: # Draw hints
# 居中显示数字1和2
hint_text = font.render(str(hints[y][x]), True, BLACK)
text_rect = hint_text.get_rect(center=rect.center)
screen.blit(hint_text, text_rect.topleft)
else:
pygame.draw.rect(screen, GRAY, rect)
pygame.draw.rect(screen, BLACK, rect, 1)
defdraw_info_panel(revealed):
text = font.render(f"得分: {len(revealed)}", True, GREEN)
screen.blit(text, (5, 10))
defreveal_cells(x, y, hints, revealed, flags, mines):
if (x, y) in mines or (x, y) in revealed:
return
queue = deque([(x, y)])
while queue:
x, y = queue.popleft()
if (x, y) notin revealed:
revealed.add((x, y))
if hints[y][x] == 0:
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
nx, ny = x + dx, y + dy
if0 <= nx < cols and0 <= ny < rows:
queue.append((nx, ny))
defrestart_game():
new_mines = place_mines()
new_hints = calculate_hints(new_mines)
return new_mines, new_hints, set(), set(), set()
defcheck_win_condition(mines, revealed):
if len(revealed) + len(mines) == cols * rows:
returnTrue
returnFalse
defmain():
mines, hints, revealed, flags, show_mines = restart_game()
running = True
game_over = False
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
x, y = event.pos
col, row = x // cell_size, (y - 40) // cell_size
if row >= 0andnot game_over:
if event.button == 1: # Left click
if (col, row) notin flags:
reveal_cells(col, row, hints, revealed, flags, mines)
if (col, row) in mines:
print("游戏结束! 右键点击重新开始。")
show_mines = mines.copy() # 显示所有地雷
game_over = True
elif event.button == 3: # Right click
if (col, row) notin revealed and (col, row) notin show_mines:
if (col, row) in flags:
flags.remove((col, row))
else:
flags.add((col, row))
elif row >= 0and game_over and event.button == 3: # 重置游戏
mines, hints, revealed, flags, show_mines = restart_game()
game_over = False
screen.fill(BLACK)
draw_grid()
draw_cells(hints, revealed, flags, mines, show_mines)
draw_info_panel(revealed)
pygame.display.flip()
pygame.quit()
sys.exit()
if __name__ == "__main__":
main()