著作権に関する声明: 独創性を発揮するのは簡単ではありません。この記事では盗作と転載が禁止されており、侵害があれば調査する必要があります。
1. 開発環境と要件の分析
開発環境:Windows10 Python3.6.4
サードパーティライブラリ:Pygame1.9.6
IDE:PyCharm/Sublime Text
要件分析:
- UIインターフェース
- リソースをロードする
- 列挙関数
- レイさんのアレンジメント
- マウスイベント
- ゲームロジック
2. 機能モジュール
サードパーティライブラリのインポート:
import sys
import time
from enum import Enum
import pygame
import random
from pygame.locals import *
from mineblock import *
ゲームの初期化とグローバル変数の定義:
# 游戏屏幕的宽
SCREEN_WIDTH = BLOCK_WIDTH * SIZE
# 游戏屏幕的高
SCREEN_HEIGHT = (BLOCK_HEIGHT + 2) * SIZE
def main():
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('扫雷')
font1 = pygame.font.Font('resources/a.TTF', SIZE * 2) # 得分的字体
fwidth, fheight = font1.size('999')
red = (200, 40, 40)
リソースをロードします:
# 加载资源图片,因为资源文件大小不一,所以做了统一的缩放处理
img0 = pygame.image.load('resources/0.bmp').convert()
img0 = pygame.transform.smoothscale(img0, (SIZE, SIZE))
img1 = pygame.image.load('resources/1.bmp').convert()
img1 = pygame.transform.smoothscale(img1, (SIZE, SIZE))
img2 = pygame.image.load('resources/2.bmp').convert()
img2 = pygame.transform.smoothscale(img2, (SIZE, SIZE))
img3 = pygame.image.load('resources/3.bmp').convert()
img3 = pygame.transform.smoothscale(img3, (SIZE, SIZE))
img4 = pygame.image.load('resources/4.bmp').convert()
img4 = pygame.transform.smoothscale(img4, (SIZE, SIZE))
img5 = pygame.image.load('resources/5.bmp').convert()
img5 = pygame.transform.smoothscale(img5, (SIZE, SIZE))
img6 = pygame.image.load('resources/6.bmp').convert()
img6 = pygame.transform.smoothscale(img6, (SIZE, SIZE))
img7 = pygame.image.load('resources/7.bmp').convert()
img7 = pygame.transform.smoothscale(img7, (SIZE, SIZE))
img8 = pygame.image.load('resources/8.bmp').convert()
img8 = pygame.transform.smoothscale(img8, (SIZE, SIZE))
ブリック列挙状態:
class BlockStatus(Enum):
normal = 1 # 未点击
opened = 2 # 已点击
mine = 3 # 地雷
flag = 4 # 标记为地雷
ask = 5 # 标记为问号
bomb = 6 # 踩中地雷
hint = 7 # 被双击的周围
double = 8 # 正被鼠标左右键双击
ゲームの列挙状態:
class GameStatus(Enum):
readied = 1,
started = 2,
over = 3,
win = 4
テキスト描画:
def print_text(screen, font, x, y, text, fcolor=(255, 255, 255)):
imgText = font.render(text, True, fcolor)
screen.blit(imgText, (x, y))
レイの手配:
# 埋雷
for i in random.sample(range(BLOCK_WIDTH * BLOCK_HEIGHT), MINE_COUNT):
self._block[i // BLOCK_WIDTH][i % BLOCK_WIDTH].value = 1
マウスクリック位置:
def get_x(self):
return self._x
def set_x(self, x):
self._x = x
x = property(fget=get_x, fset=set_x)
def get_y(self):
return self._y
def set_y(self, y):
self._y = y
ダブルマウスイベント判定:
def double_mouse_button_down(self, x, y):
if self._block[y][x].around_mine_count == 0:
return True
self._block[y][x].status = BlockStatus.double
around = _get_around(x, y)
sumflag = 0 # 周围被标记的雷数量
for i, j in _get_around(x, y):
if self._block[j][i].status == BlockStatus.flag:
sumflag += 1
# 周边的雷已经全部被标记
result = True
if sumflag == self._block[y][x].around_mine_count:
for i, j in around:
if self._block[j][i].status == BlockStatus.normal:
if not self.open_mine(i, j):
result = False
else:
for i, j in around:
if self._block[j][i].status == BlockStatus.normal:
self._block[j][i].status = BlockStatus.hint
return result
def double_mouse_button_up(self, x, y):
self._block[y][x].status = BlockStatus.opened
for i, j in _get_around(x, y):
if self._block[j][i].status == BlockStatus.hint:
self._block[j][i].status = BlockStatus.normal
ゲームのメインループ:
while True:
# 填充背景色
screen.fill(bgcolor)
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
elif event.type == MOUSEBUTTONDOWN:
mouse_x, mouse_y = event.pos
x = mouse_x // SIZE
y = mouse_y // SIZE - 2
b1, b2, b3 = pygame.mouse.get_pressed()
if game_status == GameStatus.started:
# 鼠标左右键同时按下,如果已经标记了所有雷,则打开周围一圈
# 如果还未标记完所有雷,则有一个周围一圈被同时按下的效果
if b1 and b3:
mine = block.getmine(x, y)
if mine.status == BlockStatus.opened:
if not block.double_mouse_button_down(x, y):
game_status = GameStatus.over
elif event.type == MOUSEBUTTONUP:
if y < 0:
if face_pos_x <= mouse_x <= face_pos_x + face_size \
and face_pos_y <= mouse_y <= face_pos_y + face_size:
game_status = GameStatus.readied
block = MineBlock()
start_time = time.time()
elapsed_time = 0
continue
if game_status == GameStatus.readied:
game_status = GameStatus.started
start_time = time.time()
elapsed_time = 0
if game_status == GameStatus.started:
mine = block.getmine(x, y)
if b1 and not b3: # 按鼠标左键
if mine.status == BlockStatus.normal:
if not block.open_mine(x, y):
game_status = GameStatus.over
elif not b1 and b3: # 按鼠标右键
if mine.status == BlockStatus.normal:
mine.status = BlockStatus.flag
elif mine.status == BlockStatus.flag:
mine.status = BlockStatus.ask
elif mine.status == BlockStatus.ask:
mine.status = BlockStatus.normal
elif b1 and b3:
if mine.status == BlockStatus.double:
block.double_mouse_button_up(x, y)
3. ゲーム効果
4. 著者情報
著者: Xiaohong の釣りルーティン、目標: プログラミングをもっと面白くする!
アルゴリズム、爬虫類、Web サイト、ゲーム開発、データ分析、自然言語処理、AI などに焦点を当てます。ご注目をお待ちしております。一緒に成長し、コーディングしましょう!
著作権に関する注意: この記事は盗作と転載を禁止しており、侵害があれば調査する必要があります。