基于python的pygame的游戏之迷宫小游戏

依然范特西╮ 提交于 2020-04-07 21:32:42

开发工具:vscode、pycharm

一、游戏简介
二、开发流程
三、代码实现
四、运行截图
五、总结反思

一、游戏简介

此迷宫主要通过上下左右键来控制行走,起点在左上角,终点在右下角 ,走到终点即为成功。

界面显示迷宫,步数,及撞墙提醒。

迷宫地图为随机生成。

二、开发流程

1、明确游戏功能:

  • 创建地图
  • 控制人物移动
  • 步数统计
  • 遇到阻碍提示
  • 游戏结束刷新页面进行下一关(未实现)

2、分工情况:两个小组完成

3、实现迷宫地图,自动生成地图

三、代码实现 (1)设置迷宫大小

# 设置迷宫的大小
global room_m, room_n, room_size
room_m = 40
room_n = 25
room_size = 19 # 每个小房间的大小
steps = 0

# 设置屏幕宽度和高度为全局变量
global screen_width
screen_width = 800
global screen_height
screen_height = 500

(2)画迷宫

def draw_room(screen, begin_point, walls, size, r_color):
        n = 0
        # 一个小房间的四面墙
        for wall in walls:
            x = begin_point[0] # 迷宫起点的 x 坐标
            y = begin_point[1] # 迷宫起点的 y 坐标
            n += 1
            if n == 1 and wall: # x → x + size 是墙
                pygame.draw.line(screen, r_color, (x, y), (x + size, y))
            if n == 2 and wall:
                pygame.draw.line(screen, r_color, (x + size, y), (x + size, y + size))
            if n == 3 and wall:
                pygame.draw.line(screen, r_color, (x + size, y + size), (x, y + size))
            if n == 4 and wall:
                pygame.draw.line(screen, r_color, (x, y + size), (x, y))

(3)生成迷宫地图

def creat_map(m, n):
        room_list = [[0 for col in range(n)] for row in range(m)] # 二维数组: m*n
        for i in range(m):
            for j in range(n):
                room_list[i][j] = room(i, j)
        return room_list

(4)获取下一个房间格子

def get_next_room(room_list, room):
        temp_rooms = {1: None,
                      2: None,
                      3: None,
                      4: None}
        temp_room_count = 0
        # 判断上下左右四个方向的小房间有没有被访问,没有的话就加入 temp_rooms[]
        if (not room.y - 1 < 0) and (not room_list[room.x][room.y - 1].visited): # 上边没被访问
            temp_rooms[1] = room_list[room.x][room.y - 1]
            temp_room_count += 1
        if (not room.x + 1 > room_m - 1) and (not room_list[room.x + 1][room.y].visited): # 右边
            temp_rooms[2] = room_list[room.x + 1][room.y]
            temp_room_count += 1
        if (not room.y + 1 > room_n - 1) and (not room_list[room.x][room.y + 1].visited): # 下边
            temp_rooms[3] = room_list[room.x][room.y + 1]
            temp_room_count += 1
        if (not room.x - 1 < 0) and (not room_list[room.x - 1][room.y].visited): # 左边
            temp_rooms[4] = room_list[room.x - 1][room.y]
            temp_room_count += 1

        if temp_room_count > 0:
            do = True
            while do:
                room_id = randint(1, 4) # 随机生成,指定某一边没有墙
                if temp_rooms[room_id]:
                    do = False
                    next_room = temp_rooms[room_id]
                    if room_id == 1:
                        room.walls[0] = 0  # 当前房间的上边没有墙
                        next_room.walls[2] = 0  # 上面房间的下边没有墙
                    if room_id == 2:
                        room.walls[1] = 0
                        next_room.walls[3] = 0
                    if room_id == 3:
                        room.walls[2] = 0
                        next_room.walls[0] = 0
                    if room_id == 4:
                        room.walls[3] = 0
                        next_room.walls[1] = 0
            return next_room
        else:
            return None

(5)创建迷宫

def creat_migong(room_list, next_room, temp_yes_rooms=[]):
        while True:
            if next_room:
                # 下一房间未被访问
                if not next_room.visited:
                    next_room.visited = True
                    temp_yes_rooms.append(next_room)
                next_room = room.get_next_room(room_list, next_room)
            else:
                next_room = temp_yes_rooms.pop()  # 否则出栈
                if len(temp_yes_rooms) == 0:
                    break

(6)生成角色

