### pygame鼠闯迷宫闯关小游戏

```"""鼠闯迷宫闯关小游戏.一只老鼠在一个巨大的迷宫中,它要出去才不致于被饿死,用鼠标牵引它移动即可。

__author__ = "李兴球"
__date__ = "2018年12月左右"

import os,math,sys
import pygame
from pygame.locals import *

class Maze(pygame.sprite.Sprite):
def __init__(self,image,scale,screen):
pygame.sprite.Sprite.__init__(self)
self.screen = screen
self.image = pygame.image.load(image).convert_alpha()
self.__width = self.image.get_width()                    # 获取宽度
self.__height = self.image.get_height()                  # 获取高度
newsize = (scale * self.__width,scale * self.__height)   # 新的宽高
self.image = pygame.transform.scale(self.image,newsize)  # 缩放大小
self.image = self.image.convert_alpha()
self.mask = pygame.mask.from_surface(self.image)         # 设置掩膜
self.rect = self.image.get_rect()
"为了把它放到屏幕中间，这是增加的代码"
self.rect.center = (screen.get_width()//2,screen.get_height()//2)

def update(self,dx,dy):
"""迷宫朝相反的dx和dy移动"""
self.rect.move_ip(dx*0.05,dy*0.05)

def draw(self):
self.screen.blit(self.image,self.rect)

class Mouse(pygame.sprite.Sprite):
def __init__(self,image,position,screen,maze=None):
pygame.sprite.Sprite.__init__(self)
self.position = position                                  # 原始坐标
self.screen = screen
self.maze = maze                                          # 引用当前的迷宫对象
self.raw_image = pygame.image.load(image).convert_alpha() # 原始造型
"下面这句缩小老鼠的宽度为50，高度按比例调整"
self.raw_image = pygame.transform.scale(self.raw_image,(50,int(50*self.raw_image.get_height()//self.raw_image.get_width())))
self.image = self.raw_image                               # 设定image的初始值
self.rect = self.raw_image.get_rect()                     # 得到矩形对象
self.rect.center = position                               # 定坐标
self.angle = 0                                            # 和x轴的夹角，角度
self.bump_wall = 1
def towards(self,mousexy):
"""根据鼠标指针的坐标设定方向"""
dy = -(mousexy[1] - self.rect.centery)
dx = mousexy[0] - self.rect.centerx
self.angle =  math.degrees(math.atan2(dy,dx))

def distance(self,mousexy):
"""到鼠标指针的距离"""
dy = mousexy[1] - self.rect.centery
dx = mousexy[0] - self.rect.centerx
return math.sqrt(dx * dx  + dy * dy)

def update(self,mousexy,logic):
"""根据方向角度更新图像"""
if self.distance(mousexy) > 50 :
self.image = pygame.transform.rotate(self.raw_image,self.angle).convert_alpha()
self.image.set_colorkey((0,0,0))
self.mask = pygame.mask.from_surface(self.image)        # 设定掩膜属性，以后用于和迷宫mask的碰撞检测
self.rect = self.image.get_rect()                       # 得到矩形对象
self.rect.center = self.position                        # 矩形的中心点位置
dy = -mousexy[1] + self.rect.centery
dx = -mousexy[0] + self.rect.centerx
dy = logic * dy
dx = logic * dx
self.maze.update(dx,dy)                                 # 更新迷宫坐标

def bump_check(self):
"""对碰黑墙和碰绿门进行碰撞检测，实际上是对maze进行通过mask的碰撞检测，返回point坐标。
，再侦测像素值就知道是碰到门还是碰到绿色"""
level_end = False
point = pygame.sprite.collide_mask(self.maze,self)
"迷宫绿色像素值为：(0, 255, 85, 255)，黑色墙壁的像素值为：(0,0,0,255)"
if point :
pixel_maze = self.maze.image.get_at(point)
#print("碰撞点",point,"迷宫像素值：",pixel_maze)
if pixel_maze == (0, 255, 85, 255):                  # 碰到绿色的门，那么此关结束。
level_end = True
elif pixel_maze == (0, 0, 0, 255):                   # 碰到黑色的墙，倒回去
self.update(mousexy,-1)
return level_end

def draw(self):
self.screen.blit(self.image,self.rect)

def display_shell(screensize,shell_image,begin_button_images):
width,height = screensize
index = 0
button_image = begin_button_images[index]

button_rect = button_image.get_rect()
button_width = button_rect.width
button_height = button_rect.height
button_rect.center = (width//2,100+height//2)
clock = pygame.time.Clock()
running = True
continue_game = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
continue_game = False
break
mousexy = pygame.mouse.get_pos()
mousekeys = pygame.mouse.get_pressed()

if button_rect.collidepoint(mousexy):                 # 鼠标指针在矩形范围内
index = 1
else:
index = 0

if mousekeys[0] and index == 1:
running = False

screen.blit(shell_image,(0,0))
screen.blit(begin_button_images[index],button_rect)

pygame.display.update()
clock.tick(30)

return continue_game

def display_end(end_image):
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
break
mousekeys = pygame.mouse.get_pressed()
if mousekeys[0] : running = False

screen.blit(end_image,(0,0))
pygame.display.update()
clock.tick(30)

if __name__ == "__main__":

shell_image = pygame.image.load(os.getcwd() + os.sep + "images" + os.sep + "封面.png")
begin_button_images = ["开始按钮1.png","开始按钮2.png"]
begin_button_images = [pygame.image.load(os.getcwd() + os.sep + "images" + os.sep + image) for image in  begin_button_images]
end_image = pygame.image.load(os.getcwd() + os.sep + "images" + os.sep + "endimage.png")

success_image = pygame.image.load(os.getcwd() + os.sep + "images" + os.sep + "过关界面.png")
maze_images = [os.getcwd() + os.sep + "images" + os.sep + str(i) + ".png" for i in range(5)]
maze_amounts = len(maze_images)
mouse_image = os.getcwd() + os.sep + "images" + os.sep + "mouse1-a.png"
width,height = 800,600
game_title = "鼠标迷宫游戏_作者:李兴球,风火轮少儿编程,www.scratch8.net"
pygame.init()
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption(game_title)

if  display_shell((width,height),shell_image,begin_button_images):       # 显示封面，单击开始按钮继续程序运行。

mazes  = [Maze(maze_images[index],index + 2,screen) for index in range(maze_amounts)]
current_maze_index = 0
current_maze = [current_maze_index]
mouse = Mouse(mouse_image,(width//2,height//2),screen)
clock = pygame.time.Clock()
exit_game = False
for current_maze in mazes:
mouse.maze = current_maze
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
exit_game = True
break
mousexy = pygame.mouse.get_pos()
mouse.towards(mousexy)
mouse.update(mousexy,1)                                      # mouse的update会自动调用maze.update

"给Mouse类增加了这个方法，用于碰墙与碰门的检测"
level_end = mouse.bump_check()
if level_end : break
screen.fill((255,255,255))
current_maze.draw()
mouse.draw()

pygame.display.update()
clock.tick(30)

if exit_game : break
print("本关结束，单击后开始下一关。")
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
exit_game = True
break
if pygame.mouse.get_pressed()[0] or pygame.key.get_pressed()[K_RETURN]:running = False
screen.blit(success_image,(0,0))
pygame.display.update()
clock.tick(60)
if exit_game : break

display_end(end_image)
pygame.quit()
print("游戏结束。")

```