用Python操控舞台角色
通过使用Python操控舞台角色,您可以:
- 在Scratch的基础上学习Python
- 比拖放语句块更方便地编写有一定规模的代码,比如实现算法
- 使用在Scratch很难做到的事情,比如使用字典等数据结构
在mBlock 5中,使用Python能达到和使用Scratch语句块一样的效果。
您可以控制舞台角色的运动、形象,还可以用它来绘图。
通过广播和跨角色变量,Python代码可以和其他角色的Python代码甚至Scratch语句块互动。
开始使用Python
通过将和脚本区上方的编程方式从“语句块”切换成“Python”即可开始编写Python。 (插入图片)
注意:请确保当前选中的是角色,而不是硬件设备 (插入图片)
下面是一段简单的示例代码:
from mblock import *
sprite.pencolor('red')
sprite.pendown()
for i in range(5):
sprite.forward(200)
sprite.right(144)
代码编写完成之后,点击“运行”,编写的Python代码就会执行。 (插入图片)
将积木块转换为Python
(插入图片)
移动精灵
前进:forward(距离)
让角色向前移动指定距离。方向为当前角色的朝向
sprite.forward(50)
后退:backward(距离)
让角色向后移动指定距离。方向为当前角色的朝向
sprite.backward(50)
右转:right(角度)
让角色右转指定角度(单位是度)
sprite.right(90)
左转:left(角度)
让角色左转指定角度(单位是度)
sprite.left(90)
方向:direction
可以使用direction来获取和设置角色朝向的角度
sprite.direction = 90 # 设置角色的朝向角度是90度
sprite.direction = sprite.direction + 10 # 让角色顺时针旋转10度
print(sprite.direction) # 这时应该输出100
towards(角色名)
让角色朝向指定的角色(用字符串表示的角色名)
sprite.towards("Panda")
sprite.towards('mouse') # 朝向鼠标指针
bounce()
如果角色碰到画面边缘则反弹(朝向反弹后的方向)
while True:
sprite.forward(50)
sprite.bounce()
rotation_mode(模式)
设置角色的旋转模式。模式(字符串或布尔值)可以为下列之一:
- 'left-right':角色图片只会左右翻转
- 'all-around'或者True:角色图片可以朝向任何角度
- 'none'或者False:角色图片只会保持原来的方向,不会旋转
sprite.rotation_mode('all-around')
位置和坐标
goto(x, y) | goto(地点名称)
让角色移动到屏幕上指定的x,y坐标(数字) 也可以使用下列字符串作为地点名称:
- "random": 移动到画面上随机位置
- "mouse": 移动到鼠标处
sprite.goto(30,60)
sprite.x # =30
sprite.setpos(0,0)
sprite.y # =0
sprite.goto("random") # 移动到随机位置
sprite.goto("mouse") # 移动到鼠标处
glide(x, y, 时间=5) | glide(地点名称, 时间=5)
让角色在时间内(默认5秒)滑动到屏幕上指定的x,y坐标 也可以使用下列字符串作为地点名称:
- "random": 移动到画面上随机位置
- "mouse": 移动到鼠标处
sprite.glide(30, 60, 5) # 在5秒内移动到(30, 60)坐标处
sprite.glide("random", 2) # 移动到随机位置, 耗时2秒
sprite.glide("mouse", 2) # 移动到鼠标处, 耗时2秒
角色坐标:x, y
可以获得和设置角色在舞台上的x, y坐标
sprite.x = 50 # 将角色的x坐标设为50
sprite.y = 60 # 将角色的y坐标设为60
sprite.y = sprite.y + 10 # 将角色y坐标增加10,就是向上移动10
print(sprite.x) # 输出角色x坐标(50)
print(sprite.y) # 输出角色y坐标(70)
改变角色的形象
say(文字, 时间=0)
让角色在屏幕上“说出”指定的文字 如果时间为0,则一直显示。否则指定时间后对话框消失
sprite.say("nice to meet you", 5)
sprite.say("hello world")
think(文字, 时间=0)
让角色在屏幕上“思考”指定的文字 如果时间为0,则一直显示。否则指定时间后对话框消失
sprite.think("nice to meet you", 5)
sprite.think("hello world")
hide()
隐藏角色
sprite.hide()
show()
显示角色
sprite.show()
set_costume(造型名称)
改变角色的造型,名称必须是该角色已经有的造型名称,否则没有效果
sprite.set_costume("Panda1")
next_costume()
将角色的造型切换为下一个造型
sprite.next_costume()
set_backdrop(背景名称)
改变舞台的背景,名称必须是项目中已有的背景名称,否则没有效果
sprite.set_backdrop("Party")
next_backdrop()
将背景切换为下一个背景
sprite.next_costume()
set_effect(特效, 数值)
将角色的特效效果设置为指定的数值。"特效"可以为下列之一:
- color: 颜色色值
- fisheye: 鱼眼效果强度
- whirl: 漩涡效果强度
- pixelate: 像素化效果强度
- mosaic: 马赛克效果强度
- brightness: 设置亮度
- ghost: 幽灵效果强度
sprite.set_effect("color", 10) # 将角色颜色值设置为10
change_effect_by(特效, 数值)
将角色的特效效果增加指定的数值。"特效"可以为下列之一:
- color: 颜色色值
- fisheye: 鱼眼效果强度
- whirl: 漩涡效果强度
- pixelate: 像素化效果强度
- mosaic: 马赛克效果强度
- brightness: 设置亮度
- ghost: 幽灵效果强度
sprite.change_effect_by("color", 10) # 将角色颜色值增加10
clear_effect()
清除角色所有的特效
sprite.clear_effect()
角色大小:size
可以使用size获取和设置角色的大小比例
size为100说明角色是原始大小(100%)
sprite.size = 200 # 将角色放大一倍
sprite.size = sprite.size - 50 # 将角色缩小原尺寸的50%
print(sprite.size) # 输出150,说明现在角色是原尺寸的1.5倍
播放声音
play(音效名称)
播放音效,音效名称必须在角色已有的音效中。
sprite.play("meow") # 播放猫叫
play_until_done(音效名称)
播放音效,直至播放完成;
音效名称必须在角色已有的音效中。
sprite.play_until_done("meow") # 播放猫叫
stop_sound()
停止角色正在播放的所有声音
sprite.stop_sound()
play_drum(乐器编号, 拍数)
播放鼓声。乐器编号为1到18的自然数; 拍数指播放的时间长度
sprite.play_drum(1, 0.25)
rest(拍数)
在播放其他声音或进行其他动作之前休息指定的拍数,相当于休止符
sprite.rest(0.5)
play_note(音符序号, 拍数)
播放音符。音符序号为自然数,越高则音高越高; 拍数指播放的时间长度
sprite.play_note(60, 0.25) # 播放中音C, 0.25拍
set_inst(乐器序号)
设置乐器类型,序号为1-21,代表不同乐器。 TODO: 所有乐器列表
sprite.set_inst(1) # 设置乐器为钢琴
set_sfx(音效名称, 数值)
设置声音特效的数值。 TODO: 所有音效列表
sprite.set_sfx('PITCH', 10) #
change_sfx_by(音效名称, 数值)
改变(增加)声音特效的数值。 TODO: 所有音效列表
sprite.change_sfx_by('PITCH', 10) #
clear_sfx()
清除当前角色的所有声音特效
sprite.clear_sfx() #
音量大小:volume
使用volume来获得和设置角色的音量大小
音量的范围是0-100
sprite.volume = 50 # 将音量设置成50
sprite.volume = sprite.volume + 10 # 将音量增大10%
print(sprite.volume) # 60
设置每秒节拍数:set_tempo(节拍数) | 更改每秒节拍数:change_tempo_by(节拍数)
使用tempo来获得和设置角色每秒节拍数
会影响play_note等的音符时长
sprite.set_tempo(60)
sprite.change_tempo_by(20)
海龟绘图
pendown()
落笔。落笔后角色移动将能绘制出痕迹
sprite.pendown()
penup()
抬笔。抬笔后角色移动将不会留下痕迹
sprite.penup()
stamp()
在当前位置留下精灵的图片,就像盖上印章一样
sprite.stamp()
pencolor(颜色) | pencolor(红, 绿, 蓝)
修改画笔的颜色。颜色可以为:
- 表示颜色的英文单词, 可以是以下之一 "red", "orange", "yellow", "green", "cyan", "blue", "purple", "black", "white", "grey"
- 用"#"开头的16进制的颜色代码,如"#FF0000"
- 包含RGB的元组
- 直接用数字表示的红绿蓝色值
sprite.pencolor("red")
sprite.pencolor("#FF0000")
sprite.pencolor(255, 0, 0) # 效果是相同的
pencolor_effect(特效名称, 数值)
设置画笔颜色的特效数值(0-100)。
特效名称字符串可以为:
- "hue": 颜色色相
- "saturation": 饱和度
- "brightness": 亮度
- "transparency: 透明度
sprite.pencolor_effect("hue", 60)
change_pencolor_effect_by(特效名称, 色值)
改变(增加)画笔颜色的特效数值(0-100)。
特效名称字符串可以为:
- "hue": 颜色色相
- "saturation": 饱和度
- "brightness": 亮度
- "transparency: 透明度
sprite.change_pencolor_effect_by("hue", 10)
clear()
清除画布上的图像
sprite.clear()
pensize(画笔宽度)
设置画笔宽度
sprite.pensize(1)
change_pensize_by(画笔宽度)
改变(增加)画笔宽度
sprite.change_pensize_by(1)
使用事件
可以在python代码中使用事件,来和键盘鼠标等交互
方法是在一个函数之前增加对应标记(装饰器)
from mblock import *
@event.greenflag # 表明当绿旗按下时执行函数
def on_green_flag(): # 函数名可以自己定义
print("绿旗被按下了") # 这里写当绿旗被按下时执行的代码
@greenflag
当绿旗被按下
@event.greenflag
def on_green_flag():
print("绿旗被按下了")
@keypressed(按键名称)
当键盘按键被按下时触发此事件。“按键名称”的例子有:
"a", "A", "1", "enter"(回车键), "space"(空格键), "backspace"(退格键)
之后可能会有keydown, keyup
@event.keypressed("space")
def on_space_key():
print("空格键按下了")
@clicked
当角色被点击时,触发此事件
之后可能会有mousedown, mouseup
@event.clicked
def on_clicked():
print("角色被点击了")
@backdrop_enter(背景名称)
当背景被切换为指定背景,触发此事件
@event.backdrop_enter("Party")
def on_backdrop_enter():
print("背景被切换成Party了")
@when_greater_than(参数名称, 比较值)
当指定参数名称大于比较值时,触发此事件。 参数名称可以为:
- "TIMER": Scratch内置计时器秒数
- "VOLUME"(未实现): 麦克风音量大小
@event.when_greater_than("TIMER", 10)
def on_backdrop_enter():
print("已经经过10秒了")
broadcast(事件名称)
向系统中广播指定事件
sprite.broadcast("game_start")
@received(事件名称)
当接收到特定事件的时候,执行下面的函数
@event.received("game_start")
def when_game_start():
print("游戏已经开始")
使用变量
通过使用全局变量和列表
角色中的Python代码可以和其他角色中的积木块或Python代码通信
甚至可以和硬件设备通信
set_variable(变量名, 数值)
设置Scratch积木变量。
请注意变量必须已经在积木块编辑器中存在
否则不会有任何效果(可以在控制台看到"积木变量不存在"警告)
sprite.set_variable("score", 50)
get_variable(变量名)
获得Scratch积木变量的数值
如果该变量不存在,返回None
print(sprite.get_variable("score"))
克隆角色和流程控制
clone(角色名)
克隆指定角色,
(可暂不实现)并返回角色的克隆(Sprite对象)
如果没有提供角色名则克隆自己
sprite.clone('_myself_') # 克隆自己
sprite.clone("Panda") # 克隆一个熊猫角色
delete_clone()
如果自己作为克隆出现,则把自己删除掉
sprite.delete_clone()
stop_all() / stop_this() / stop_other()
停止全部脚本/(暂不实现)本角色脚本/(暂不实现)其他角色脚本
sprite.stop_all() # 停止舞台上全部脚本
基本输入输出
print(内容)
将内容显示在python编辑器下方的日志区,一般用于调试。
print("hello world")
input(提示语)
在舞台区提示用户输入内容。
name = sprite.input("what's your name?")
sprite.say("your name is:" + name)
角色状态检测
touching(角色名)
判断当前角色是否触碰到其他角色、鼠标指针或者屏幕边缘 得到的结果时True或False
print(sprite.touching("Panda")) # 输出当前角色是否碰到熊猫
print(sprite.touching('_mouse_')) # 输出当前角色是否碰到鼠标指针
print(sprite.touching('_edge_')) # 输出当前角色是否碰到屏幕边缘
touching_color(颜色) | touching_color(红, 绿, 蓝) | touching_color(角色颜色, 画面颜色)
判断当前角色是否触碰到指定的颜色。颜色可以是
- 用"#"开头的16进制的颜色代码,如"#FF0000"
- 包含RGB的元组
- 直接用数字表示的红绿蓝色值
如果提供了2个颜色参数,则可以检测角色上的某个颜色是否触碰到画布上的其他颜色
得到的结果时True或False
print(sprite.touching_color("#ff0000")) # 输出当前角色是否碰到红色
print(sprite.touching_color(255, 0, 0)) # 同上
color = (255, 0, 0)
print(sprite.touching_color(color)) # 同上
print(sprite.touching_color("#ff0000", "#00ff00")) # 检测角色的红色区域是否触碰到绿色
distance_to(角色)
获得角色到鼠标指针或其他角色的距离
sprite.distance_to('_mouse_') # 获得到鼠标指针的距离
sprite.distance_to('Accordion3')
is_keypressed(按键名称)
指定按键是否被按下(返回True和False) “按键名称”的例子有:"a", "A", "1", "enter"(回车键), "space"(空格键), "backspace"(退格键)
print(sprite.is_keypressed("space")) # 若执行当时空格键被按下,返回True
is_mousedown
鼠标是否被按下(返回True和False)
print(sprite.is_mousedown) # 若执行当时鼠标被按下,返回True
一些角色状态属性
可以使用下列属性获得角色状态:
- mousex: 当前鼠标在画布上的x坐标
- mousey: 当前鼠标在画布上的y坐标
- loudness: 获得电脑麦克风感知的响度
- timer: 获得定时器当前值
- current(unit): 当前时间分量。参数unit为其中之一 year | month | date | day_of_week | hour | minute | second
- days_since_2000: 获取自2000年1月1日来经过的天数
print("%d, %d" % (sprite.mousex, sprite.mousey)) # 输出鼠标坐标
print(sprite.loudness) # 输出响度
print(sprite.timer) # 输出计时器秒数
print("%d-%d-%d %d:%d:%d" % (sprite.current('year'), sprite.current('month'), sprite.current('date'), sprite.current('hour'), sprite.current('minute'), sprite.current('second')))
print("day of week: ", sprite.current('day_of_week')) # 获得星期数
print("days since 2000", sprite.days_since_2000)
reset_timer()
重置定时器
sprite.reset_timer()
print(sprite.timer) # 得到0,因为被重置了