user = pygame.image.load("user.png").convert_alpha()
    width,height = user.get_size()
    user = pygame.transform.smoothscale(user, (8,8))
    # 画角色
    width, height = user.get_size()
    x = 27
    y = 30
    roomx = 0
    roomy = 0
    screen.blit(user, (x, y))

(7)实现计步功能

if(r_list[roomx][roomy].walls[1] == False):
   x += maze.room_size
   roomx += 1 # 计房间数
   maze.steps += 1 # 计步
   font1 = pygame.font.Font(None, 32)
   screen.fill(color.White, (25, 0, 200, 25)) # x:25 y:0 width:200 height:25
   screen.fill(color.White, (300, 0, 200, 25))  # x:300 y:0 width:200 height:25
   print_text(font1, 25, 0, "Steps:" + str(maze.steps), color.Black)
   pygame.display.flip()
   screen.fill(color.White, (x-15,y,10,10))
   screen.blit(user, (x, y))

(8)、障碍提示

 elif (r_list[roomx][roomy].walls[1] == True):
     maze.steps += 1
     font1 = pygame.font.Font(None, 32)
     font2 = pygame.font.Font(None, 32)
     screen.fill(color.White, (25, 0, 200, 25))  # x:25 y:0 width:200 height:25
     print_text(font1, 25, 0, "Steps:" + str(maze.steps), color.Black)
     print_text(font2, 350, 0, "This is a wall!", color.Black)
     pygame.display.flip()
     screen.blit(user, (x, y))

完整代码

1、maze.py

import pygame
import sys
import time
from pygame.locals import *
from random import randint, choice
import color


# 设置迷宫的大小
global room_m, room_n, room_size
room_m = 40
room_n = 25
room_size = 19 # 每个小房间的大小
steps = 0

# 设置屏幕宽度和高度为全局变量
global screen_width
screen_width = 800
global screen_height
screen_height = 500

class room():
    def __init__(self, x, y):
        self.walls = [True, True, True, True] # 初始化地图,小房间四周都是墙
        self.visited = False # 初始化小房间都未被访问过
        self.x = x
        self.y = y


    # 画迷宫
    def draw_room(screen, begin_point, walls, size, r_color):
        n = 0
        # 一个小房间的四面墙
        for wall in walls:
            x = begin_point[0] # 迷宫起点的 x 坐标
            y = begin_point[1] # 迷宫起点的 y 坐标
            n += 1
            if n == 1 and wall: # x → x + size 是墙
                pygame.draw.line(screen, r_color, (x, y), (x + size, y))
            if n == 2 and wall:
                pygame.draw.line(screen, r_color, (x + size, y), (x + size, y + size))
            if n == 3 and wall:
                pygame.draw.line(screen, r_color, (x + size, y + size), (x, y + size))
            if n == 4 and wall:
                pygame.draw.line(screen, r_color, (x, y + size), (x, y))


    # 生成迷宫地图
    def creat_map(m, n):
        room_list = [[0 for col in range(n)] for row in range(m)] # 二维数组: m*n
        for i in range(m):
            for j in range(n):
                room_list[i][j] = room(i, j)
        return room_list


    # 获取下一个房间
    def get_next_room(room_list, room):
        temp_rooms = {1: None,
                      2: None,
                      3: None,
                      4: None}
        temp_room_count = 0
        # 判断上下左右四个方向的小房间有没有被访问,没有的话就加入 temp_rooms[]
        if (not room.y - 1 < 0) and (not room_list[room.x][room.y - 1].visited): # 上边没被访问
            temp_rooms[1] = room_list[room.x][room.y - 1]
            temp_room_count += 1
        if (not room.x + 1 > room_m - 1) and (not room_list[room.x + 1][room.y].visited): # 右边
            temp_rooms[2] = room_list[room.x + 1][room.y]
            temp_room_count += 1
        if (not room.y + 1 > room_n - 1) and (not room_list[room.x][room.y + 1].visited): # 下边
            temp_rooms[3] = room_list[room.x][room.y + 1]
            temp_room_count += 1
        if (not room.x - 1 < 0) and (not room_list[room.x - 1][room.y].visited): # 左边
            temp_rooms[4] = room_list[room.x - 1][room.y]
            temp_room_count += 1

        if temp_room_count > 0:
            do = True
            while do:
                room_id = randint(1, 4) # 随机生成,指定某一边没有墙
                if temp_rooms[room_id]:
                    do = False
                    next_room = temp_rooms[room_id]
                    if room_id == 1:
                        room.walls[0] = 0  # 当前房间的上边没有墙
                        next_room.walls[2] = 0  # 上面房间的下边没有墙
                    if room_id == 2:
                        room.walls[1] = 0
                        next_room.walls[3] = 0
                    if room_id == 3:
                        room.walls[2] = 0
                        next_room.walls[0] = 0
                    if room_id == 4:
                        room.walls[3] = 0
                        next_room.walls[1] = 0
            return next_room
        else:
            return None


    # 创建迷宫
    def creat_migong(room_list, next_room, temp_yes_rooms=[]):
        while True:
            if next_room:
                # 下一房间未被访问
                if not next_room.visited:
                    next_room.visited = True
                    temp_yes_rooms.append(next_room)
                next_room = room.get_next_room(room_list, next_room)
            else:
                next_room = temp_yes_rooms.pop()  # 否则出栈
                if len(temp_yes_rooms) == 0:
                    break

