7109浏览
查看: 7109|回复: 5

【行空板Python入门教程】第5课时:2D迷宫

[复制链接]
本帖最后由 木子呢 于 2022-5-5 16:08 编辑

行空板,新一代国产开源硬件平台,仅需2步,即可让你轻松开启Python学习之路。

2D迷宫




迷宫游戏是许多小伙伴儿时经常做的游戏,它能锻炼我们的空间推理能力、逻辑力、耐心与恒心,也能带来许多欢乐。

让我们设计一个迷宫游戏,在屏幕上体验一下吧!

【行空板Python入门教程】第5课时:2D迷宫图1

任务目标

通过三轴加速度传感器获取加速度值,继而控制角色在地图上移动走出迷宫。

【行空板Python入门教程】第5课时:2D迷宫图2【行空板Python入门教程】第5课时:2D迷宫图3

知识点

1、认识三轴加速度传感器

2、学习使用Pinpong库读取加速度值的方法

3、学习使用turtle库绘制迷宫的方法

材料清单

【行空板Python入门教程】第5课时:2D迷宫图4
软件使用:Mind+编程软件x1

知识储备

1、什么是重力加速度与加速度传感器


地球表面附近的物体因受重力产生的加速度叫做重力加速度,也叫自由落体加速度,用g表示。

加速度传感器,是一种能够测量加速度,将其转换为电信号的设备。

行空板的加速度传感器是内置在板子上的,可以测量X,Y,Z三个方向的加速度,其中,X轴正方向为金手指一侧的方向,Y轴正方向为Home按键一侧的方向,Z轴垂直于板子,正方向为屏幕背面一侧的方向。

【行空板Python入门教程】第5课时:2D迷宫图5【行空板Python入门教程】第5课时:2D迷宫图6


2、Pinpong库读取加速度值

Pinpong库的“pinpong.extension.unihiker”文件下“GD32Sensor_acc”类中的“get_x()”、“get_y()”、“get_z()”三个方法可以分别获取x/y/z三个方向的加速度值,并且由于在文件中已经对该类进行过实例化生成了一个accelerometer对象,因此,我们在使用时,可以直接通过“accelerometer.getx()”/“accelerometer.gety()”/“accelerometer.getz()”指令来获取各自方向的加速度值。当然,在这之前,我们需要先导入Pinpong库相关的文件并初始化板子。

  1. from pinpong.board import Board # 从pinpong.board包中导入Board模块
  2. from pinpong.extension.unihiker import * # 导入pinpong.extension.unihiker包中所有模块
  3. Board().begin() # 初始化,选择板型和端口号,不输入则进行自动识别
  4.      x = accelerometer.get_x() # 获取x轴加速度值
  5.      y = accelerometer.get_y() # 获取y轴加速度值
  6. 其中,x和y是一个变量,分别用来存储检测到的x和y轴方向的加速度值。
复制代码

3、turtle库屏幕控制的常见函数

turtle库中关于屏幕控制的函数有很多,我们只使用其中的一部分,编程时,通过“import turtle”导入库后可采用“turtle.函数名()”的形式来实现功能。

(1)bgpic()函数设置绘图窗口(画布)的背景颜色

通过bgpic()函数我们可为当前的窗口屏幕设置背景颜色。

  1. turtle.bgcolor("pink") # 设置窗口背景颜色
复制代码

其中,“pink”指的是粉红色。这里的颜色同样可以通过RGB值、十六进制值、固定值三种不同的方式来表示。

(2)clear()函数清空窗口

通过clear()函数我们可以将窗口上的内容清空掉。

  1. turtle.clear() # 清空窗口
复制代码

4、turtle库画笔运动的常见函数

(1)setheading()函数设置画笔当前的朝向

通过setheading()函数我们可使画笔朝向任何方位。0°表示正东方向,90°表示正北方向,180°/-180°表示正西方向,270°/-90°表示正南方向。

【行空板Python入门教程】第5课时:2D迷宫图7

  1. turtle.setheading(90) # 设置画笔的朝向为90°方向
复制代码

其中,“90”指的是具体要指向的方位角度。可通过改变方位角度值来改变画笔的朝向。

