知识点:什么是掌控板?
掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED显示屏、RGB灯、加速度计、麦克风、光线传感器、蜂鸣器、按键开关、触摸开关、金手指外部拓展接口,支持图形化及MicroPython代码编程,可实现智能机器人、创客智造作品等智能控制类应用。
掌控板硬件特性:
ESP-32主控
处理器:Tensilica LX6双核处理器(一核处理高速连接;一核独立应用开发)
主频:高达240MHz的时钟频率
SRAM:520KB
Flash:8MB
Wi-Fi标准:FCC/CE/TELEC/KCC
Wi-Fi协议:802.11 b/g/n/d/e/i/k/r (802.11n,速度高达150 Mbps),A-MPDU和A-MSDU聚合,支持0.4us防护间隔
频率范围:2.4~2.5 GHz
蓝牙协议:符合蓝牙v4.2 BR/EDR和BLE标准
蓝牙音频:CVSD和SBC音频低功耗:10uA
供电方式:Micro USB供电
工作电压:3.3V
最大工作电流:200mA
最大负载电流:1000mA
掌控板载
三轴加速度计MSA300,测量范围:±2/4/8/16G
地磁传感器MMC5983MA,测量范围:±8 Gauss;精度0.4mGz,电子罗盘误差±0.5°
光线传感器
麦克风
3 颗全彩ws2812灯珠
1.3英寸OLED显示屏,支持16*16字符显示,分辨率128x64
无源蜂鸣器
支持2个物理按键(A/B)、6个触摸按键
支持1路鳄鱼夹接口,可方便接入各种阻性传感器
拓展接口
20通道数字I/O, (其中支持12路PWM,6路触摸输入)
5通道12bit模拟输入ADC,P0~P4
1路的外部输入鳄鱼夹接口:EXT/GND
支持I2C、UART、SPI通讯协议
小游戏 (体积较小、玩法简单的游戏)
小游戏是一个较模糊的概念,它是相对于体积庞大的单机游戏及网络游戏而言的,泛指所有体积较小、玩法简单的游戏,通常这类游戏以休闲益智类为主,有单机版有网页版,在网页上嵌入的多为FLASH格式。当下小游戏主要是指在线玩的flash版本游戏,统称小游戏,其实小游戏还包含单机游戏,小型游戏机等。一般游戏大小小于10m的游戏都统称为小游戏,一些街机类小游戏。因其游戏安装简便,耐玩性强,无依赖性而广受白领及小朋友的喜爱。
“小游戏”这个词的型含义其实很简单,它不是一些大的游戏,不必花费更多的时间和精力。小游戏是原始的游戏娱乐方式,小游戏本身是为了叫人们在工作,学习后的一种娱乐、休闲的一种方式,不是为了叫玩家为之花费金钱、花费精力,更不是叫玩家为他痴迷。小游戏也可以理解为“Flash游戏”,是以SWF为后缀的游戏的总称.这些游戏是通过Flash软件和 Flash 编程语言 Flash ActionScript 制作而成。由于Flash是矢量软件,所以小游戏放大后几乎不影响画面效果。Flash小游戏是一种新兴起的游戏形式,以游戏简单,操作方便,绿色,无需安装,文件体积小等优点渐渐被广大网友喜爱。
1、弹球游戏
#MicroPython动手做(35)——体验小游戏
#弹球游戏from mpython import *
import music
import timedef func():global a, b, FMQ, loc, staart_flag, Start, X, Ymusic.pitch(131, 500)loc = 44a = 2b = 2staart_flag = FalseStart = TrueY = 48X = 64FMQ = Falsedef a1():global a, b, FMQ, loc, staart_flag, Start, X, Yif FMQ:music.pitch(131, 500)FMQ = Falsedef a3():global a, b, FMQ, loc, staart_flag, Start, X, Yif Start:if button_a.value() == 0:staart_flag = Trueloc = loc - 2if loc < 0:loc = 0if button_b.value() == 0:staart_flag = Trueloc = loc + 2if loc > 88:loc = 88def a2():global a, b, FMQ, loc, staart_flag, Start, X, Yoled.fill(0)oled.fill_rect(loc, 55, 40, 5, 1)oled.fill_circle(X, Y, 5, 1)oled.show()if button_a.value() == 0 and button_b.value() == 0:func()while button_a.value() == 0 and button_b.value() == 0:passtime.sleep_ms(100)def a4():global a, b, FMQ, loc, staart_flag, Start, X, Yif staart_flag:X = X + aY = Y - bif X >= 122:a = a * -1if X <= 5:a = a * -1if Y <= 5:b = b * -1if Y >= 48:if not (X > loc + 50 or X < loc - 10):b = b * -1if X > loc + 50 or X < loc - 10:staart_flag = FalseStart = FalseFMQ = Truefunc()
while True:a1()a2()a3()a4()
mPython X 实验图形编程
mPython X 实验图形编程2
Mind+ 实验图形编程
弹球游戏(实验视频)
https://v.youku.com/v_show/id_XNDcyNzU1MjkwNA==.html?spm=a2h0c.8166622.PhoneSokuUgc_1.dtitle
添加链接描述
2、简单连连看(shworld)
玩法说明
按A键左移动
按B键右移动
按金手指T或H来选择
#MicroPython动手做(35)——体验小游戏
#简单连连看from mpython import *
import random#--------------------------------------------------------
#图片转换参考https://mpython.readthedocs.io/zh/master/tutorials/basics/oled.html#id3
#图片定义
#苹果
apple = bytearray([\
0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X00,0X01,0X80,0X00,0X00,0X01,0X80,0X18,0X70,0X01,
0X80,0X00,0X0C,0X01,0X80,0X00,0X03,0X01,0X84,0X01,0XC0,0X81,0X88,0X3F,0XF0,0X61,
0X98,0X3F,0XF8,0X31,0X90,0X3F,0XFC,0X31,0XB0,0X3F,0XFC,0X19,0XB0,0X3F,0XFE,0X19,
0XB0,0X0F,0XF6,0X19,0XB8,0X00,0X80,0X19,0XBC,0X00,0X00,0X19,0XBE,0X00,0X00,0X39,
0XBF,0X80,0X00,0X79,0XBF,0XE0,0X07,0XF9,0X9F,0XFF,0XFF,0XF9,0X9F,0XFF,0XFF,0XF1,
0X8F,0XFF,0XFF,0XF1,0X8F,0XFF,0XFF,0XE1,0X87,0XFF,0XFF,0XE1,0X83,0XFF,0XFF,0XC1,
0X81,0XFF,0XFF,0X81,0X81,0XFF,0XFF,0X01,0X80,0XFF,0XFE,0X01,0X80,0X7F,0XFC,0X01,
0X80,0X3F,0XF0,0X01,0X80,0X00,0X00,0X01,0X80,0X00,0X00,0X01,0XFF,0XFF,0XFF,0XFF,
])#樱桃
cherry = bytearray([\
0XFF,0XFF,0XFF,0XFF,0X80,0XC0,0X00,0X01,0X81,0XC0,0X00,0X01,0X80,0XC0,0X00,0X01,
0X80,0XC0,0X00,0X01,0X80,0XA0,0X00,0X01,0X80,0X10,0X00,0X01,0X80,0X90,0X00,0X01,
0X80,0X88,0X00,0X01,0X80,0X8C,0X00,0X01,0X80,0X84,0X00,0X01,0X80,0X83,0X00,0X01,
0X80,0X81,0X80,0X01,0X80,0X00,0XCF,0X21,0X80,0X40,0X7F,0X11,0X80,0X79,0XFF,0X19,
0X87,0XFC,0XFF,0XF9,0X8F,0XFC,0X7F,0XF9,0X9F,0XF8,0X7F,0XFD,0XBF,0XF8,0X7F,0XFD,
0XBF,0XF8,0X7F,0XFD,0XBF,0XF8,0X7F,0XFD,0XBF,0XFF,0XFF,0XFD,0XBF,0XFF,0XFF,0XF9,
0XBF,0XFF,0XFF,0XF9,0XBF,0XFF,0XFF,0XF1,0XBF,0XFF,0XFF,0XF1,0X9F,0XFF,0XFF,0XE1,
0X8F,0XFF,0X9F,0X81,0X87,0XFF,0X00,0X01,0X81,0XFC,0X00,0X01,0XFF,0XFF,0XFF,0XFF,
])#桑葚
mulberry = bytearray([\
0XFF,0XFF,0XFF,0XFF,0X80,0X21,0X00,0X01,0X80,0X10,0X00,0X01,0X81,0X08,0X80,0X01,
0X82,0X38,0X80,0X01,0X82,0X3F,0X80,0X01,0X82,0X3F,0XE0,0X01,0X86,0X3F,0XF0,0X01,
0X86,0X3F,0XF8,0X01,0X83,0XFF,0XFC,0X01,0X83,0XFF,0XFE,0X01,0X87,0XFF,0XFF,0X01,
0X8F,0XFF,0XFF,0X01,0X8F,0XFF,0XFF,0X01,0X8F,0XFF,0XFF,0X81,0X8F,0XFF,0XFF,0X81,
0X8F,0XFF,0XFF,0X81,0X8F,0XFF,0XFF,0X81,0X8F,0XFF,0XFF,0X81,0X87,0XFF,0XFF,0X81,
0X87,0XFF,0XFF,0X81,0X83,0XFF,0XFF,0XC1,0X81,0XFF,0XFF,0XC1,0X80,0XFF,0XFF,0XC1,
0X80,0XFF,0XFF,0XC1,0X80,0X7F,0XFF,0XC1,0X80,0X3F,0XFF,0X81,0X80,0X1F,0XFF,0X81,
0X80,0X0F,0XFF,0X81,0X80,0X03,0XFF,0X01,0X80,0X01,0XFC,0X01,0XFF,0XFF,0XFF,0XFF,
])#草莓
strawberry = bytearray([\
0XFF,0XFF,0XFF,0XFF,0X80,0X00,0X00,0X01,0X80,0X00,0X00,0X01,0X80,0X00,0X00,0X01,
0X80,0X00,0X00,0X01,0X80,0X00,0XC0,0X01,0X80,0X03,0XE8,0X01,0X80,0X0D,0XE4,0X01,
0X80,0X1F,0XFE,0X01,0X80,0X3F,0XFF,0X01,0X80,0X7F,0XFF,0X01,0X80,0XFF,0XDF,0X81,
0X81,0XFF,0XFF,0XF9,0X83,0XFF,0XFF,0XC1,0X83,0XFF,0XFF,0XC1,0X87,0XFF,0XFF,0XC1,
0X8F,0XFF,0XFF,0XE1,0X9F,0X7F,0XFF,0XE1,0XBF,0XFF,0XFF,0XE1,0XBF,0XFF,0XFF,0XE1,
0XBF,0XFE,0XFF,0XE1,0XBF,0XDF,0XFF,0XE1,0XBF,0XFF,0XFF,0XC1,0X9F,0XFF,0XFE,0XC1,
0X9F,0XFF,0XBF,0X81,0X8F,0XFF,0XFF,0X01,0X81,0XFF,0XFC,0X01,0X80,0X07,0XF0,0X01,
0X80,0X00,0X00,0X01,0X80,0X00,0X00,0X01,0X80,0X00,0X00,0X01,0XFF,0XFF,0XFF,0XFF,
])#打勾
tick = bytearray([\
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XC0,0X00,0X00,0X03,0XC0,0X00,0X00,0X03,
0XC0,0X00,0X00,0X03,0XC0,0X00,0X00,0X63,0XC0,0X00,0X00,0XE3,0XC0,0X00,0X01,0XE3,
0XC0,0X00,0X03,0XE3,0XC0,0X00,0X07,0XE3,0XC0,0X00,0X0F,0XE3,0XC0,0X00,0X1F,0XE3,
0XC0,0X00,0X1F,0XF3,0XC0,0X00,0X3F,0XF3,0XC0,0X00,0X7F,0XC3,0XC0,0X00,0X7F,0X83,
0XC0,0XC0,0XFF,0X03,0XC1,0XE0,0XFE,0X03,0XC7,0XE1,0XFC,0X03,0XCF,0XF1,0XF8,0X03,
0XCF,0XF3,0XF0,0X03,0XC3,0XFB,0XE0,0X03,0XC1,0XFF,0XC0,0X03,0XC0,0X7F,0X80,0X03,
0XC0,0X3F,0X80,0X03,0XC0,0X1F,0X00,0X03,0XC0,0X0E,0X00,0X03,0XC0,0X06,0X00,0X03,
0XC0,0X04,0X00,0X03,0XC0,0X00,0X00,0X03,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,
])#--------------------------------------------------------
#函数定义
#生成8个随机水果下标
#默认数组[0,1,2,3],循环2次,就有个8了,如何避免每次生成重复的呢,下面请看
def getFruitRand():fruitsIndex=[0,1,2,3]fruitsIndex_random=[]for i in range(2): #对[0,1,2,3]循环2次加入到fruitsIndex_random中fruitsIndex_=fruitsIndex.copy() #这里不直接用fruitsIndex,因为下面有del删除,我们拷贝一份副本for j in range(4): #循环4次rand=random.randint(0,len(fruitsIndex_)-1) #随机0-3,因j从0开始最大为3,而len(fruitsIndex)返回的是4,所以-1randIndex=fruitsIndex_[rand] #取随机下标,范围在0-3中, fruitsIndex=[0,1,2,3] fruitsIndex_random.append(randIndex) #添加到fruitsIndex_random中del(fruitsIndex_[rand]) #这里核心,添加完成后删除掉fruitsIndex中的内容 #删除掉后,随机就肯定不会出现重复的了#比如每次都随机删除最后一个#循环第一次fruitsIndex_长度为[0,1,2,3]#循环第二次fruitsIndex_长度为[0,1,2]#循环第三次fruitsIndex_长度为[0,1]#循环第四次fruitsIndex_长度为[0]#这样随机肯定不会重复#返回得到的8位随机水果下标fruitsIndex_random return fruitsIndex_random#显示8个水果图片
#isShow主要控制是否最后oled.show(),因为我可能会再show()之前插入一些文字
#fruitsIndex传输的8位随机水果下标,如[2,1,3,0,2,0,1,3]
def showFruit(fruitsIndex,isShow=True):i=0for index in fruitsIndex: #遍历fruitsIndex下标,i计次,从0开始if i<4: #控制一行显示4个if index==-1: #下标为何出现-1,在其他函数中连连看完成会置下标-1oled.Bitmap(32*i, 0, tick, 32, 32, 1) #显示打勾图片(x每次递增32,因为每张图32*32,屏宽128)else: #否则显示水果图oled.Bitmap(32*i, 0, fruits[index], 32, 32, 1) if i>=4: #如果显示第5个图了,换行显示,y坐标变成32if index==-1: #以此类题,显示打勾图片oled.Bitmap(32*(i-4), 32, tick, 32, 32, 1)else:oled.Bitmap(32*(i-4), 32, fruits[index], 32, 32, 1)i=i+1 #i递增#是否显示输出if isShow:oled.show()#按键A触发事件,向左移动判断
def on_button_a_down(_):global cursor_X,cursor_Y,chose1XY,isFinish #引用全局变量time.sleep_ms(10) #防抖,可以不写 if button_a.value() == 1: return #按钮按下状态if isFinish==True: #如果全部连完了,重新开始游戏start()returnoled.fill(0) #清空屏幕显示 showFruit(fruitsIndex,False) #显示水果,传入随机的8个水果下标cursor_X=cursor_X-32 #全局光标坐标-32(因图片宽高为32) if cursor_X<0 and cursor_Y==8: #如果光标在第一行且X到最左端了,那么换到第二行最右侧cursor_X=100 #换到第二行最右侧cursor_Y=40if cursor_X<4 and cursor_Y==40: #如果光标在第二行且X在最左端了,那么换到第一行最右侧cursor_X=100cursor_Y=8if chose1XY: #如果第1个位置已经选中状态oled.DispChar('选中', chose1XY[0], chose1XY[1]) #显示那个"光标"的文字位置oled.DispChar('光标', cursor_X, cursor_Y) #否则显示"光标"文字oled.show() #显示生效#按键B触发事件,向右移动判断
def on_button_b_down(_):global cursor_X,cursor_Y,chose1XY,isFinish #按键B与按键A没有区别,就是到极端时换行不同time.sleep_ms(10)if button_b.value() == 1: returnif isFinish==True:start()returnoled.fill(0) showFruit(fruitsIndex,False)cursor_X=cursor_X+32if cursor_X>128 and cursor_Y==40:cursor_X=4cursor_Y=8if cursor_X>128 and cursor_Y==8:cursor_X=4cursor_Y=40if chose1XY :oled.DispChar('选中', chose1XY[0], chose1XY[1])oled.DispChar('光标', cursor_X, cursor_Y)oled.show()#验证是否完成8个水果的连连看
def checkIsFinish():global isFinish #引用全局变量i=0 #初始化i变量for index in fruitsIndex: #遍历fruitsIndex下标情况if index==-1: #如果为-1,i递增(在其他函数中连连看完成会置下标-1)i=i+1if i>=8: #如果i等于8说明8个连连看都完成了isFinish=True #置全局变量oled.fill(0) #清空屏幕显示oled.DispChar('恭喜您,通关了!', 28, 15) #填充文字oled.DispChar('按A或B重新开始', 22, 30) #填充文字oled.show() #显示生效#通过金手指T和H来选择水果
def choseFruit(cursor_X,cursor_Y):global fruitsIndex,chose1Index,chose2Index,chose1XY,chose2XYi=0for x,y in fruitXY: #遍历8张图的预定义坐标if cursor_X==x and cursor_Y==y: #如果当前光标位置=预定义坐标位置,即可得到水果下标if fruitsIndex[i]==-1: #如果光标位置下标为-1,说明已是打勾状态,不重复选中return #返回if chose1XY: #如果第1个位置已经选中状态 chose2XY=[x,y] #把光标位置赋给第2个选择位置chose2Index=fruitsIndex[i] #同时得到水果下标else:chose1XY=[x,y] #否则赋值第1个选择位置chose1Index=fruitsIndex[i] #同时得到水果下标i=i+1 #i递增 showFruit(fruitsIndex,False) #显示水果,不立即显示生效if chose2XY: #如果第2个位置选中了,此时可进行匹配if chose1Index==chose2Index and chose1XY!=chose2XY: #如果位置1和位置2的下标相同且坐标不相同(否则连自身就匹配成功了)oled.line(chose1XY[0], chose1XY[1], chose2XY[0], chose2XY[1], 1) #画线,位置1到位置2oled.DispChar('成功', cursor_X, cursor_Y) #填充文字for i in range(len(fruitsIndex)): #遍历全局fruitsIndex,把该水果的下标置-1if fruitsIndex[i]==chose2Index:fruitsIndex[i]=-1chose1XY=[] #清空位置1坐标chose2XY=[] #清空位置2坐标oled.show() #显示生效checkIsFinish() #检测是否全部匹配完成else:oled.DispChar('选中', cursor_X, cursor_Y) #否则继续显示"选中"文字oled.show() #显示生效#开始游戏
def start():#引用全局变量并初始化默认值,因为重新开始游戏时必须初始化global fruitsIndex,cursor_X,cursor_Y,chose1XY,chose1Index,chose2XY,chose2Index,fruitsIndex,isFinish#初始化变量chose1XY=[]chose1Index=''chose2XY=[]chose2Index=''fruitsIndex=[]cursor_X=4cursor_Y=8isFinish=Falseoled.fill(0) #清空屏幕显示fruitsIndex=getFruitRand() #获取随机的8个水果下标showFruit(fruitsIndex,False) #第一次开始游戏先显示水果,传入8个随机水果下标oled.DispChar('光标', cursor_X, cursor_Y) #第一次开始游戏,光标出现在默认的x,y4,8位置oled.show() #显示生效#--------------------------------------------------------
#变量定义
fruits=[apple,cherry,mulberry,strawberry] #4个图片的bitmap数组
fruitsIndex=[] #水果的下标数组,用来存放随机的8个水果
fruitXY=[[4,8],[36,8],[68,8],[100,8],[4,40],[36,40],[68,40],[100,40]] #8张图的预定义坐标,从左到右,从上到下chose1XY=[] #位置1选择的水果坐标
chose1Index='' #位置1选择的水果下标chose2XY=[] #位置2选择的水果坐标
chose2Index='' #位置2选择的水果下标cursor_X=4 #全局光标坐标,默认为第一个图的位置4,8(居中显示)
cursor_Y=8 isFinish=False #是否已完成start() #开始游戏#--------------------------------------------------------
#按键监听
#按键A/B触发监视
button_a.irq(trigger=Pin.IRQ_FALLING, handler=on_button_a_down)
button_b.irq(trigger=Pin.IRQ_FALLING, handler=on_button_b_down)#通过金手指T和H来选择水果
while True:if(touchPad_T.read() < 100):choseFruit(cursor_X,cursor_Y)elif(touchPad_H.read() < 100):choseFruit(cursor_X,cursor_Y)
简单连连看