2、color.py

# RGB
Aqua = (0, 255, 255)
Black = (0, 0, 0)
Blue = (0, 0, 255)
Fuchsia = (255, 0, 255)
Gray = (128, 128, 128)
Green = (0, 128, 0)
Lime = (0, 255, 0)
Maroon = (128, 0, 0)
NavyBlue = (0, 0, 128)
Olive = (128, 128, 0)
Purple = (128, 0, 128)
Red = (255,0,0)
Silver = (192, 192, 192)
Teal = (0, 128, 128)
White = (255, 255, 255)
Yellow = (255, 255, 0)

colors = [Aqua, Black, Blue, Fuchsia, Gray, Green, Lime, Maroon, NavyBlue, Olive, Purple, Red, Silver, Teal, Yellow]

3、main.py

# 功能:主程序

import pygame
import sys
import random
import time
from pygame.locals import *
from random import randint, choice
import maze
import color


# 设置屏幕宽度和高度为全局变量
global screen_width
screen_width = 800
global screen_height
screen_height = 550


# 输出文本信息
def print_text(font, x, y, text, color, shadow=True):
    if shadow:
        imgText = font.render(text, True, (0, 0, 0))
        screen.blit(imgText, (x-2,y-2))
    imgText = font.render(text, True, color)
    screen.blit(imgText, (x,y))


