推箱子小游戏 - Python Turtle 实现
import turtle # 引入turtle库 import level # 引入关卡数据模块
设置游戏窗口
ms = turtle.Screen() ms.setup(900, 650, 200, 0) ms.bgpic('bc1.gif') ms.title('推箱子小游戏')
注册游戏元素形状
ms.register_shape('wall.gif') ms.register_shape('o.gif') ms.register_shape('p.gif') ms.register_shape('box.gif') ms.register_shape('boxc.gif')
注册背景图
ms.register_shape('bc1.gif') ms.register_shape('bc2.gif') ms.register_shape('bc3.gif') ms.register_shape('bc4.gif') ms.register_shape('bc5.gif')
禁用自动刷新
ms.tracer(0)
加载关卡数据
levels = level.level_list()
定义画笔类
class Pen(turtle.Turtle): # 初始化画笔 def init(self, pic): super().init() self.shape(pic) self.penup()
# 移动画笔
def move(self, x, y, px, py):
# 计算移动后的坐标
gox, goy = x+px, y+py
# 如果移动后的坐标在可行走区域内
if (gox, goy) in go_space:
# 移动画笔
self.goto(gox, goy)
# 如果移动后的坐标在可行走区域内,并且有箱子
if (gox+px, goy+py) in go_space and (gox, goy) in box_space:
# 遍历箱子列表
for i in box_list:
# 如果箱子的位置与移动后的位置相同
if i.pos() == (gox, goy):
# 更新可行走区域和箱子位置列表
go_space.append(i.pos())
box_space.remove(i.pos())
# 移动箱子
i.goto(gox+px, goy+py)
# 移动画笔
self.goto(gox, goy)
# 更新可行走区域和箱子位置列表
go_space.remove(i.pos())
box_space.append(i.pos())
# 如果箱子位置在正确位置列表中
if i.pos() in correct_box_space:
# 显示正确的箱子图标
i.shape('boxc.gif')
else:
# 显示普通的箱子图标
i.shape('box.gif')
# 如果所有箱子位置都在正确位置列表中
if set(box_space) == set(correct_box_space):
# 显示过关提示
text.show_win()
# 向上移动画笔
def go_up(self):
self.move(self.xcor(), self.ycor(), 0, 50)
# 向下移动画笔
def go_down(self):
self.move(self.xcor(), self.ycor(), 0, -50)
# 向左移动画笔
def go_left(self):
self.move(self.xcor(), self.ycor(), -50, 0)
# 向右移动画笔
def go_right(self):
self.move(self.xcor(), self.ycor(), 50, 0)
定义游戏类
class Game(): # 绘制游戏元素 def paint(self): # 获取关卡数据的行数和列数 i_date = len(levels[num-1]) j_date = len(levels[num-1][0]) # 遍历关卡数据 for i in range(i_date): for j in range(j_date): # 计算每个元素的坐标 x = -j_date25+25+j50 + sister_x y = i_date25-25-i50 # 如果是正确的箱子位置 if levels[num-1][i][j] == 'O': # 绘制正确的箱子图标 correct_box.goto(x, y) correct_box.stamp() # 将正确的箱子位置添加到可行走区域和正确的箱子位置列表中 go_space.append((x, y)) correct_box_space.append((x, y)) # 如果是空白区域 if levels[num-1][i][j] == ' ': # 将空白区域添加到可行走区域中 go_space.append((x, y)) # 如果是墙 if levels[num-1][i][j] == 'X': # 绘制墙图标 wall.goto(x, y) wall.stamp() # 如果是玩家 if levels[num-1][i][j] == 'P': # 绘制玩家图标,并将位置添加到可行走区域中 player.goto(x, y) go_space.append((x, y)) # 如果是箱子 if levels[num-1][i][j] == 'B': # 绘制箱子图标,并将箱子和位置添加到箱子列表和箱子位置列表中 box = Pen('box.gif') box.goto(x, y) box_list.append(box) box_space.append((x, y))
定义显示消息的类
class ShowMessage(turtle.Turtle): # 初始化显示消息的类 def init(self): super().init() self.penup() self.pencolor('blue') self.ht()
# 显示消息
def message(self):
self.goto(0+sister_x, 290)
self.write(f'第{num}关', align='center', font=('仿宋', 20, 'bold'))
self.goto(0+sister_x, 270)
self.write('重新开始本关请按回车键', align='center', font=('仿宋', 15, 'bold'))
self.goto(0+sister_x, 250)
self.write('选择关卡请按Q', align='center', font=('仿宋', 15, 'bold'))
# 显示过关提示
def show_win(self):
global num
if num == len(levels):
# 如果已经通关所有关卡,显示全部通关提示
num = 1
self.goto(0, 0)
self.write('你已全部过关', align='center', font=('黑体', 30, 'bold'))
self.goto(0, -50)
self.write('返回第一关轻按空格键', align='center', font=('黑体', 30, 'bold'))
else:
# 如果还有未通关的关卡,显示过关提示
num = num+1
self.goto(0, 0)
self.write('恭喜过关', align='center', font=('黑体', 30, 'bold'))
self.goto(0, -50)
self.write('进入下一关请按空格键', align='center', font=('黑体', 30, 'bold'))
初始化游戏元素
def init(): # 清空画布和列表 text.clear() wall.clear() correct_box.clear() for i in box_list: i.ht() del(i) box_list.clear() box_space.clear() go_space.clear() correct_box_space.clear() # 绘制游戏元素和显示消息 game.paint() text.message() # 更换背景图 ms.bgpic(f'bc{num}.gif')
选择关卡
def choose(): global num a = ms.numinput('选择关卡', '你的选择(请输入1-5)', 1) if a is None: a = num num = int(a) init() ms.listen()
设置游戏元素的x坐标
sister_x = 225
设置当前关卡为第一关
num = 1
创建正确的箱子位置列表、箱子列表、箱子位置列表和可行走区域
correct_box_space = [] box_list = [] box_space = [] go_space = []
创建墙、正确的箱子、玩家、游戏和显示消息的对象
wall = Pen('wall.gif') correct_box = Pen('o.gif') player = Pen('p.gif') game = Game() text = ShowMessage()
绘制游戏元素和显示消息
game.paint() text.message()
监听玩家按键事件
ms.listen() ms.onkey(player.go_up, 'Up') ms.onkey(player.go_down, 'Down') ms.onkey(player.go_left, 'Left') ms.onkey(player.go_right, 'Right') ms.onkey(init, 'Return') ms.onkey(init, 'space') ms.onkey(choose, 'Q')
主循环
while True: # 更新画布 ms.update()
进入主循环
ms.mainloop()
原文地址: https://www.cveoy.top/t/topic/oRHs 著作权归作者所有。请勿转载和采集!