(2)write()函数书写文字

通过write()函数我们可以使画笔在窗口屏幕上书写文字。

  1. turtle.write('you win!',,font = ('微软雅黑', 30)) # 书写“you win!”
复制代码

其中,“you win!”指的是具体要写入的文字内容,align指的是对齐方式,“center”表示中心对齐,font指的是字体,这里为大小30的微软雅黑字体。

动手实践

任务描述1:绘制迷宫

在屏幕上绘制一幅盘根错节的迷宫图。

1、硬件搭建

STEP1:通过USB连接线将行空板连接到计算机

2、程序编写

STEP1:创建与保存项目文件

启动Mind+,另存项目并命名为“005、2D迷宫”。

STEP2:创建与保存Python文件

创建一个Python程序文件“protract.py”,双击打开。

STEP3:程序编写1

在这个任务中,我们将绘制一幅迷宫图,由于迷宫图的绘制过程比较复杂,因此,我们将其单独编写在protract程序文件中,以便在后续直接调用。

(1) 导入所需功能库

这里,我们需要使用turtle库来绘制迷宫,因此,我们需要先导入它。

  1. import turtle # 导入turtle库
复制代码

(2) 创建图形窗口

为了能使迷宫显示在屏幕上,我们需要先创建一个和屏幕大小一致的图形窗口,而后在图形窗口中创建一块画布,设置好相应的大小尺寸和背景颜色,并设置屏幕延迟为0,避免卡顿。

  1. turtle.setup(240, 320) # 设置图像窗口大小
  2. turtle.bgcolor("pink") # 设置窗口背景颜色
  3. turtle.delay(0) # 屏幕延迟
复制代码

(3) 设计迷宫路线方案

对于迷宫图的绘制,我们分两步进行。首先,我们设定一个宽和高都为20像素的小方格作为一堵墙,之后,以此小方格为一个单位来设定整体的迷宫,由于屏幕的宽为240像素,高为320像素,在横向上,我们可绘制13个方格(屏幕显示为11个整块方格+2边各一个半块方格),而在纵向上,我们也够绘制13个方格。

这里,我们以“0”和“1”来表示小方格的有无,并通过列表嵌套的形式来表示迷宫的路线。

  1. # 迷宫列表
  2. maze_list = [
  3.    [0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0], # 第0行
  4.    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], # 第1行
  5.    [0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0], # 第2行
  6.    [0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0], # 第3行
  7.    [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0], # 第4行
  8.    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], # 第5行
  9.    [0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0], # 第6行
  10.    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], # 第7行
  11.    [0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0], # 第8行
  12.    [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0], # 第9行
  13.    [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0], # 第10行
  14.    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], # 第11行
  15.    [0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0], # 第12行
  16. ]
复制代码

(4) 创建迷宫类并在类中设定绘图的基本属性

在实际编程时,我们先创建一个迷宫类,之后再通过类的实例化来创建迷宫对象,在迷宫类中,我们首先需要定义一个方格的尺寸,并设置绘图的一些基本属性。

  1. class Maze(turtle.Turtle): # 定义Maze类
  2.     size = 20    #设定迷宫内一格墙的边宽尺寸为20像素
  3.     def __init__(self, maze_list):
  4.         # 所有类都有一个名为 __init__() 的函数,它始终在启动类时执行
  5.         # __init__方法是专门用来定义一个类具有哪些属性的方法
  6.         # 需要先调用父类的初始化方法才能在初始化方法中调用父类的方法
  7.         turtle.Turtle.__init__(self) # 解绑Maze类中的方法,使其也拥有Turtle类中的方法
  8.         self.maze_list = maze_list # 设置迷宫列表
  9.         # 为了加快绘图速度隐藏海龟,速度设为最快
  10.         self.hideturtle() # 隐藏海龟画笔
  11.         self.speed(0) # 设置海龟移动(绘图)速度为最快
  12.         self.draw_walls() # 绘制整个迷宫
复制代码

(5) 在迷宫类中创建绘制单个方格的函数

