把这个代码的问题解决下#===============================库导入=======================================
import pygame
from pygame.locals import *
#方向键:
"""
K_UP,K_DOWN,K_LEFT,K_RIGHT
K_a~z:字母:a=97
k_ESCAPE:退出游戏
"""
import time
import os
from sys import exit #系统退出
# 初始化pygame
pygame.init()
#=========================加载资源===========================
#创建游戏的窗口
#模式:0,窗口是固定的。pygame.FULLSCEEN:全屏模式,pygame.RESIZABLE:窗口可缩放模式
#32:颜色的深度
Game_Screen = pygame.display.set_mode((768,768),0,32)
#图片资源
Image_Welcome = pygame.image.load("source/welcome.png").convert()
Image_Help = pygame.image.load("source/help.png").convert()
#convert:1.提升渲染速度。2.原始图像有很多像素格式:JPG,PNG。统一
#缩放图片到指定尺寸。
Image_Welcome = pygame.transform.scale(Image_Welcome,(768,768))
Image_Help = pygame.transform.scale(Image_Help,(768,768))
# 加载其他游戏图片
def load_and_scale(image_path, size=(64,64)):
"""加载并缩放图片"""
# 修复:使用convert()替代convert_alpha()避免透明问题
img = pygame.image.load(image_path).convert()
return pygame.transform.scale(img, size)
# 加载游戏元素图片
Image_Player = load_and_scale("source/lanlingwang.jpg")
Image_Wall = load_and_scale("source/wall.jpg")
Image_Box_Outplace = load_and_scale("source/Box_Inplace.jpg")
Image_Box_Inplace = load_and_scale("source/Box_Inplace.jpg") # 使用同一张图片,但可以不同颜色
Image_Goal = load_and_scale("source/Goal.jpg")
Image_Success = pygame.image.load("source/Success.jpg").convert()
Image_Success = pygame.transform.scale(Image_Success, (768, 768))
# 设置箱子到位后的颜色(绿色)
# 使用copy()避免修改原图
Image_Box_Inplace = Image_Box_Inplace.copy()
Image_Box_Inplace.fill((0, 255, 0, 128), special_flags=pygame.BLEND_RGBA_MULT)
#===============================全局变量====================================
Game_Map=[] #动态变化的地图数据
Map_Wide=0 #地图列数(横向格子数)
Map_Deepth=0 #地图行数(纵向格子数)
Game_Level=1 #当前关卡编号
Player_Pos=[0,0] #玩家当前位置[y,x]
Game_Map_Source=[] #原始地图数据备份
Game_path=[]#记录玩家操作路径(如移动步骤)。
MAX_LEVEL = 2 # 最大关卡数
#==============================地图读取===========================
def Map_Reader(Mission):
"""读取指定关卡地图"""
global Game_Map, Map_Deepth,Map_Wide, Player_Pos
File_Name="map/"+str(Mission)+'.dat'#构建文件路径
if not os.path.exists(File_Name):
print(f"关卡文件 {File_Name} 不存在!")
return False
Game_Map = [] # 重置地图
with open(File_Name,'r') as file: #打开地图文件
#读取首行获取地图尺寸(行数 列数)
size_line = file.readline().split()
if len(size_line) < 2:
print("地图文件格式错误!")
return False
Map_Deepth, Map_Wide = map(int, size_line)
#逐行读取地图数据(截取指定宽度)
for i in range(Map_Deepth):
line = file.readline().strip()
if len(line) < Map_Wide:
line += ' ' * (Map_Wide - len(line)) # 用空格补齐
Game_Map.append(line[:Map_Wide])
# 寻找玩家初始位置
if 'P' in line:
Player_Pos = [i, line.index('P')] # [y, x]
return True
#===============================地图绘制=======================
def Display_refresh(Game_Screen):
"""更新游戏画面"""
global Player_Pos
Game_Screen.fill((255,255,255)) #填充白色背景
# 计算偏移量使地图居中
screen_width, screen_height = Game_Screen.get_size()
offset_x = (screen_width - Map_Wide * 64) // 2
offset_y = (screen_height - Map_Deepth * 64) // 2
#遍历每个地图格子
for i in range(Map_Deepth):
for j in range(Map_Wide):
pos = [offset_x + j*64, offset_y + i*64] #计算屏幕坐标
cell = Game_Map[i][j] #获取当前格子内容
# 先绘制目标点(如果有)
if Game_Map_Source[i][j] == 'G':
Game_Screen.blit(Image_Goal, pos)
# 根据内容绘制对应元素
if cell == 'P': #玩家
Game_Screen.blit(Image_Player, pos)
elif cell == 'W':#墙壁
Game_Screen.blit(Image_Wall, pos)
elif cell == 'B':#未到位箱子
Game_Screen.blit(Image_Box_Outplace, pos)
elif cell == 'A':#到位箱子
Game_Screen.blit(Image_Box_Inplace, pos)
# 显示关卡信息
font = pygame.font.SysFont(None, 36)
level_text = font.render(f"第{Game_Level}关", True, (0, 0, 0))
Game_Screen.blit(level_text, (20, 20))
# 显示操作提示
help_text = font.render("R:重置关卡 Z:撤销 ESC:退出", True, (0, 0, 0))
Game_Screen.blit(help_text, (20, screen_height - 40))
pygame.display.set_caption(f"推箱子 - 第{Game_Level}关")
pygame.display.update()
#===============================关卡初始化=============================
def Defult():
"""初始化新关卡"""
global Game_Map, Game_Map_Source, Game_path, Player_Pos
Game_path = [] #清空操作记录
if not Map_Reader(Game_Level): #读取新关卡
return None
# 修复:使用深拷贝备份地图
Game_Map_Source = [row[:] for row in Game_Map]
#根据地图尺寸调整窗口大小
screen_width = max(768, Map_Wide * 64)
screen_height = max(768, Map_Deepth * 64)
pygame.display.set_mode((screen_width, screen_height), 0, 32)
return Game_Screen
#===============================移动处理函数=============================
def move_player(dx, dy):
"""处理玩家移动"""
global Game_Map, Player_Pos, Game_path
y, x = Player_Pos # 玩家位置 [y, x]
new_x, new_y = x + dx, y + dy
# 检查是否超出边界
if new_y < 0 or new_y >= Map_Deepth or new_x < 0 or new_x >= Map_Wide:
return False
# 获取目标位置的字符
target_cell = Game_Map[new_y][new_x]
# 如果是墙,不能移动
if target_cell == 'W':
return False
# 如果是空地或目标点,直接移动
if target_cell == ' ' or target_cell == 'G':
# 移动玩家 - 修复:恢复原始地图状态
old_char = Game_Map_Source[y][x]
Game_Map[y] = Game_Map[y][:x] + old_char + Game_Map[y][x+1:]
new_char = 'G' if Game_Map[new_y][new_x] == 'G' else 'P'
Game_Map[new_y] = Game_Map[new_y][:new_x] + 'P' + Game_Map[new_y][new_x+1:]
Player_Pos[0], Player_Pos[1] = new_y, new_x
Game_path.append((dx, dy, False, (y, x))) # 记录移动位置
return True
# 如果是箱子
if target_cell == 'B' or target_cell == 'A':
# 计算箱子移动后的位置
box_new_x, box_new_y = new_x + dx, new_y + dy
# 检查箱子新位置是否有效
if box_new_y < 0 or box_new_y >= Map_Deepth or box_new_x < 0 or box_new_x >= Map_Wide:
return False
# 获取箱子新位置的字符
new_box_cell = Game_Map[box_new_y][box_new_x]
# 如果箱子新位置是墙或另一个箱子,不能移动
if new_box_cell == 'W' or new_box_cell == 'B' or new_box_cell == 'A':
return False
# 移动箱子和玩家
# 1. 恢复玩家当前位置
old_char = Game_Map_Source[y][x]
Game_Map[y] = Game_Map[y][:x] + old_char + Game_Map[y][x+1:]
# 2. 移动箱子
# 箱子新位置:如果是目标点,则设置为到位箱子'A',否则为未到位箱子'B'
if Game_Map_Source[box_new_y][box_new_x] == 'G':
new_box_char = 'A'
else:
new_box_char = 'B'
Game_Map[box_new_y] = Game_Map[box_new_y][:box_new_x] + new_box_char + Game_Map[box_new_y][box_new_x+1:]
# 3. 移动玩家到箱子原来的位置
# 箱子原来位置的状态
new_char = 'G' if Game_Map_Source[new_y][new_x] == 'G' else 'P'
Game_Map[new_y] = Game_Map[new_y][:new_x] + 'P' + Game_Map[new_y][new_x+1:]
Player_Pos[0], Player_Pos[1] = new_y, new_x
# 记录移动(推箱子)
Game_path.append((dx, dy, True, (y, x)))
return True
return False
#===============================撤销操作=============================
def undo_move():
"""撤销上一步操作"""
global Game_Map, Player_Pos, Game_path
if not Game_path:
return False # 没有可撤销的操作
# 获取最后一步操作
dx, dy, pushed, (old_y, old_x) = Game_path.pop()
# 当前玩家位置
y, x = Player_Pos # [y, x]
# 玩家回到之前的位置
prev_x, prev_y = x - dx, y - dy
# 恢复玩家当前位置为原始状态
Game_Map[y] = Game_Map[y][:x] + Game_Map_Source[y][x] + Game_Map[y][x+1:]
# 如果上一步推动了箱子
if pushed:
# 箱子的位置是新的位置
box_x, box_y = x + dx, y + dy
# 恢复箱子原来位置为玩家移动前的位置状态
Game_Map[box_y] = Game_Map[box_y][:box_x] + Game_Map_Source[box_y][box_x] + Game_Map[box_y][box_x+1:]
# 恢复箱子原来位置的状态(地图原始状态)
Game_Map[y] = Game_Map[y][:x] + ('G' if Game_Map_Source[y][x] == 'G' else 'B') + Game_Map[y][x+1:]
# 设置玩家到之前的位置
Game_Map[prev_y] = Game_Map[prev_y][:prev_x] + 'P' + Game_Map[prev_y][prev_x+1:]
Player_Pos[0], Player_Pos[1] = prev_y, prev_x
return True
#===============================检查是否过关=============================
def check_victory():
"""检查是否过关"""
for i in range(Map_Deepth):
for j in range(Map_Wide):
# 如果原始地图中有目标点,但当前地图没有到位箱子,则未过关
if Game_Map_Source[i][j] == 'G' and Game_Map[i][j] != 'A':
return False
return True
#===============================主游戏循环=============================
def show_success_screen():
"""显示通关成功画面"""
global Game_Screen
# 创建半透明表面
overlay = pygame.Surface(Game_Screen.get_size(), pygame.SRCALPHA)
overlay.fill((0, 0, 0, 128)) # 半透明黑色
# 显示成功图片
Game_Screen.blit(overlay, (0, 0))
Game_Screen.blit(Image_Success,
((Game_Screen.get_width() - Image_Success.get_width()) // 2,
(Game_Screen.get_height() - Image_Success.get_height()) // 2))
# 显示文字
font = pygame.font.SysFont(None, 72)
text = font.render("恭喜过关!", True, (255, 215, 0)) # 金色
Game_Screen.blit(text,
((Game_Screen.get_width() - text.get_width()) // 2,
Game_Screen.get_height() // 4))
font = pygame.font.SysFont(None, 36)
text = font.render("按空格键继续下一关", True, (255, 255, 255))
Game_Screen.blit(text,
((Game_Screen.get_width() - text.get_width()) // 2,
Game_Screen.get_height() * 3 // 4))
pygame.display.update()
# 等待按键
waiting = True
while waiting:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
exit()
if event.type == KEYDOWN:
if event.key == K_SPACE or event.key == K_RETURN:
waiting = False
elif event.key == K_ESCAPE:
pygame.quit()
exit()
#===============================主函数=============================
if __name__ == "__main__":
#显示欢迎界面
in_welcome = True
while in_welcome:
Game_Screen.blit(Image_Welcome, (0, 0))
pygame.display.update()
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
exit()
if event.type == KEYDOWN:
if event.key == K_1:
in_welcome = False # 开始游戏
elif event.key == K_2: # 显示帮助
Game_Screen.blit(Image_Help, (0, 0))
pygame.display.update()
waiting = True
while waiting:
for evt in pygame.event.get():
if evt.type == KEYDOWN or evt.type == QUIT:
waiting = False
elif event.key == K_3: # 退出
pygame.quit()
exit()
# 游戏主循环
running = True
while running and Game_Level <= MAX_LEVEL:
# 初始化关卡
screen = Defult()
if screen is None:
print(f"无法加载第{Game_Level}关,游戏结束")
break
# 关卡内游戏循环
level_complete = False
while running and not level_complete:
Display_refresh(Game_Screen)
for event in pygame.event.get():
if event.type == QUIT:
running = False
break
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
break
elif event.key == K_r: # 重置关卡
Game_Map = [row[:] for row in Game_Map_Source]
Game_path = []
# 重新查找玩家位置
for i in range(Map_Deepth):
for j in range(Map_Wide):
if Game_Map[i][j] == 'P':
Player_Pos[0], Player_Pos[1] = i, j
elif event.key == K_z: # 撤销
undo_move()
elif event.key == K_UP:
move_player(0, -1)
elif event.key == K_DOWN:
move_player(0, 1)
elif event.key == K_LEFT:
move_player(-1, 0)
elif event.key == K_RIGHT:
move_player(1, 0)
if not running:
break
# 检查是否过关
if check_victory():
level_complete = True
show_success_screen()
Game_Level += 1
# 检查是否通关所有关卡
if Game_Level > MAX_LEVEL:
# 显示最终通关画面
Game_Screen.fill((0, 0, 0))
font = pygame.font.S