pygame小游戏开发 - 扫雷

版权声明:原创不易,本文禁止抄袭、转载,侵权必究!

一、开发环境&需求分析

开发环境 :Windows10 Python3.6.4
第三方库 :Pygame1.9.6
IDE :PyCharm/Sublime Text

需求分析:

  • UI界面
  • 加载资源
  • 枚举功能
  • 雷的布置
  • 鼠标事件
  • 游戏逻辑

二、功能模块

第三方库的导入:

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)



三、游戏效果

在这里插入图片描述

四、作者Info

Author:小鸿的摸鱼日常,Goal:让编程更有趣!

专注于算法、爬虫,网站,游戏开发,数据分析、自然语言处理,AI等,期待你的关注,让我们一起成长、一起Coding!

版权说明:本文禁止抄袭、转载 ,侵权必究!

猜你喜欢

转载自blog.csdn.net/qq_44000141/article/details/128024111