之后,我们还需要在类中定义一个绘制单个方格的函数以便在绘制整体迷宫时调用。

  1. # 绘制迷宫内一格墙的过程
  2.     def draw_wall(self):
  3.         self.pendown() # 落笔
  4.         self.begin_fill() # 填充
  5.         self.fillcolor('red') #设置填充颜色为红
  6.         # 首先画一个距离为20的横线,再向右旋转90度,循环4次形成正方形
  7.         for i in range(4):
  8.             self.forward(20) # 前进20像素
  9.             self.right(90) # 右旋转90度
  10.         self.end_fill() # 结束填充
  11.         self.penup() # 抬起画笔
复制代码

(6) 在迷宫类中创建绘制整体迷宫的函数

这里,我们可通过调用绘制单个方格的函数并结合线路来绘制整体的迷宫。

  1. # 绘制整个迷宫的墙
  2.     def draw_walls(self):
  3.         self.penup() # 抬起画笔
  4.         self.goto(-120, 120) # 走到初始位置
  5.         # 绘制墙体,循环嵌套,横纵各重复13次(整个迷宫的长和宽由13格墙组成)
  6.         for row in range(13): # 行循环
  7.             for col in range(13): # 列循环
  8.                 # 主函数中的maze_list里面的1则打印出一格墙
  9.                 if self.maze_list[row][col] == 1: # 如果迷宫列表中的某行某列为1
  10.                     self.draw_wall() # 画单堵墙         
  11.                 self.goto(20 * (col + 1) - 130, 130 - 20 * row) # 右移一列
  12.             self.goto(-130, 130 - 20 * (row + 1)) # 下移一行
复制代码

Tips:完整protract示例程序如下:

  1. import turtle # 导入turtle库
  2. turtle.setup(240, 320) # 设置图像窗口大小
  3. turtle.bgcolor("pink") # 设置窗口背景颜色
  4. turtle.delay(0) # 屏幕延迟,设为0避免卡顿
  5. # turtle.tracer(0) # turns off screen updates
  6. # turtle.delay(0) # there's a 10-millisecond pause whenever the turtle moves if the delay is not turned off.
  7. # turtle.tracer(0, 0)
  8. # 迷宫列表
  9. maze_list = [
  10.    [0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0], # 第0行
  11.    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], # 第1行
  12.    [0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0], # 第2行
  13.    [0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0], # 第3行
  14.    [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0], # 第4行
  15.    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], # 第5行
  16.    [0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0], # 第6行
  17.    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], # 第7行
  18.    [0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0], # 第8行
  19.    [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0], # 第9行
  20.    [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0], # 第10行
  21.    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], # 第11行
  22.    [0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0], # 第12行
  23. ]
  24. class Maze(turtle.Turtle): # 定义Maze类
  25.     size = 20    #设定迷宫内一格墙的边宽尺寸为20像素
  26.     def __init__(self, maze_list):
  27.         # 所有类都有一个名为 __init__() 的函数,它始终在启动类时执
  28.         # __init__方法是专门用来定义一个类具有哪些属性的方法
  29.         # 需要先调用父类的初始化方法才能在初始化方法中调用父类的方法
  30.         turtle.Turtle.__init__(self) # 解绑Maze类中的方法,使其也拥有Turtle类中的方法
  31.         self.maze_list = maze_list # 设置迷宫列表
  32.         # 为了加快绘图速度隐藏海龟,速度设为最快
  33.         self.hideturtle() # 隐藏海龟画笔
  34.         self.speed(0) # 设置海龟移动(绘图)速度为最快
  35.         self.draw_walls() # 绘制整个迷宫
  36.     # 绘制迷宫内一格墙的过程
  37.     def draw_wall(self):
  38.         self.pendown() # 落笔
  39.         self.begin_fill() # 填充
  40.         self.fillcolor('red') #设置填充颜色为红
  41.         # 首先画一个距离为20的横线,再向右旋转90度,循环4次形成正方形
  42.         for i in range(4):
  43.             self.forward(20) # 前进20像素
  44.             self.right(90) # 右旋转90度
  45.         self.end_fill() # 结束填充
  46.         self.penup() # 抬起画笔
  47.     # 绘制整个迷宫的墙
  48.     def draw_walls(self):
  49.         self.penup() # 抬起画笔
  50.         self.goto(-120, 120) # 走到初始位置
  51.         # 绘制墙体,循环嵌套,横纵各重复13次(整个迷宫的长和宽由13格墙组成)
  52.         for row in range(13): # 行循环
  53.             for col in range(13): # 列循环
  54.                 # 主函数中的maze_list里面的1则打印出一格墙
  55.                 if self.maze_list[row][col] == 1: # 如果迷宫列表中的某行某列为1
  56.                     self.draw_wall() # 画单堵墙         
  57.                 self.goto(20 * (col + 1) - 130, 130 - 20 * row) # 右移一列
  58.             self.goto(-130, 130 - 20 * (row + 1)) # 下移一行