# 游戏开始
if __name__ == '__main__':
    pygame.init()

    screen = pygame.display.set_mode([screen_width, screen_height])
    pygame.display.set_caption('Maze') # 游戏标题
    global font1, font2, font3, font4 # 文字


    clock = pygame.time.Clock()
    fps = 20
    screen.fill(color.White)


    r_list = maze.room.creat_map(maze.room_m, maze.room_n)
    begin_point = [0, 0]
    begin_room = r_list[0][0]
    maze.room.creat_migong(r_list, begin_room)
    # 画出去起点和终点的其他点
    for i in range(maze.room_m):
        for j in range(maze.room_n):
            begin_point[0] = 25 + i * maze.room_size
            begin_point[1] = 25 + j * maze.room_size
            r_color = color.Black
            maze.room.draw_room(screen, begin_point, r_list[i][j].walls, maze.room_size, r_color)
    # 画起点
    maze.room.draw_room(screen, [25, 25], [0, 0, 0, 1], maze.room_size, color.White)
    # 画终点
    maze.room.draw_room(screen, [25 + (maze.room_m - 1) * maze.room_size, 25 + (maze.room_n - 1) * maze.room_size],
                        [0, 1, 0, 0], maze.room_size, color.White)


    # 加载角色照片
    user = pygame.image.load("user.png").convert_alpha()
    width,height = user.get_size()
    user = pygame.transform.smoothscale(user, (8,8))
    # 画角色
    width, height = user.get_size()
    x = 27
    y = 30
    roomx = 0
    roomy = 0
    screen.blit(user, (x, y))


    # 键盘控制角色移动
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            # 走到终点
            elif(roomx == maze.room_m-1 and roomy == maze.room_n-1):
                font4 = pygame.font.Font(None, 32)
                print_text(font4, 350, 350, "Win" , color.Red)
               
            # 键盘响应,只取按“→”键作为例子,“↑”、“↓”、“←”类似,只要改改参数即可
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    # 右边无墙
                    if(r_list[roomx][roomy].walls[1] == False):
                        x += maze.room_size
                        roomx += 1 # 计房间数
                        maze.steps += 1 # 计步
                        font1 = pygame.font.Font(None, 32)
                        screen.fill(color.White, (25, 0, 200, 25)) # x:25 y:0 width:200 height:25
                        screen.fill(color.White, (300, 0, 200, 25))  # x:300 y:0 width:200 height:25
                        print_text(font1, 25, 0, "Steps:" + str(maze.steps), color.Black)
                        pygame.display.flip()
                        screen.fill(color.White, (x-15,y,10,10))
                        screen.blit(user, (x, y))
                    # 右边有墙
                    elif (r_list[roomx][roomy].walls[1] == True):
                        maze.steps += 1
                        font1 = pygame.font.Font(None, 32)
                        font2 = pygame.font.Font(None, 32)
                        screen.fill(color.White, (25, 0, 200, 25))  # x:25 y:0 width:200 height:25
                        print_text(font1, 25, 0, "Steps:" + str(maze.steps), color.Black)
                        print_text(font2, 350, 0, "This is a wall!", color.Black)
                        pygame.display.flip()
                        screen.blit(user, (x, y))

                elif event.key == pygame.K_LEFT:
                    # 左边无墙
                    if (r_list[roomx][roomy].walls[3] == False):
                        x -= maze.room_size
                        roomx -= 1
                        maze.steps += 1
                        font1 = pygame.font.Font(None, 32)
                        screen.fill(color.White, (25, 0, 200, 25))
                        screen.fill(color.White, (300, 0, 200, 25))  # x:300 y:0 width:200 height:25
                        print_text(font1, 25, 0, "Steps:" + str(maze.steps), color.Black)
                        pygame.display.flip()
                        screen.fill(color.White, (x+15,y,10,10))
                        screen.blit(user, (x, y))
                    # 左边有墙
                    elif (r_list[roomx][roomy].walls[3] == True):
                        maze.steps += 1
                        font1 = pygame.font.Font(None, 32)
                        font2 = pygame.font.Font(None, 32)
                        screen.fill(color.White, (25, 0, 200, 25))
                        print_text(font1, 25, 0, "Steps:" + str(maze.steps), color.Black)
                        print_text(font2, 350, 0, "This is a wall!", color.Black)
                        pygame.display.flip()
                        screen.blit(user, (x, y))

                elif event.key == pygame.K_UP:
                    # 上边无墙
                    if (r_list[roomx][roomy].walls[0] == False):
                        y -= maze.room_size
                        roomy -= 1
                        maze.steps += 1
                        font1 = pygame.font.Font(None, 32)
                        screen.fill(color.White, (25, 0, 200, 25))
                        screen.fill(color.White, (300, 0, 200, 25))  # x:300 y:0 width:200 height:25
                        print_text(font1, 25, 0, "Steps:" + str(maze.steps), color.Black)
                        pygame.display.flip()
                        screen.fill(color.White, (x,y+15,10,10))
                        screen.blit(user, (x, y))
                    # 上边有墙
                    elif (r_list[roomx][roomy].walls[0] == True):
                        maze.steps += 1
                        font1 = pygame.font.Font(None, 32)
                        font2 = pygame.font.Font(None, 32)
                        screen.fill(color.White, (25, 0, 200, 25))
                        print_text(font1, 25, 0, "Steps:" + str(maze.steps), color.Black)
                        print_text(font2, 350, 0, "This is a wall!", color.Black)
                        pygame.display.flip()
                        screen.blit(user, (x, y))

                elif event.key == pygame.K_DOWN:
                    # 下边无墙
                    if (r_list[roomx][roomy].walls[2] == False):
                        y += maze.room_size
                        roomy += 1
                        maze.steps += 1
                        font1 = pygame.font.Font(None, 32)
                        screen.fill(color.White, (25, 0, 200, 25))
                        screen.fill(color.White, (300, 0, 200, 25))  # x:300 y:0 width:200 height:25
                        print_text(font1, 25, 0, "Steps:" + str(maze.steps), color.Black)
                        pygame.display.flip()
                        screen.fill(color.White, (x,y-15,10,10))
                        screen.blit(user, (x, y))
                    # 下边无墙
                    elif (r_list[roomx][roomy].walls[2] == True):
                        maze.steps += 1
                        font1 = pygame.font.Font(None, 32)
                        font2 = pygame.font.Font(None, 32)
                        screen.fill(color.White, (25, 0, 200, 25))
                        print_text(font1, 25, 0, "Steps:" + str(maze.steps), color.Black)
                        print_text(font2, 350, 0, "This is a wall!", color.Black)
                        pygame.display.flip()
                        screen.blit(user, (x, y))

        # 更新屏幕
        pygame.display.update()

四、运行截图

五、总结反思

对pygame的了解不够透彻,对它按钮的跳转不会使用,对按钮的掌握不好,导致在这个实验的下一关刷新失败。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!