用Python控制Codey Rocky
通过使用Python操控舞台角色,您可以:
- 和实物结合,更有趣地学习Python
- 比拖放语句块更方便地编写有一定规模的代码,比如实现算法
- 使用积木式编程很难做到的事情,比如使用字典等数据结构
为Codey写的Python程序,一定要上传到Codey之后才能生效。
开始使用Python
通过将和脚本区上方的编程方式从“语句块”切换成“Python”即可开始编写Python。 (插入图片)
注意:请确保标签选中的是“设备”,角色选择的是Codey。 (插入图片)
下面是一段简单的示例代码: (注意这里使用了import *, pendown()实际上实现了sprite.pendown()的功能)
from codey import *
from rocky import *
color("red")
for i in range(5):
rocky.forward(50, 1)
rocky.right(50, 1)
代码编写完成之后,点击“运行”,编写的Python代码就会执行。 (插入图片)
将积木块转换为Python
(插入图片)
在表情面板(点阵)上显示内容
show(文字内容)
将文字内容显示在Codey的表情面板上
codey.show("hello world")
codey.show(3.14)
codey.show("14:02")
face(点阵像素内容, 时间=0)
将一个点阵图案显示在Codey的表情面板上 如果时间不为0, 则显示相应时间后点阵熄灭.
codey.face(
'0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'
'0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0'
'0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0'
'0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0'
'0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0'
'0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0'
'0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0'
'0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0')
face_at(点阵像素内容, x, y)
在指定的x, y坐标处显示点阵内容
codey.face_at(
'0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'
'0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0'
'0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0'
'0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0'
'0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0'
'0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0'
'0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0'
'0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0', 0, 0) # 在屏幕的左上角显示一个笑脸
pixel(x, y) / pixel_off(x, y) / pixel_toggle(x, y)
- pixel: 点亮点阵上某个位置(x, y)的像素
- pixel_off: 点灭点阵上某个位置(x, y)的像素
- pixel_toggle: 反转某个位置(x, y)的像素:如果是灭的则点亮,如果是亮的则点灭
codey.pixel(5, 5) # 点亮坐标为(5, 5)处的像素
codey.pixel_off(5, 5) # 点灭坐标为(5, 5)处的像素
codey.pixel_toggle(5, 5) # 将(5, 5)处的像素反转。现在是灭的,所以结果会是亮的
【有改动】has_pixel(x, y)
检查Codey的指定像素处是否点亮
如果点亮则返回True, 反之False
print(codey.has_pixel(5, 5)) # 如果已经点亮,输出True
clear()
清空表情面板上所有的显示内容
codey.clear() # 熄灭表情面板
使用Codey的指示灯
color(颜色, 时间=0)
将Codey指示灯设置为指定颜色。
如果“时间”参数不为0,则在指定秒数后熄灭。
codey.color('#334455', 1) # 设置颜色,在1秒后熄灭
codey.color('#ff0000') # 设置指示灯为红色,不熄灭
color_off()
熄灭Codey的指示灯
codey.color_off() # 熄灭指示灯
red(数值) / green(数值) / blue(数值)
独立设置Codey指示灯的红绿蓝数值
取值范围为 0-255
codey.red(255)
codey.green(255)
codey.blue(255)
让Codey发出声音
【有改动】play(声音名称)
播放Codey内存储的声音文件名称
codey.play("cat")
codey.play("cat.wav") # 是否带.wav,效果是一样的
可选参数
hello.wav
: 哈喽hi.wav
: 嗨bye.wav
: 拜yeah.wav
: 耶wow.wav
: 哇哦laugh.wav
: 笑声hum.wav
: 哼唱sad.wav
: 难过sigh.wav
: 叹气annoyed.wav
: 哼!angry.wav
: 生气surprised.wav
: 惊吓yummy.wav
: 撒娇curious.wav
: 好奇embarrassed.wav
: 尴尬ready.wav
: 准备sprint.wav
: 冲刺sleepy.wav
: 打呼meow.wav
: 喵start.wav
: 启动switch.wav
: 开关beeps.wav
: 哔哔buzzing.wav
: 蜂鸣exhaust.wav
: 排气explosion.wav
: 爆炸gotcha.wav
: 获取hurt.wav
: 痛苦jump.wav
: 跳动laser.wav
: 激光level up.wav
: 升级low energy.wav
: 低能量metal clash.wav
: 金属音prompt tone.wav
: 提示right.wav
: 正确wrong.wav
: 错误ring.wav
: 铃声score.wav
: 得分shot.wav
: 发射step_1.wav
: 脚步声1step_2.wav
: 脚步声2wake.wav
: 激活warning.wav
: 警告
play_note(音符编号, 拍数) / 【待实现】play_note(音符名称, 拍数)
让Codey播放一个音符,持续指定拍数
音符编号指音符的Midi编号
也可以使用"c3"(第三级do), "d4"(第四级re)这样的音符名称。不正确的音符名称会报错
codey.play_note(36, 1)
codey.play_note('c3', 0.25)
play_freq(频率, 拍数)
让Codey播放指定频率的音调,持续一定拍数
codey.play_freq(700, 1)
pause(拍数)
让Codey暂停播放指定拍数,相当于音乐中的休止符
codey.pause(0.25)
mute()
让Codey停止播放一切声音
codey.mute()
设置音量:set_volume(音量大小)
设置Codey的音量大小
codey.set_volume(100) # 将Codey的音量设置为100
【有改动】获得音量:volume()
获得现在Codey的音量大小
print(codey.volume()) # 输出现在的音量大小
【有改动】改变音量:change_volume_by(音量变化)
将Codey的音量增加(改变)一定数值
codey.change_volume_by(-10) # 将音量减小10
使用Codey的内置传感器
【有改动】button_pressed(按钮名称)
如果指定按钮被按下,返回True; 否则返回False
注意按钮名称是大写的"A", "B", "C"
print(codey.button_pressed("A")) # 当按钮A被按下时输出True
dail()
获得齿轮电位器的位置。范围是0-100
print(codey.dail()) # 输出现在电位器的0-100的位置
【有改动】loudness()
获得声音传感器感受到环境音量的大小。范围是0-100
print(codey.loudness()) # 输出现在环境音量的大小
【有改动】lightness()
获得Codey光线传感器的数值。范围是0-100
数字越大环境光越亮
print(codey.lightness()) # 输出现在环境光线强度
is_shaked()
获得Codey当前是否被摇晃。结果是True或者False
print(codey.is_shaked()) # 如果Codey正在被摇晃,输出True
【有改动】is_tilted(倾斜方向)
获得Codey当前是否向某个方向倾斜。结果是True或者False
“倾斜方向”可以是"forward", "backward", "left", "right"之一
print(codey.is_tilted("forward")) # 如果Codey正在向前倾斜,输出True
【有改动】is_placed(放置方向)
获得Codey是否被放置到某个方向。结果是True或者False
“放置方向”可以是"screen_up"(屏幕朝上), "screen_down"(屏幕朝下), "up_right"(直立)之一
print(codey.is_placed("up_right")) # 如果Codey被直立放置,输出True
【有改动】陀螺仪:gyro
可以获得陀螺仪的偏转和俯仰角:
- gyro.pitch: 陀螺仪俯仰角
- gyro.yaw: 陀螺仪偏转角
可以使用gyro.rotation获得陀螺仪绕某一坐标轴旋转的角度:
- gyro.rotation.x: 绕x轴旋转角度
- gyro.rotation.y: 绕y轴旋转角度
- gyro.rotation.z: 绕z轴旋转角度
- gyro.rotation.reset(): 重置陀螺仪旋转角度
可以使用gyro.shake_strength获得陀螺仪被摇晃的强度(范围0-100)
print("俯仰和偏转角:", gyro.pitch, gyro.yaw) # 输出陀螺仪的俯仰和偏转角
print("陀螺仪绕3轴旋转角:", gyro.rotation.x, gyro.rotation.y, gyro.rotation.z)
gyro.rotation.reset() # 重置旋转角,现在gyro.rotation.x, gyro.rotation.y, gyro.rotation.z都是0了
print("摇晃力度:", gyro.shake_strength)
【有改动】计数器:time()
获得计数器的值(距启动或上次归零经过的秒数)
print(codey.time()) # 输出距启动或上次归零经过的秒数
【有改动】重置计数器:reset_time()
将计数器归零
codey.reset_time() # 先归零计数器
print(codey.time()) # 应该输出0
Codey的事件和执行控制
Codey支持事件(比如当按钮被按下)触发代码,也支持多线程
这是Codey和市面上其他机器人的主控的一个显著不同
如要使用事件,需要先定义一个事件处理函数,然后将它分配到相应的事件上
TODO: 一个程序最多同时执行N个事件
比如:
def button_a_pressed(): # 先定义一个函数,作为按钮A被按下的事件
print("A按钮被按下!")
codey.on_button('A', button_a_pressed) # 然后将该函数分配到“按钮A被按下”的事件中
按钮被按下:on_button(按钮名称, 处理函数名)
当按钮被按下时,调用处理函数
def button_a_pressed():
print("A按钮被按下!")
codey.on_button('A', button_a_pressed)
当摇晃小程:on_shake(处理函数名)
当按钮被按下时,调用处理函数
def when_shaked():
print("我被摇晃了!")
codey.on_shake('A', when_shaked)
当倾斜小程:on_tilt(倾斜方向, 处理函数名)
当小程被摇晃时,调用处理函数
“倾斜方向”可以是"forward", "backward", "left", "right"之一
def when_tilted_forward():
print("我被前倾了!")
codey.on_tilt('forward', when_tilted_forward)
当声音大于:on_sound_over(响度, 处理函数名)
当声音传感器的音量(loudness())大于特定数值时,触发处理函数
def when_sound_over_50():
print("音量大于50,太吵了!")
codey.on_sound_over(50, when_sound_over_50)
当光线小于:on_light_under(光线, 处理函数名)
当光线传感器的光线强度(lightness())小于特定数值时,触发处理函数
def when_light_under_30():
print("光线小于30,太暗了!")
codey.on_light_under(30, when_light_under_30)
当收到消息:on_message(消息名, 处理函数名)
当收到Scratch消息为指定名称的广播时,触发处理函数
def when_game_start():
print("游戏开始!")
codey.on_message('game_start', when_game_start)
广播消息:message(消息名)
向舞台和硬件角色广播某种消息
codey.message('game_start')
【有改动-暂未实现】stop_all() / stop_this() / stop_others()
停止全部脚本/(暂不实现)本角色(事件?)脚本/(暂不实现)其他角色脚本
sprite.stop_all() # 停止舞台上全部脚本
让Rocky动起来
forward(速度, 时间=0)
让Rocky以指定速度向前运动指定时间。如果时间为0则一直运动下去
速度的范围是0-100
rocky.forward(50, 1) # 以50的速度向前运动1秒
rocky.forward(100) # 以最高速度100一直前进下去,直到停止
back(速度, 时间=0)
让Rocky以指定速度向后运动指定时间。如果时间为0则一直运动下去
速度的范围是0-100
rocky.back(50)
rocky.back(100) # 以最高速度100一直后退下去,直到停止
right(速度, 时间=0)
让Rocky以指定速度右转指定时间。如果时间为0则一直运动下去
速度的范围是0-100
rocky.right(50, 1) # 以50的速度右转,持续1秒
rocky.right(100) # 以最高速度100一直向右旋转
left(速度, 时间=0)
让Rocky以指定速度左转指定时间。如果时间为0则一直运动下去
速度的范围是0-100
rocky.left(50, 1) # 以50的速度左转,持续1秒
rocky.left(100) # 以最高速度100一直向左旋转
right_angle(角度)
让Rocky右转指定角度,直到运动结束
rocky.right_angle(90) # 右转90度,直到完成
left_angle(角度)
让Rocky左转指定角度,直到运动结束
rocky.left_angle(90) # 左转90度,直到完成
drive(左轮动力, 右轮动力)
同时设置Rocky左轮和右轮的动力参数
rocky.drive(50, 50) # 将两个轮子的速度同时设为50
stop()
停止Rocky轮子的运动
rocky.stop() # 让Rocky的运动停止
使用Rokey底盘上的传感器和指示灯
【有改动】base_light(颜色, 时间=0)
设置底部传感器LED灯的颜色。
颜色只能在"red", "green", "blue", "yellow", "purple", "cyan", "white", "black"之中选。
rocky.base_light("red")
【有改动】base_light_off()
熄灭底盘上的LED灯
rocky.base_light_off()
is_obstacle_ahead()
得知前方是否有障碍物。结果是True或者False
(Rokey底盘传感器必须朝前)
print(rocky.is_obstacle_ahead()) #
【有改动】底盘传感器:base_sensor
使用rocky.base_sensor可以获得底盘传感器的一系列信息:
- base_sensor.lightness: 获得环境光强度,范围是0-100
- base_sensor.reflection: 获得反射光强度,范围是0-100
- base_sensor.ir_reflection: 获得红外线反射光强度,范围是0-100
- base_sensor.grey: 获得反射灰度值,范围是0-100
- base_sensor.red: 获得检测到的红色值,范围是0-255
- base_sensor.green: 获得检测到的绿色值,范围是0-255
- base_sensor.blue: 获得检测到的蓝色值,范围是0-255
- base_sensor.is_color(颜色名): 获取颜色传感器读到的颜色是否为指定颜色,返回True或False 其中颜色名需要是"red", "green", "blue", "yellow", "purple", "cyan", "white", "black"其中之一
print("环境和反射光: ", base_sensor.lightness, base_sensor.reflection)
print("红外反射光: ", base_sensor.ir_reflection)
print("灰度值: ", base_sensor.grey)
print("红绿蓝: ", base_sensor.red, base_sensor.green, base_sensor.blue )
print("是否为红色? ", base_sensor.is_color("red") )
使用红外通信
小程可以接收和发送红外信号
ir_send(字符串信息)
使用红外发射器发射一段字符串信息。另一台小程可以使用ir_receive接收这样的信息。
codey.ir_send("A")
ir_receive()
使用红外接收器接收一条红外线信息。会返回接收到的字符串数据
codey.show(codey.ir_receive())