from random import randint import pygame from game_over import Over from pygame.mixer import * from button import Button import sys from time import sleep class Map: """管理游戏中出现的雷和数字""" def __init__(self, setting, covers, screen): #游戏参数,游戏的覆盖物,游戏界面 pygame.mixer.init() self.setting = setting self.bg_color = self.setting.background_color self.screen = screen self.covers = covers #踩雷的背景音乐 self.boot=pygame.mixer.Sound('data/boot.wav') self.boot.set_volume(0.2) #开始时全部初始为0,表示当前方块啥都没有 self.maps = [[0 for _ in range(20)] for _ in range(20)] #状态转移数组,所有(x+moves[i][0], y+moves[i][1])表示包围坐标为(x, y)方块的另外8块方块, #用于随机产生地雷后更新它周围方块上的数字 self.moves = [[-1, -1], [0, -1], [1, -1], [-1, 0], [1, 0], [-1, 1], [0, 1], [1, 1]] #存储当前需要被显示出来数字方块 self.now_show = [] #点击到地雷后结束游戏 self.over = Over(self.screen) #随机生成游戏地图 self._born_map() def _born_map(self): """随机生成地图""" for i in range(40): x = randint(0, 19) y = randint(0, 19) while self.maps[x][y] != 0: x = randint(0, 19) y = randint(0, 19) self.maps[x][y] = 'X' self._connect_(x, y) #更新地雷周围的数字 def _connect_(self, x, y): """更新地雷周围数字的函数""" for cur in self.moves: i = x + cur[0] j = y + cur[1] if i >= 0 and i < 20 and j >= 0 and j < 20 and self.maps[i][j] != 'X': self.maps[i][j] += 1 def add(self, x, y): #传入当前鼠标点击的位置,判断合法性,合法则将对应的方块左边传入要展示的列表中 i = x // 25 j = y // 25 #鼠标位置合法性判断 if i < 0 and i >= 20 and j < 0 and j >= 20: return #避免重复添加 if [i,j] not in self.now_show: self.now_show.append([i, j]) if self.maps[i][j] == 0: self._add_connect_(i, j) #如果当前点击到了地雷,将地雷标记为红色方块,并展示出来,暂停游戏3秒,自动退出游戏 if self.maps[i][j] == 'X': pygame.draw.rect(self.screen, (255, 0, 0), ((i * 25, j * 25), (25, 25))) #self.boot.play() self.over.show() return True #返回已经触发结束游戏的事件了 return False #没有触发结束游戏事件 # 宽度搜索将(x,y)周围相连的空白方块也展示出来 def _add_connect_(self, x, y): que = [] que.append([x, y]) while que: cur = que[-1] del (que[-1]) for k in range(8): i, j = cur[0] + self.moves[k][0], cur[1] + self.moves[k][1] if i >= 0 and i < 20 and j >= 0 and j < 20 and self.maps[i][j] != 'X' and [i, j] not in self.now_show: self.now_show.append([i, j]) self.covers.delete(i * 25, j * 25) if self.maps[i][j]==0: que.append([i, j]) def show(self): """将生成的地图展现到屏幕上""" for cur in self.now_show: i = cur[0] j = cur[1] if self.maps[i][j] == 0: continue else: self.msg = str(self.maps[i][j]) self.font = pygame.font.SysFont(None, 45) self.font_image = self.font.render(self.msg, True, (60, 0, 0), None) self.image_ract = self.font_image.get_rect() self.image_ract.x = i * 25 self.image_ract.y = j * 25 self.image_ract.width = 24 self.image_ract.height = 24 self.screen.blit(self.font_image, self.image_ract)