先看一下运行效果
该小游戏是基于Pygame的,定义了游戏的基本数据
# 游戏数据
grid_size = 40 # 方格大小
num_cols = WIDTH // grid_size
num_rows = HEIGHT // grid_size
num_bombs = 10 # 炸弹数量
grid = []
grid是一个二维数组,定义了每个格子的情况。数组的每个元素是一个GridSquare对象。GridSquare.draw()方法,绘制了不同状态的方块样式。
整体代码结构比较简单,源码如下:
import pygame
import random
# 游戏设置
WIDTH = 240
HEIGHT = 400
FPS = 60
# 颜色定义
BLACK = (0, 0, 0)
WHITE = (220, 220, 220)
GRAY = (200, 200, 200)
BLUE = (0, 0, 255)
ORANGE = (255, 97, 0)
RED = (255, 0, 0)
# 初始化Pygame
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("扫雷游戏")
clock = pygame.time.Clock()
pygame.init()
pygame.mixer.init()
pygame.mixer.music.load('res/background.wav')
pygame.mixer.music.set_volume(0.2)
pygame.mixer.music.play(-1)
clickSound = pygame.mixer.Sound('res/click.mp3')
clickSound.set_volume(2)
bombSound = pygame.mixer.Sound('res/bomb.mp3')
bombSound.set_volume(2)
# 游戏数据
grid_size = 40 # 方格大小
num_cols = WIDTH // grid_size
num_rows = HEIGHT // grid_size
num_bombs = 10 # 炸弹数量
grid = []
bombImg = pygame.image.load('res/bang.png')
bombImg = pygame.transform.smoothscale(bombImg, (25, 25))
flagImg = pygame.image.load('res/flag.png')
flagImg = pygame.transform.smoothscale(flagImg, (25, 25))
GAME_OVER = 0 # 为 GAME_OVER 赋予一个默认值
# 创建方格对象
class GridSquare:
def __init__(self, x, y):
self.x = x
self.y = y
self.bomb = False
self.revealed = False
self.neighbors = []
self.num_neighbor_bombs = 0
self.flag = False
def draw(self):
rect = pygame.Rect(self.x * grid_size, self.y * grid_size, grid_size, grid_size)
if self.revealed:
pygame.draw.rect(screen, WHITE, rect)
if self.bomb:
# 触发爆炸
rect.x += 7
rect.y += 7
screen.blit(bombImg, rect)
else:
color = BLACK
font = pygame.font.Font(None, 22)
if self.num_neighbor_bombs == 0:
color = BLACK
elif self.num_neighbor_bombs == 1:
color = BLUE
elif self.num_neighbor_bombs == 2:
color = ORANGE
elif self.num_neighbor_bombs >= 3:
color = RED
text = font.render(str(self.num_neighbor_bombs), True, color)
text_rect = text.get_rect(center=rect.center)
screen.blit(text, text_rect)
elif self.flag:
pygame.draw.rect(screen, GRAY, rect)
rect.x += 7
rect.y += 7
screen.blit(flagImg, rect)
else:
pygame.draw.rect(screen, GRAY, rect)
# 初始化方块网格
def initialize_grid():
for row in range(num_rows):
grid.append([])
for col in range(num_cols):
square = GridSquare(col, row)
square.draw()
grid[row].append(square)
# 随机放置炸弹
def place_bombs():
bomb_count = 0
while bomb_count < num_bombs:
row = random.randint(0, num_rows - 1)
col = random.randint(0, num_cols - 1)
square = grid[row][col]
if not square.bomb:
square.bomb = True
bomb_count += 1
# 计算每个方格周围的炸弹数量
def calculate_neighbor_bombs():
for row in range(num_rows):
for col in range(num_cols):
square = grid[row][col]
if not square.bomb:
for i in range(-1, 2):
for j in range(-1, 2):
if i == 0 and j == 0:
continue
if row + i >= 0 and row + i < num_rows and col + j >= 0 and col + j < num_cols:
neighbor = grid[row + i][col + j]
square.neighbors.append(neighbor)
if neighbor.bomb:
square.num_neighbor_bombs += 1
# 揭示方块和相邻的空方块
def reveal_square(square):
square.revealed = True
if square.num_neighbor_bombs == 0:
for neighbor in square.neighbors:
if not neighbor.revealed:
reveal_square(neighbor)
# 游戏循环
initialize_grid()
place_bombs()
calculate_neighbor_bombs()
running = True
while running:
clock.tick(FPS)
# 处理事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONUP and event.button == 1: # 左键点击
pos = pygame.mouse.get_pos()
col = pos[0] // grid_size
row = pos[1] // grid_size
clickSound.play()
square = grid[row][col]
if square.bomb:
GAME_OVER = 1
bombSound.play()
if not square.revealed:
reveal_square(square)
elif event.type == pygame.MOUSEBUTTONUP and event.button == 3: # 右键点击
pos = pygame.mouse.get_pos()
col = pos[0] // grid_size
row = pos[1] // grid_size
square = grid[row][col]
if not square.revealed:
square.flag = not square.flag
# 更新
screen.fill(BLACK)
for row in range(num_rows):
for col in range(num_cols):
square = grid[row][col]
if GAME_OVER > 0:
square.revealed = True
square.draw()
# 画面翻转
pygame.display.flip()
# 退出游戏
pygame.quit()
源码已上传到gitee: bomb: 扫雷游戏
如有想法,欢迎提建议。