复制代码

STEP4:程序编写2

在上述“protract”程序中,我们只是创建了一个迷宫类,但无法直接看到效果,因此,接下来,我们再创建一个“main1.py”Python 文件,双击打开编写程序,观察绘制的迷宫效果。

(1)导入所需文件

在这个任务中,为了能创建迷宫对象并保持窗口界面,我们需要导入刚才编写的protract程序文件和turtle库文件。

  1. import turtle # 导入turtle库
  2. import protract # 导入protract模块
复制代码

(2)生成迷宫对象并结束绘图

最后,我们通过类的实例化来生成迷宫对象,并结束绘图保持窗口。

  1. protract.Maze(protract.maze_list) # 实例化Maze类,创建迷宫对象
  2. turtle.done() # 结束绘图,保持窗口
复制代码

Tips:完整示例程序如下:

  1. import turtle # 导入turtle库
  2. import protract # 导入protract模块
  3. protract.Maze(protract.maze_list) # 实例化Maze类,创建迷宫对象
  4. turtle.done() # 结束绘图,保持窗口
复制代码

3、程序运行

STEP1:连接板子

STEP2:点击右上方的运行按钮,运行“main1.py”程序

STEP3:观察效果

观察行空板,可以看到首先出现了一个粉红的背景,之后一个个红色的小方块从左上角开始依次出现,最终拼合在一起,形成了一幅错综复杂的迷宫。

【行空板Python入门教程】第5课时:2D迷宫图8

任务描述2:检测加速度值

在上个任务中,我们完成了迷宫图的绘制,而为了能够通过加速度值来控制角色在迷宫上移动,接下来,我们需要先检测一下加速度值在各个不同方向上的变化情况。

1、程序编写

STEP1:创建与保存项目文件

新建一个Python程序文件“main2.py”,双击打开。

Step2:程序编写

(1)导入所需功能库

由于我们将在屏幕上显示加速度值,因此,我们需要先导入unihiker库和time时间库。同时,为了能够检测加速度,我们还需导入Pinpong相关库并初始化行空板。

  1. from unihiker import GUI  # 导入unihiker库
  2. import time  # 导入time库
  3. from pinpong.board import Board # 从pinpong.board包中导入Board模块
  4. from pinpong.extension.unihiker import * # 导入pinpong.extension.unihiker包中所有模块
  5. Board().begin() # 初始化,选择板型和端口号,不输入端口号则进行自动识别
复制代码

(2)实例化GUI类并在屏幕上显示初始的x、y轴方向上的加速度值
在显示初始加速度值时,我们可以不输入数值,表示为空。

  1. gui = GUI()  # 实例化GUI类,创建gui对象
  2. value_1 = gui.draw_text(x=65, y=65, text='x轴加速度值:', font_size=13) #显示文字
  3. value_2 =gui.draw_text(x=65, y=178, text='y轴加速度值:', font_size=13)#显示文字
  4. value_x = gui.draw_text(x=85, y=122, text='', font_size=13) # 显示初始x轴加速度值
  5. value_y = gui.draw_text(x=85, y=240, text='', font_size=13) #显示初始y轴加速度值
复制代码

(3)循环检测加速度值并更新数值

接下来,我们每隔1秒不停得检测x和y轴方向上的加速度值,并实时更新显示在屏幕上。

  1. while True:
  2.     x = accelerometer.get_x() # 获取x轴加速度值
  3.     y = accelerometer.get_y() # 获取y轴加速度值
  4.     value_x.config(text = x) # 更新显示x轴加速度值
  5.     value_y.config(text = y) # 更新显示y轴加速度值
  6.     time.sleep(1)
  7.     print(x,y)
