ADD file via upload

main
pa3r2yevq 2 years ago
parent 18881e0e58
commit 74ded43dd5

@ -0,0 +1,347 @@
import pgzrun
from pgzero.actor import Actor
from pgzero.clock import clock
from pgzero.loaders import sounds
GRID_SIZE = 48 # 格子尺寸
WIDTH = GRID_SIZE * 11 # 屏幕宽度
HEIGHT = GRID_SIZE * 9 # 屏幕高度
size=WIDTH,HEIGHT
level = 1 # 游戏关卡值
level_images=[] #关卡图片
level_complete = False # 游戏过关标记
MAX_LEVEl = 3
game_over = False
display_game_over = False
start=False#开始游戏按钮
level_num_flag=False#选关窗口判定
ui_game_over = Actor("pushbox_game_over",(WIDTH//2,HEIGHT//2))
# 方向字典,存储各方向对应的坐标偏移值
dirs = {"right":(1, 0), "left":(-1, 0),
"up":(0, -1), "down":(0, 1), "none":(0, 0)}
# 游戏界面元素
ui_level_up = Actor("pushbox_level_up", (WIDTH//2, HEIGHT//2))
#开始界面
gui_background_image=Actor("gui_background",topleft=(0,0))
btn_start_game=Actor("start",(WIDTH-290, HEIGHT-160))
btn_exit_game=Actor("finish",(WIDTH-275,HEIGHT-60))
#绘制关卡
for i in range(3):
level_image=Actor("level"+str(i + 1), (0, HEIGHT // 2 + 80 * i))
level_images.append(level_image)
# 从文件读取地图数据
def load_map(map_file):
map_array =[]
with open(map_file, "r") as map_file:
lines = map_file.readlines()
for line in lines:
line = line.replace(" ", "") # 去掉空格
line = line.split(",") # 将文本行转换为字符列表
line = list(map(int, line)) # 将字符转化成整数
map_array.append(line)
return map_array
# 初始化地图,生成游戏角色
def setup_screen(mapdata):
global walls, floors, boxes, targets, player
walls = [] # 墙壁列表
floors= [] # 地板列表
boxes = [] # 箱子列表
targets = [] # 目标点列表
for row in range(len(mapdata)):
for col in range(len(mapdata[row])):
x = col * GRID_SIZE
y = row * GRID_SIZE
floors.append(Actor("pushbox_floor", topleft=(x, y)))
if mapdata[row][col] == 1:
walls.append(Actor("pushbox_wall", topleft=(x, y)))
elif mapdata[row][col] == 2:
box = Actor("pushbox_box", topleft=(x, y))
box.placed = False
boxes.append(box)
elif mapdata[row][col] == 3:
player = Actor("pushbox_down", topleft=(x, y))
elif mapdata[row][col] == 4:
targets.append(Actor("pushbox_target", topleft=(x, y)))
elif mapdata[row][col] == 6:
targets.append(Actor("pushbox_target", topleft=(x, y)))
box = Actor("pushbox_box_hit", topleft=(x, y))
box.placed = True
boxes.append(box)
# 加载地图,初始化关卡
def setup_level(level):
if level<=0:
return
mapdata = load_map("maps/map" + str(level) + ".txt")
setup_screen(mapdata)
# 处理键盘按下事件
def on_key_down(key):
if level_complete or game_over:
return
if key==keys.C:
undo()
return
if key == keys.O:
setup_level(level)
return
if key == keys.RIGHT:
player.direction = "right"
player.image = "pushbox_right"
elif key == keys.LEFT:
player.direction = "left"
player.image = "pushbox_left"
elif key == keys.DOWN:
player.direction = "down"
player.image = "pushbox_down"
elif key == keys.UP:
player.direction = "up"
player.image = "pushbox_up"
else:
player.direction = "none"
player_move()
player_collision()
#按钮点击
def on_mouse_down(pos):
global start,level_num_flag,level
if btn_start_game.collidepoint(pos):
start=True
level_num_flag = True
elif btn_exit_game.collidepoint(pos):
exit()
else:
for i in range(len(level_images)):
if level_images[i].collidepoint(pos) and level_num_flag and level:
if i == 0:
level_num1()
setup_level(level)
if i == 1:
level_num2()
setup_level(level)
elif i == 2:
level_num3()
setup_level(level)
level_num_flag = False
#游戏关卡绘制
level_image_bg=Actor("gui_background",topleft=(0,0))
def level_draw():
level_image_bg.draw()
#关卡1、2、3
def level_num1():
global level
level = 1
def level_num2():
global level
level = 2
def level_num3():
global level
level = 3
# 移动玩家角色
moves=[]
box_moves = []
def player_move():
player.oldx = player.x
player.oldy = player.y
if player.direction is None:
dx, dy = 0, 0
else:
dx, dy = dirs[player.direction]
player.x += dx * GRID_SIZE
player.y += dy * GRID_SIZE
moves.append((player.direction, -dx * GRID_SIZE, -dy * GRID_SIZE))
# 记录箱子移动前的位置
for box in boxes:
box.oldx = box.x
box.oldy = box.y
# 撤销最后一次移动操作
def undo():
global moves, box_moves, boxes
if moves:
last_move = moves.pop()
direction, dx, dy = last_move
player.direction = opposite_dir(direction)
player.x += dx
player.y += dy
player_collision() # 处理碰撞
# 检查是否有箱子的移动记录,如果有,则撤销箱子的移动
if box_moves:
last_box_move = box_moves.pop()
box,bx, by = last_box_move
box.x += bx
box.y += by
box_collision(box) # 重新处理箱子碰撞
# 获取相反的方向
def opposite_dir(direction):
if direction == "right":
return "left"
elif direction == "left":
return "right"
elif direction == "up":
return "down"
elif direction == "down":
return "up"
# 玩家角色的碰撞检测与处理
def player_collision():
# 玩家与墙壁的碰撞
if player.collidelist(walls) != -1:
player.x = player.oldx
player.y = player.oldy
return
# 检测玩家与箱子的碰撞
index = player.collidelist(boxes)
# 如果玩家没有碰到箱子,返回
if index == -1:
return
# 如果玩家碰到箱子,箱子先移动一格
box = boxes[index]
box.oldx = box.x
box.oldy = box.y
dx, dy = dirs[player.direction]
box.x += dx * GRID_SIZE
box.y += dy * GRID_SIZE
current_box = box
# 记录箱子的移动
box_moves.append((current_box, -dx * GRID_SIZE, -dy * GRID_SIZE))
# 如果箱子碰到了墙壁或者其他箱子,玩家和箱子都退回原来的位置
if box_collision(box) == True:
box.x = box.oldx
box.y = box.oldy
player.x = player.oldx
player.y = player.oldy
return
sounds.fall.play()
# 箱子角色的碰撞检测与处理
def box_collision(box):
# 箱子与墙壁的碰撞返回True
if box.collidelist(walls) != -1:
return True
# 箱子与其他箱子的碰撞返回True
if box_collision_check(box):
return True
for bx in boxes:
if box == bx:
continue
if box.colliderect(bx):
return True
check_target(box)
return False
def box_collision_check(box):
for bx in boxes:
if box == bx:
continue
if box.colliderect(bx):
return True
return False
# 检测箱子是否放置在目标点上
def check_target(box):
if box.collidelist(targets) != -1:
box.image = "pushbox_box_hit"
box.placed = True
else:
box.image = "pushbox_box"
box.placed = False
# 判断是否过关
def check_level_up():
for box in boxes:
if not box.placed:
return False
return True
# 设置新的关卡
def set_next_level():
global level_complete, level
level_complete = False
level += 1
setup_level(level)
# 更新游戏逻辑
def update():
global level_complete,game_over
if level_complete or game_over:
return
if check_level_up():
if level == MAX_LEVEl:
game_over = True
sounds.win.play()
clock.schedule(set_game_over,1)
else:
level_complete = True
sounds.win.play()
clock.schedule(set_next_level, 2)
# 绘制游戏图像
def draw():
screen.fill((255, 255, 255))
if not start:
# screen.clear()
gui_background_image.draw()
btn_start_game.draw()
btn_exit_game.draw()
return
elif level_num_flag and start:
# screen.clear()
level_draw()
level_menu_draw()
for level_image in level_images:
level_image.draw()
return
if game_over & display_game_over:
ui_game_over.draw()
return
for floor in floors:
floor.draw()
for wall in walls:
wall.draw()
for target in targets:
target.draw()
for box in boxes:
box.draw()
screen.draw.text("Level " + str(level), topleft=(20, 20),
fontsize=30, color="black")
player.draw()
if level_complete:
ui_level_up.draw()
def set_game_over():
global display_game_over
display_game_over = True
def level_menu_draw():
if level_num_flag:
for level_image in level_images:
level_image.x=WIDTH//2
else:
for level_image in level_images:
level_image.x=-50
setup_level(level)
pgzrun.go()
Loading…
Cancel
Save