开发工具: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的了解不够透彻,对它按钮的跳转不会使用,对按钮的掌握不好,导致在这个实验的下一关刷新失败。
来源:oschina
链接:https://my.oschina.net/u/4459334/blog/3223400