复制代码

Tips:完整示例程序如下:

  1. from unihiker import GUI  # 导入unihiker库
  2. import time  # 导入time库
  3. from pinpong.board import Board # 从pinpong.board包中导入Board模块
  4. from pinpong.extension.unihiker import * # 导入pinpong.extension.unihiker包中所有模块
  5. Board().begin() # 初始化,选择板型和端口号,不输入则进行自动识别
  6. gui = GUI()  # 实例化GUI类,创建gui对象
  7. value_1 = gui.draw_text(x=65, y=65, text='x轴加速度值:', font_size=13) # 显示文字
  8. value_2 = gui.draw_text(x=65, y=178, text='y轴加速度值:', font_size=13) # 显示文字
  9. value_x = gui.draw_text(x=85, y=122, text='', font_size=13) # 显示初始x轴加速度值
  10. value_y = gui.draw_text(x=85, y=240, text='', font_size=13) # 显示初始y轴加速度值
  11. while True:
  12.     x = accelerometer.get_x() # 获取x轴加速度值
  13.     y = accelerometer.get_y() # 获取y轴加速度值
  14.     value_x.config(text = x) # 更新显示x轴加速度值
  15.     value_y.config(text = y) # 更新显示y轴加速度值
  16.     time.sleep(1)
  17.     print(x,y)
复制代码

2、程序运行

STEP1:连接板子

STEP2:运行程序并观察效果

点击运行后,将行空板由水平放置状态往四个不同的方向倾斜。由于板子静止时只受到一个重力加速度,而重力加速度始终朝向地面,因此,可以看到当板子向下倾斜时,x轴方向上的加速度值不断增大,垂直时数值在1左右;当板子向上倾斜时,x轴方向上的加速度值不断减小,垂直时数值在-1左右;当板子向左倾斜时,y轴方向上的加速度值不断增大,垂直时数值在1左右;当板子向右倾斜时,y轴方向上的加速度值不断减小,垂直时数值在-1左右;

【行空板Python入门教程】第5课时:2D迷宫图9【行空板Python入门教程】第5课时:2D迷宫图10


【行空板Python入门教程】第5课时:2D迷宫图11

任务描述3:走迷宫

接下来,我们将把绘制的迷宫图和加速度检测结合起来,通过加速度的不同方位来控制角色走迷宫。

1、程序编写

STEP1:创建与保存项目文件

新建一个Python程序文件“main3.py”,双击打开。

Step2:程序编写

(1)导入所需功能库

在这个任务中,我们将在绘制的迷宫图上创建一个海龟角色作为玩家,并通过板载三轴加速度计来控制它移动,因此我们需要先导入turtle库,绘制迷宫的protract程序文件,time时间库以及Pinpong库,并初始化行空板。

  1. import turtle # 导入turtle库
  2. import time # 导入time库
  3. import protract # 导入绘制迷宫文件
  4. from pinpong.board import Board # 导入pinpong.board包中Board模块
  5. from pinpong.extension.unihiker import * # 导入pinpong.extension.unihiker包中所有模块
  6. Board().begin() # 初始化,选择板型和端口号,不输入端口号则进行自动识别
复制代码

(2)绘制迷宫
由于我们的游戏是在迷宫上进行,因此,我们需要先实例化上个任务protract程序文件中创建的“Maze“类来生成一个迷宫对象。

  1. protract.Maze(protract.maze_list) # 实例化Maze类,创建迷宫对象
复制代码

(3)创建玩家类,并在类中设置玩家的基本属性与功能

对于迷宫图上的玩家角色,我们通过先创建玩家类再实例化的方式来生成玩家对象。

同时,在创建的玩家类中,我们需要设置玩家的一些基本属性及功能。

这里,我们设置好玩家初始位置和终点位置,设置玩家角色所在的地图为迷宫地图,设置移动速度为最快,并使玩家在移动到迷宫的起点后以海龟的形态显示在屏幕上,同时,设置海龟玩家的颜色和初始朝向。

  1. class Player(turtle.Turtle): # 创建玩家类
  2.     def __init__(self, maze_list, start_m, start_n, end_m, end_n):
  3.         turtle.Turtle.__init__(self) # 父类初始化
  4.         self.m = start_m # 设定起点的行数
  5.         self.n = start_n # 设定起点的列数
  6.       
  7.         self.end_m = end_m # 设定终点的行数
  8.         self.end_n = end_n # 设定终点的列数
  9.       
  10.         self.maze_list = maze_list # 设定迷宫列表
  11.         self.hideturtle() # 隐藏海龟画笔
  12.         self.speed(0) # 设置海龟移动(绘图)速度为最快
  13.         self.penup() # 抬起画笔   
  14.         self.goto(self.n * 20 - 120, 120 - self.m * 20) # 玩家移到对应的位置   
  15.         self.shape('turtle') # 设置玩家形态为海龟
  16.         self.color('yellow') # 设置玩家颜色为yellow
  17.       
  18.         self.setheading(270) # 设置玩家初始方向
  19.         self.showturtle() # 显示玩家
复制代码

(4)在玩家类中设定可移动范围
由于游戏机制,我们需要设定玩家只能在迷宫内的通道里移动。

  1. def canmove(self, m, n): # 定义玩家可移动的位置,即只允许在迷宫内的通道里移动
  2.         if 0 <= m and m <= 12: # 如果在第0行到第12行之内
  3.             print(m,n) # 打印
  4.             return self.maze_list[m][n] == 0 # 返回值0,表示第m行第n列没有墙,可以移动
复制代码

(5)在玩家类中创设定移动时位置的变化
在玩家可移动后,我们需要设定移动时位置发生的变化。

  1. def move(self, m, n): # 定义玩家的移动
  2.         self.m = m # 定义行数
  3.         self.n = n # 定义列数
  4.         self.goto(self.n * 20 - 120, 120 - self.m * 20) # 移动到该位置
  5.         self.reach_exit(m, n) # 判断是否到达终端
复制代码

(6)在玩家类中设定不同方向的移动

之后,我们还需要设定玩家在四个方向上的移动。

  1. def go_up(self): # 向上移动
  2.         if self.canmove(self.m - 1, self.n): # 如果向上可移动
  3.             self.setheading(90) # 设置朝向
  4.             self.move(self.m - 1, self.n) # 设置向上移动
  5.     def go_down(self): # 向下移动
  6.         if self.canmove(self.m + 1, self.n): # 如果向下可移动
  7.             self.setheading(270) # 设置朝向
  8.             self.move(self.m + 1, self.n) # 设置向下移动
  9.     def go_left(self): # 向左移动
  10.         if self.canmove(self.m, self.n - 1): # 如果向左可移动
  11.             self.setheading(180) # 设置朝向
  12.             self.move(self.m, self.n - 1) # 设置向左移动
  13.     def go_right(self): # 向右移动
  14.         if self.canmove(self.m, self.n + 1): # 如果向右可移动
  15.             self.setheading(0) # 设置朝向
  16.             self.move(self.m, self.n + 1) # 设置向右移动
复制代码

(7)在玩家类中设定终点的判别
当玩家的横纵坐标和终点坐标点一致时,我们判定游戏结束,并在屏幕上显示获胜的信息,同时,使游戏重新开始。

  1. def reach_exit(self, m, n): # 判断是否到达终端,当玩家到达终点时,显示'you win!'
  2.         if m == self.end_m and n == self.end_n: # 如果移动到终点
  3.             text = turtle.Turtle() # 创建文字对象
  4.             text.hideturtle() # 隐藏画笔
  5.             text.penup() # 抬起画笔
  6.             text.goto(0,0) # 移动到原点
  7.             text.color('blue') # 设定颜色为blue
  8.             text.write('you win!',align="center",font = ('微软雅黑', 30)) # 书写“you win!”
  9.             time.sleep(2) # 延时两秒
  10.             text.clear() # 清空
  11.             self.restart() # 重新开始游戏
复制代码

(8)在玩家类中设定重新开始机制

在到达终点后,我们使玩家再次回到初始位置。

  1. def restart(self): # 重新开始游戏
  2.         self.goto(-20, 120) # 移动到(-20,120)坐标点位
  3.         self.m = 0 # 起点的行数
  4.         self.n = 5 # 起点的列数
  5.         self.end_m = 12 # 终点的行数
  6.         self.end_n = 5 # 终点的列数
复制代码

(9)生成玩家

之后,我们通过实例化类来生成一个玩家角色。

  1. player = Player(protract.maze_list, 0, 5, 12, 5) # 实例化Player类,创建一个玩家对象
复制代码

(10)设定陀螺仪标志值

为了能够在后续通过x轴和y轴上的加速度值来判定方位,我们需要提前设定一个用以比较的参考标志值。这里,经过上述任务2的读取检测,我们选取“0.4”作为标志值。

  1. thread_value = 0.4 # 定义一个标志值
复制代码

(11)循环读取加速度值并进行检测

最后,我们使用永久循环的方式持续获取陀螺仪x轴和y轴加速度的值,并以此与标志值进行比较,继而判定移动的方向。

  1. while True:
  2.     x = accelerometer.get_x() # 获取x轴加速度值
  3.     y = accelerometer.get_y() # 获取y轴加速度值
  4.     time.sleep(0.15)
  5.     if x > thread_value : # 如果x轴加速度值 > 阈值
  6.         player.go_down() # 向下移动
  7.         time.sleep(0.1)
  8.     if x < -thread_value: # 如果x轴加速度值 < 阈值
  9.         player.go_up() # 向上移动
  10.         time.sleep(0.1)
  11.     if y > thread_value : # 如果y轴加速度值 > 阈值
  12.         player.go_left() # 向左移动
  13.         time.sleep(0.1)
  14.     if y < -thread_value : # 如果y轴加速度值 < 阈值
  15.         player.go_right() # 向右移动
  16.         time.sleep(0.1)
复制代码

Tips:完整示例程序如下:

  1. import turtle # 导入turtle库
  2. import time # 导入time库
  3. import protract # 导入protract模块
  4. from pinpong.board import Board # 导入pinpong.board包中Board模块
  5. from pinpong.extension.unihiker import * # 导入pinpong.extension.unihiker包中所有模块
  6. Board().begin() # 初始化,选择板型和端口号,不输入则进行自动识别
  7. thread_value = 0.4 # 定义一个标志值
  8. protract.Maze(protract.maze_list) # 实例化Maze类,创建迷宫对象
  9. class Player(turtle.Turtle): # 创建玩家类
  10.     def __init__(self, maze_list, start_m, start_n, end_m, end_n):
  11.         turtle.Turtle.__init__(self) # 父类初始化
  12.         self.m = start_m # 设定起点的行数
  13.         self.n = start_n # 设定起点的列数
  14.         self.end_m = end_m # 设定终点的行数
  15.         self.end_n = end_n # 设定终点的列数
  16.         self.maze_list = maze_list # 设定迷宫列表
  17.         self.hideturtle() # 隐藏海龟画笔
  18.         self.speed(0) # 设置海龟移动(绘图)速度为最快
  19.         self.penup() # 抬起画笔
  20.         self.goto(self.n * 20 - 120, 120 - self.m * 20) # 玩家移到对应的位置   
  21.         self.shape('turtle') # 设置玩家形态为海龟
  22.         self.color('yellow') # 设置玩家颜色为yellow
  23.         self.setheading(270) # 设置玩家初始方向
  24.         self.showturtle() # 显示玩家
  25.     def canmove(self, m, n): # 定义玩家可移动的位置,即只允许在迷宫内的通道里移动
  26.         if 0 <= m and m <= 12: # 如果在第0行到第12行之内
  27.             print(m,n) # 打印
  28.             return self.maze_list[m][n] == 0 # 返回值0,表示第m行第n列没有墙,可以移动
  29.     def move(self, m, n): # 定义玩家的移动
  30.         self.m = m # 定义行数
  31.         self.n = n # 定义列数
  32.         self.goto(self.n * 20 - 120, 120 - self.m * 20) # 移动到该位置
  33.         self.reach_exit(m, n) # 判断是否到达终端
  34.     def go_up(self): # 向上移动
  35.         if self.canmove(self.m - 1, self.n): # 如果向上可移动
  36.             self.setheading(90) # 设置朝向
  37.             self.move(self.m - 1, self.n) # 设置向上移动
  38.     def go_down(self): # 向下移动
  39.         if self.canmove(self.m + 1, self.n): # 如果向下可移动
  40.             self.setheading(270) # 设置朝向
  41.             self.move(self.m + 1, self.n) # 设置向下移动
  42.     def go_left(self): # 向左移动
  43.         if self.canmove(self.m, self.n - 1): # 如果向左可移动
  44.             self.setheading(180) # 设置朝向
  45.             self.move(self.m, self.n - 1) # 设置向左移动
  46.     def go_right(self): # 向右移动
  47.         if self.canmove(self.m, self.n + 1): # 如果向右可移动
  48.             self.setheading(0) # 设置朝向
  49.             self.move(self.m, self.n + 1) # 设置向右移动
  50.     def reach_exit(self, m, n): # 判断是否到达终端,当玩家到达终点时,显示'you win!'
  51.         if m == self.end_m and n == self.end_n: # 如果移动到终点
  52.             text = turtle.Turtle() # 创建文字对象
  53.             text.hideturtle() # 隐藏画笔
  54.             text.penup() # 抬起画笔
  55.             text.goto(0,0) # 移动到原点
  56.             text.color('blue') # 设定颜色为blue
  57.             text.write('you win!',align="center",font = ('微软雅黑', 30)) # 书写“you win!”
  58.             time.sleep(2) # 延时两秒
  59.             text.clear() # 清空
  60.             self.restart() # 重新开始游戏
  61.     def restart(self): # 重新开始游戏
  62.         self.goto(-20, 120) # 移动到(-20,120)坐标点位
  63.         self.m = 0 # 起点的行数
  64.         self.n = 5 # 起点的列数
  65.         self.end_m = 12 # 终点的行数
  66.         self.end_n = 5 # 终点的列数
  67. player = Player(protract.maze_list, 0, 5, 12, 5) # 实例化Player类,创建一个玩家对象
  68. while True:
  69.     x = accelerometer.get_x() # 获取x轴加速度值
  70.     y = accelerometer.get_y() # 获取y轴加速度值
  71.     time.sleep(0.15)
  72.     if x > thread_value : # 如果x轴加速度值 > 阈值
  73.         player.go_down() # 向下移动
  74.         time.sleep(0.1)
  75.     if x < -thread_value: # 如果x轴加速度值 < 阈值
  76.         player.go_up() # 向上移动
  77.         time.sleep(0.1)
  78.     if y > thread_value : # 如果y轴加速度值 > 阈值
  79.         player.go_left() # 向左移动
  80.         time.sleep(0.1)
  81.     if y < -thread_value : # 如果y轴加速度值 < 阈值
  82.         player.go_right() # 向右移动
  83.         time.sleep(0.1)
复制代码

2、程序运行

STEP1:连接板子

STEP2:运行程序并观察效果

点击运行后,观察行空板,我们发现屏幕上先绘制出一个迷宫,随后一个小海龟出现在迷宫的出口,之后我们就可以通过转动行空板来控制小海龟走迷宫啦!


挑战自我


尝试更换迷宫线路列表中的“0、1“,来自己设计一个迷宫,游戏一番吧!
了解更多!

szjuliet  版主

发表于 2022-5-20 23:31:42

Mind+这个“项目文件”的设计真的好!可以把需要的文件全部包含在一个项目里,python教学太方便了。
回复

使用道具 举报

 初级技匠

发表于 2022-6-9 14:52:49

这个迷宫不错
就是代码有点多
回复

使用道具 举报

 初级技匠

发表于 2022-8-18 12:10:43

可以用这个做iwanna
回复

使用道具 举报

_深蓝_  高级技师

发表于 2023-9-13 16:42:19

不错,值得试一试,没有图片更好做。
回复

使用道具 举报

手机连接万物  高级技师

发表于 2023-12-5 15:44:02

牛,学习了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail