驴友花雕 发表于 2020-6-26 15:14:52


8、模拟计算器(shworld)

通过按键A向左移动光标,按键B向右移动光标
金手指Y键确认选择
支持多元运算,最长显示结果限定在16位左右,防止超出屏幕宽度
如果运算错误会输出显示,比如被除数为0或者其他错误乱输入



#MicroPython动手做(35)——小游戏
#模拟计算器

from mpython import *

#图片bitmap数组
bmp = bytearray([\
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF8,0X00,
0X80,0X0C,0X00,0X60,0X03,0X00,0X18,0X00,0XC0,0X06,0X00,0X30,0X01,0X80,0X08,0X00,
0X80,0X0C,0X00,0X60,0X03,0X00,0X18,0X00,0XC0,0X06,0X3E,0X30,0X61,0X83,0X08,0X00,
0X82,0X0C,0X3C,0X61,0XE3,0X02,0X18,0X40,0XC1,0X06,0X02,0X30,0XB1,0X84,0X88,0X00,
0X86,0X0C,0X44,0X61,0X23,0X06,0X18,0X40,0XC3,0X06,0X02,0X31,0X11,0X84,0X48,0X00,
0X82,0X0C,0X04,0X60,0X23,0X06,0X18,0X70,0XC2,0X06,0X04,0X30,0XA1,0X84,0XC8,0X00,
0X82,0X0C,0X08,0X60,0XC3,0X0A,0X18,0X08,0XC7,0XC6,0X04,0X30,0XE1,0X87,0X88,0X00,
0X82,0X0C,0X08,0X60,0X23,0X12,0X18,0X08,0XC4,0X46,0X08,0X31,0X91,0X81,0X88,0X00,
0X82,0X0C,0X10,0X60,0X23,0X1F,0X18,0X88,0XC4,0X46,0X08,0X31,0X11,0X81,0X08,0X00,
0X82,0X0C,0X20,0X61,0X63,0X02,0X18,0X58,0XC6,0XC6,0X08,0X30,0XB1,0X83,0X08,0X00,
0X82,0X0C,0X3C,0X60,0X83,0X00,0X18,0X20,0XC3,0X86,0X00,0X30,0X41,0X80,0X08,0X00,
0X80,0X0C,0X00,0X60,0X03,0X00,0X18,0X00,0XC0,0X06,0X00,0X30,0X01,0X80,0X08,0X00,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XF8,0X00,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XE0,0X00,0X00,0X00,0X00,
0X80,0X0C,0X00,0X60,0X03,0X00,0X18,0X00,0XC0,0X06,0X00,0X20,0X00,0X00,0X00,0X00,
0X82,0X0C,0X00,0X60,0X03,0X00,0X18,0X00,0XC0,0X06,0X1C,0X20,0X00,0X00,0X00,0X00,
0X85,0X0C,0X00,0X60,0X03,0X10,0X58,0X08,0XC0,0X06,0X34,0X20,0X00,0X00,0X00,0X00,
0X88,0X8C,0X10,0X60,0X03,0X08,0X98,0X10,0XDF,0XF6,0X22,0X20,0X00,0X00,0X00,0X00,
0X88,0X8C,0X10,0X60,0X03,0X01,0X18,0X10,0XC0,0X06,0X20,0X20,0X00,0X00,0X00,0X00,
0X88,0X8C,0X7C,0X61,0XE3,0X06,0X18,0X20,0XC0,0X06,0X20,0X20,0X00,0X00,0X00,0X00,
0X88,0X8C,0X10,0X60,0X03,0X06,0X18,0X00,0XC0,0X06,0X22,0X20,0X00,0X00,0X00,0X00,
0X8C,0X8C,0X10,0X60,0X03,0X09,0X18,0X40,0XDF,0XF6,0X26,0X20,0X00,0X00,0X00,0X00,
0X87,0X0C,0X00,0X60,0X03,0X10,0X98,0X00,0XC0,0X06,0X1C,0X20,0X00,0X00,0X00,0X00,
0X80,0X0C,0X00,0X60,0X03,0X00,0X18,0X80,0XC0,0X06,0X00,0X20,0X00,0X00,0X00,0X00,
0X80,0X0C,0X00,0X60,0X03,0X00,0X18,0X00,0XC0,0X06,0X00,0X20,0X00,0X00,0X00,0X00,
0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XE0,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X7F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X00,
0X00,0X7F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X60,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X00,
0X00,0X7F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X00,
0X00,0X7F,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
])
#[建议]
#这一块由于数据太大写入太慢影响调试速度
#如果技术上跟的上的话,可以把背景事先截图,然后删掉代码,这样写入很快,然后盲按按钮调试

#主要逻辑是判断坐标来取值,把值拼接起来形成字符串,最后通过eval()函数运算
#实现方法很多种,自己的代码3个月后也不一定看懂,最好的教程是自己实现和学习
#by阿唯




#-------------------变量定义-------------------
#矩形光标的宽高
RECT_CURSOR=

#第一行各键序XY坐标,Y轴固定0
#偏移量13为矩形光标的宽度
KEY_ONE=
KEY_TWO=
KEY_THREE=
KEY_FOUR=
KEY_FIVE=
KEY_SIX=
KEY_SEVEN=
KEY_EIGHT=
KEY_NINE=
#第二行各键序XY坐标,Y轴固定13
KEY_ZERO=
KEY_ADD=
KEY_MINUS=
KEY_MULTI=
KEY_DIVIDE=
KEY_EQUAL=
KEY_CLEAR=

#定义键序坐标列表,用于按钮左右移动,通过列表索引的增减来移动
KEY_LIST=[KEY_ONE,KEY_TWO,KEY_THREE,KEY_FOUR,KEY_FIVE,KEY_SIX,
KEY_SEVEN,KEY_EIGHT,KEY_NINE,KEY_ZERO,KEY_ADD,KEY_MINUS,
KEY_MULTI,KEY_DIVIDE,KEY_EQUAL,KEY_CLEAR]

#定义键序值列表,用于取值运算和显示
KEY_LIST_VAL=["1","2","3","4","5","6","7","8","9","0","+","-","*","/","=","c"]

#当前键序0,即引用KEY_LIST,也就是默认在1的位置
KEY_INDEX=0

#数值内容,通过eval()对字符串表达式直接运算
RESULT_CALC=""






#-------------------函数方法-------------------
#移动光标,例moveCursor("left")
def moveCursor(direction=None):
    oled.fill(0)
    oled.bitmap(0, 0, bmp, 128, 64, 1)
    oled.DispChar("输出:"+RESULT_CALC,10,37)
   
    global KEY_INDEX         #如果要对全局变量修改的话需要引用
    if(direction=="left"):   #如果是向左移动,则KEY_LIST索引-1
      if KEY_INDEX>0:       #只有索引>0才可以进行递减,防止越界
             KEY_INDEX=KEY_INDEX-1
   
    if(direction=="right"):    #同理
      if KEY_INDEX<15:
            KEY_INDEX=KEY_INDEX+1
   
    _x=KEY_LIST#通过KEY_LIST的索引来获取矩形光标的填充位置
    _y=KEY_LIST
   
    RECT_CURSOR_WIDTH=RECT_CURSOR    #获取矩形光标的宽高
    RECT_CURSOR_HEIGHT=RECT_CURSOR
   
    oled.fill_rect(_x, _y, RECT_CURSOR_WIDTH, RECT_CURSOR_HEIGHT, 1) #填充画面
    oled.show()






#-------------------程序入口-------------------
#第一次方向参数direction不传,用于渲染一次主画面
moveCursor()








#-------------------按钮监听-------------------
#按钮a触发事件
def on_button_a_down(_):
    if button_a.value() == 1: return
    moveCursor("left")

#按钮b触发事件
def on_button_b_down(_):
    if button_b.value() == 1: return
    moveCursor("right")

#按钮监听回调函数
button_a.irq(trigger=Pin.IRQ_FALLING, handler=on_button_a_down)
button_b.irq(trigger=Pin.IRQ_FALLING, handler=on_button_b_down)


#金手指触摸监听
while True:
    time.sleep_ms(50)                   #延迟调高,按钮迟钝,反之延迟越低越容易误触
    if(touchPad_Y.read() < 100):
      keyVal=KEY_LIST_VAL#通过全局索引获取键值列表的值
      if(KEY_INDEX<=9):               #如果索引<=9,说明按的是前面10个数字,直接累加就行
             RESULT_CALC=RESULT_CALC+keyVal
      if(keyVal=="+"):                #如果按的是+好,累加就可以,下面同理
            RESULT_CALC=RESULT_CALC+"+"
      if(keyVal=="-"):
            RESULT_CALC=RESULT_CALC+"-"
      if(keyVal=="*"):
            RESULT_CALC=RESULT_CALC+"*"
      if(keyVal=="/"):
            RESULT_CALC=RESULT_CALC+"/"
      if(keyVal=="="):                #当按了等号后,会获得一个累加的字符串变量RESULT_CALC
            try:                        #RESULT_CALC比如为"1+2*3",这里加try屏蔽运算错误
                RESULT_CALC=str(eval(RESULT_CALC))#核心函数eval()进行字符串运算,运算不成立会报错
                RESULT_CALC=RESULT_CALC[:16]      #取结果集左边16位字符串,防止超出画面显示
                moveCursor()                        #最后提前调用一次移动函数显示画面
                RESULT_CALC=""                      #置结果集为空,不会生效,下一次移动才会生效
                continue                            #跳出本次循环,不然最后moveCursor()又要重画一次
            except:                     #异常处理
                RESULT_CALC="输入错误"
                moveCursor()
                RESULT_CALC=""
                continue
      if(keyVal=="c"):
            RESULT_CALC=""
      moveCursor()                  #不传参数direction=None(不移动光标),直接渲染主画面

驴友花雕 发表于 2020-6-26 18:44:23

9、是男人就下一百层(luyi)

设置Y/O触摸键控制人物左右移动

#MicroPython动手做(35)——小游戏
#是男人就下一百层

from mpython import *

import time

def man(x, y):
    global x1, y1, xman, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8, x9, y9, x10, y10, yman, down
    oled.fill_circle(x, (y - 25), 3, 1)
    oled.fill_rect((x - 5), (y - 21), 10, 10, 1)
    oled.fill_rect((x - 4), (y - 11), 3, 11, 1)
    oled.fill_rect((x + 1), (y - 11), 3, 11, 1)

def dangban():
    global x, y, x1, y1, xman, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8, x9, y9, x10, y10, yman, down
    oled.fill_rect(0, 0, 5, 8, 1)
    oled.fill_rect(0, 8, 5, 8, 1)
    oled.fill_rect(0, 17, 5, 8, 1)
    oled.fill_rect(0, 26, 5, 8, 1)
    oled.fill_rect(0, 35, 5, 8, 1)
    oled.fill_rect(0, 44, 5, 8, 1)
    oled.fill_rect(0, 53, 5, 8, 1)
    oled.fill_rect(0, 62, 5, 8, 1)

from machine import Timer

_status_p = _status_y = _status_t = _status_h = _status_o = _status_n = 0
def on_touchpad_P_pressed():pass
def on_touchpad_P_unpressed():pass
def on_touchpad_Y_pressed():pass
def on_touchpad_Y_unpressed():pass
def on_touchpad_T_pressed():pass
def on_touchpad_T_unpressed():pass
def on_touchpad_H_pressed():pass
def on_touchpad_H_unpressed():pass
def on_touchpad_O_pressed():pass
def on_touchpad_O_unpressed():pass
def on_touchpad_N_pressed():pass
def on_touchpad_N_unpressed():pass

tim12 = Timer(12)

def timer12_tick(_):
    global _status_p, _status_y, _status_t, _status_h, _status_o, _status_n
    try:
      touchPad_P.read();pass
    except:
      return
    if touchPad_P.read() < 400:
      if 1 != _status_p:_status_p = 1;on_touchpad_P_pressed()
    elif 0 != _status_p:_status_p = 0;on_touchpad_P_unpressed()
    if touchPad_Y.read() < 400:
      if 1 != _status_y:_status_y = 1;on_touchpad_Y_pressed()
    elif 0 != _status_y:_status_y = 0;on_touchpad_Y_unpressed()
    if touchPad_T.read() < 400:
      if 1 != _status_t:_status_t = 1;on_touchpad_T_pressed()
    elif 0 != _status_t:_status_t = 0;on_touchpad_T_unpressed()
    if touchPad_H.read() < 400:
      if 1 != _status_h:_status_h = 1;on_touchpad_H_pressed()
    elif 0 != _status_h:_status_h = 0;on_touchpad_H_unpressed()
    if touchPad_O.read() < 400:
      if 1 != _status_o:_status_o = 1;on_touchpad_O_pressed()
    elif 0 != _status_o:_status_o = 0;on_touchpad_O_unpressed()
    if touchPad_N.read() < 400:
      if 1 != _status_n:_status_n = 1;on_touchpad_N_pressed()
    elif 0 != _status_n:_status_n = 0;on_touchpad_N_unpressed()

tim12.init(period=100, mode=Timer.PERIODIC, callback=timer12_tick)

def on_touchpad_Y_pressed():
    global x, y, x1, y1, xman, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8, x9, y9, x10, y10, yman, down
    xman = xman + -5

def on_touchpad_O_pressed():
    global x, y, x1, y1, xman, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8, x9, y9, x10, y10, yman, down
    xman = xman + 5

def dangban2():
    global x, y, x1, y1, xman, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x7, y7, x8, y8, x9, y9, x10, y10, yman, down
    oled.fill_rect(122, 0, 5, 8, 1)
    oled.fill_rect(122, 8, 5, 8, 1)
    oled.fill_rect(122, 17, 5, 8, 1)
    oled.fill_rect(122, 26, 5, 8, 1)
    oled.fill_rect(122, 35, 5, 8, 1)
    oled.fill_rect(122, 44, 5, 8, 1)
    oled.fill_rect(122, 53, 5, 8, 1)
    oled.fill_rect(122, 62, 5, 8, 1)
x1 = 10
y1 = 59
x2 = 70
y2 = 95
x3 = 30
y3 = 129
x4 = 60
y4 = 165
x5 = 90
y5 = 199
x6 = 70
y6 = 235
x7 = 55
y7 = 269
x8 = 40
y8 = 305
x9 = 20
y9 = 339
x10 = 50
y10 = 375
xman = 20
yman = 33
while True:
    down = True
    oled.fill(0)
    dangban()
    dangban2()
    oled.fill_rect(x1, y1, 30, 5, 1)
    oled.fill_rect(x2, y2, 25, 5, 1)
    oled.fill_rect(x3, y3, 20, 5, 1)
    oled.fill_rect(x4, y4, 30, 5, 1)
    oled.fill_rect(x5, y5, 20, 5, 1)
    oled.fill_rect(x6, y6, 25, 5, 1)
    oled.fill_rect(x7, y7, 25, 5, 1)
    oled.fill_rect(x8, y8, 30, 5, 1)
    oled.fill_rect(x9, y9, 20, 5, 1)
    oled.fill_rect(x10, y10, 30, 5, 1)
    man(xman, yman)
    oled.show()
    if xman >= x1 and xman <= x1 + 30 and yman == y1:
      down = False
    if xman >= x2 and xman <= x2 + 25 and yman == y2:
      down = False
    if xman >= x3 and xman <= x3 + 20 and yman == y3:
      down = False
    if xman >= x4 and xman <= x4 + 30 and yman == y4:
      down = False
    if xman >= x5 and xman <= x5 + 20 and yman == y5:
      down = False
    if xman >= x6 and xman <= x6 + 25 and yman == y6:
      down = False
    if xman >= x7 and xman <= x7 + 25 and yman == y7:
      down = False
    if xman >= x8 and xman <= x8 + 30 and yman == y8:
      down = False
    if xman >= x9 and xman <= x9 + 20 and yman == y9:
      down = False
    if xman >= x10 and xman <= x10 + 30 and yman == y10:
      down = False
    if down:
      yman = yman + 1
    else:
      yman = yman + -1
    y1 = y1 + -1
    y2 = y2 + -1
    y3 = y3 + -1
    y4 = y4 + -1
    y5 = y5 + -1
    y6 = y6 + -1
    y7 = y7 + -1
    y8 = y8 + -1
    y9 = y9 + -1
    y10 = y10 + -1
    time.sleep_ms(50)

驴友花雕 发表于 2020-6-26 18:50:22

mPython实验图形编程



驴友花雕 发表于 2020-6-26 18:54:37

mPython实验图形编程2



驴友花雕 发表于 2020-6-26 18:59:35

mPython实验图形编程3



驴友花雕 发表于 2020-6-26 19:04:35

是男人就下一百层


驴友花雕 发表于 2020-6-26 19:13:14

10、秒表计时器
秒表主要是用来统计秒数的。它有一般有两个按键。A键和B键。
第一次按下A键时,开始计时。
第二次按下A键时,暂停计时。
再按下A键时,继续上一步暂停的计时。
按下B键,归零。

#MicroPython动手做(35)——小游戏
#秒表计时器

from mpython import *
import time
import framebuf
import font.digiface_44
from machine import Timer

def on_button_b_down(_):
    global AKey, timeCount
    time.sleep_ms(10)
    if button_b.value() == 1: return
    timeCount = 0
    oled.fill(0)
    display_font(font.digiface_44, "00:00", 2, 10, False, 2)
    oled.show()
    tim1.deinit()
    AKey = 1

def timer1_tick(_):
    global AKey, timeCount
    # 大于等于60,表示已经计时1小时,超出设计范围,退出计时,并恢复初始
    if timeCount // 60 >= 60:
      oled.fill(0)
      display_font(font.digiface_44, "00:00", 0, 0, False, 2)
      oled.show()
      tim1.deinit()
    else:
      timeCount = timeCount + 1
      # 分的部分,如果是一位数(0-9),则在前面补0
      if timeCount // 60 < 10:
            # 秒的部分,如果是一位数(0-9),则在前面补0
            if timeCount % 60 < 10:
                oled.fill(0)
                display_font(font.digiface_44, (''.join(])), 2, 10, False, 2)
                oled.show()
            else:
                oled.fill(0)
                display_font(font.digiface_44, (''.join(])), 2, 10, False, 2)
                oled.show()
      else:
            if timeCount % 60 < 10:
                oled.fill(0)
                display_font(font.digiface_44, (''.join(])), 2, 10, False, 2)
                oled.show()
            else:
                oled.fill(0)
                display_font(font.digiface_44, (''.join(])), 2, 10, False, 2)
                oled.show()

tim1 = Timer(1)

def on_button_a_down(_):
    global AKey, timeCount
    time.sleep_ms(10)
    if button_a.value() == 1: return
    if AKey == 1:
      AKey = 0
      tim1.init(period=1000, mode=Timer.PERIODIC, callback=timer1_tick)
    else:
      AKey = 1
      tim1.deinit()

def display_font(_font, _str, _x, _y, _wrap, _z=0):
    _start = _x
    for _c in _str:
      _d = _font.get_ch(_c)
      if _wrap and _x > 128 - _d: _x = _start; _y += _d
      if _c == '1' and _z > 0: oled.fill_rect(_x, _y, _d, _d, 0)
      oled.blit(framebuf.FrameBuffer(bytearray(_d), _d, _d,
      framebuf.MONO_HLSB), (_x+int(_d/_z)) if _c=='1' and _z>0 else _x, _y)
      _x += _d

button_b.irq(trigger=Pin.IRQ_FALLING, handler=on_button_b_down)

button_a.irq(trigger=Pin.IRQ_FALLING, handler=on_button_a_down)


oled.fill(0)
oled.DispChar("秒表计时器", 34, 26, 1)
oled.show()
time.sleep(3)
oled.fill(0)
display_font(font.digiface_44, "00:00", 2, 10, False, 2)
oled.show()
timeCount = 0
# A中,1表示初始状态,接下来要计数,当它变成0时,表示接下来需要暂停
AKey = 1

驴友花雕 发表于 2020-6-26 19:18:04

mPython X 实验图形编程


驴友花雕 发表于 2020-6-26 19:21:53

mPython X 实验图形编程


驴友花雕 发表于 2020-6-26 19:26:13

秒表计时器




驴友花雕 发表于 2020-6-26 20:20:37

11、俄罗斯方块

#MicroPython动手做(35)——小游戏
#俄罗斯方块

from mpython import *
import math
import random, time

class Brick():
    def __init__(self, p_position):
      self.position = p_position

    def draw(self):

      x = self.position * brick_size
      y = self.position * brick_size
      oled.fill_rect(brick_size * (field_height - 1) - x, y, brick_size, brick_size, 1)


class Block():
    def __init__(self, p_bricks_layout, p_direction):
      self.bricks_layout = p_bricks_layout
      self.direction = p_direction
      self.init_position = (field_width // 2 - 2, 0)
      self.cur_layout = self.bricks_layout
      self.position = self.init_position
      self.stopped = False
      self.move_interval = 500
      self.last_move = 0
      self.bricks = []
      for (x, y) in self.cur_layout:
            self.bricks.append(Brick((self.position + x, self.position + y)))

    def draw(self):
      for brick in self.bricks:
            brick.draw()

    def isLegal(self, layout, position):
      (x0, y0) = position
      for (x, y) in layout:
            if x + x0 < 0 or y + y0 < 0 or x + x0 >= field_width or y + y0 >= field_height:
                return False
            if field_map != 0:
                return False
      return True

    def left(self):
      new_position = (self.position - 1, self.position)
      if self.isLegal(self.cur_layout, new_position):
            self.position = new_position
            self.refresh_bircks()

    def right(self):
      new_position = (self.position + 1, self.position)
      if self.isLegal(self.cur_layout, new_position):
            self.position = new_position
            self.refresh_bircks()

    def down(self):
      (x, y) = (self.position, self.position + 1)
      while self.isLegal(self.cur_layout, (x, y)):
            self.position = (x, y)
            self.refresh_bircks()
            y += 1

    def refresh_bircks(self):
      for (brick, (x, y)) in zip(self.bricks, self.cur_layout):
            brick.position = (self.position + x, self.position + y)

    def stop(self):
      global field_bricks
      global score
      self.stopped = True
      ys = []
      for brick in self.bricks:
            field_bricks.append(brick)
            (x, y) = brick.position
            if y not in ys:
                ys.append(y)
            field_map = 1

      eliminate_count = 0
      ys.sort()

      for y in ys:
            if 0 in field_map:
                continue
            eliminate_count += 1
            for fy in range(y, 0, -1):
                field_map = field_map[:]
            field_map =

            tmp_field_bricks = []
            for fb in field_bricks:
                (fx, fy) = fb.position
                if fy < y:
                  fb.position = (fx, fy + 1)
                  tmp_field_bricks.append(fb)
                elif fy > y:
                  tmp_field_bricks.append(fb)
            field_bricks = tmp_field_bricks
      if eliminate_count == 1:
            score += 1
      elif eliminate_count == 2:
            score += 2
      elif eliminate_count == 3:
            score += 4
      elif eliminate_count == 4:
            score += 6

    def update(self, time):
      self.draw()
      if time - self.last_move >= self.move_interval:
            new_position = (self.position, self.position + 1)
            if self.isLegal(self.cur_layout, new_position):
                self.position = new_position
                self.refresh_bircks()
                self.last_move = time
            else:
                self.stop()

    def rotate(self):
      new_direction = (self.direction + 1) % len(self.bricks_layout)
      new_layout = self.bricks_layout
      if not self.isLegal(new_layout, self.position):
            return
      self.direction = new_direction
      self.cur_layout = new_layout
      for (brick, (x, y)) in zip(self.bricks, self.cur_layout):
            brick.position = (self.position + x, self.position + y)
      self.refresh_bircks()
      self.draw()


# 0: oooo
# 1: oo
#    oo
# 2: o
#   ooo
# 3: o
#    oo
#   o
# 4:o
#    oo
#    o
# 5: ooo
#    o
# 6: ooo
#      o
bricks_layout_0 = (((0, 0), (0, 1), (0, 2), (0, 3)), ((0, 1), (1, 1), (2, 1), (3, 1)))
bricks_layout_1 = (((1, 0), (2, 0), (1, 1), (2, 1)), )
bricks_layout_2 = (
    ((1, 0), (0, 1), (1, 1), (2, 1)),
    ((0, 1), (1, 0), (1, 1), (1, 2)),
    ((1, 2), (0, 1), (1, 1), (2, 1)),
    ((2, 1), (1, 0), (1, 1), (1, 2)),
)
bricks_layout_3 = (
    ((0, 1), (1, 1), (1, 0), (2, 0)),
    ((0, 0), (0, 1), (1, 1), (1, 2)),
)
bricks_layout_4 = (
    ((0, 0), (1, 0), (1, 1), (2, 1)),
    ((1, 0), (1, 1), (0, 1), (0, 2)),
)
bricks_layout_5 = (
    ((0, 0), (1, 0), (1, 1), (1, 2)),
    ((0, 2), (0, 1), (1, 1), (2, 1)),
    ((1, 0), (1, 1), (1, 2), (2, 2)),
    ((2, 0), (2, 1), (1, 1), (0, 1)),
)
bricks_layout_6 = (
    ((2, 0), (1, 0), (1, 1), (1, 2)),
    ((0, 0), (0, 1), (1, 1), (2, 1)),
    ((0, 2), (1, 2), (1, 1), (1, 0)),
    ((2, 2), (2, 1), (1, 1), (0, 1)),
)

field_width, field_height = 16, 30
brick_size = 4
field_map = [ for i in range(field_height)]
field_bricks = []
score = 0
running = True
threshhold = 400


def drawField():
    for brick in field_bricks:
      brick.draw()


def getBlock():
    block_type = random.randint(0, 6)
    if block_type == 0:
      return Block(bricks_layout_0, random.randint(0, len(bricks_layout_0) - 1))
    elif block_type == 1:
      return Block(bricks_layout_1, random.randint(0, len(bricks_layout_1) - 1))
    elif block_type == 2:
      return Block(bricks_layout_2, random.randint(0, len(bricks_layout_2) - 1))
    elif block_type == 3:
      return Block(bricks_layout_3, random.randint(0, len(bricks_layout_3) - 1))
    elif block_type == 4:
      return Block(bricks_layout_4, random.randint(0, len(bricks_layout_4) - 1))
    elif block_type == 5:
      return Block(bricks_layout_5, random.randint(0, len(bricks_layout_5) - 1))
    elif block_type == 6:
      return Block(bricks_layout_6, random.randint(0, len(bricks_layout_6) - 1))


def run():
    global running
    btn_n_stat, btn_o_stat, btn_t_stat, btn_p_stat = * 4

    while running:

      cur_block = getBlock()

      if not cur_block.isLegal(cur_block.cur_layout, cur_block.position):
            cur_block.draw()
            running = False
            continue

      while not cur_block.stopped:

            oled.fill(0)
            ticks = time.ticks_ms()
            cur_block.update(ticks)
            drawField()
            oled.show()

            if touchPad_T.read() < threshhold and btn_t_stat == 0:
                cur_block.rotate()
                btn_t_stat = 1
            elif touchPad_T.read() >= threshhold:
                btn_t_stat = 0

            if touchPad_P.read() < threshhold and btn_p_stat == 0:
                cur_block.down()
                btn_p_stat = 1
            elif touchPad_P.read() >= threshhold:
                btn_p_stat = 0

            if touchPad_N.read() < threshhold and btn_n_stat == 0:
                cur_block.left()
                btn_n_stat = 1
            elif touchPad_N.read() >= threshhold:
                btn_n_stat = 0

            if touchPad_O.read() < threshhold and btn_o_stat == 0:
                cur_block.right()
                btn_o_stat = 1
            elif touchPad_O.read() >= threshhold:
                btn_o_stat = 0
    oled.fill(0)
    oled.text('Game over!', 25, 20)
    oled.text('Score:%d' % score, 25, 32)
    oled.show()


if __name__ == '__main__':
    run()

驴友花雕 发表于 2020-6-26 20:47:33


驴友花雕 发表于 2020-6-27 08:13:33

12、 乒乓球


#MicroPython动手做(35)——小游戏
# 乒乓球

from mpython import *
import music


class Pong():
    def __init__(self):

      self.running = True
      self.start = False
      self.ball_rad = 5
      self.bats_position = 0
      self.bats_width = 15
      self.bats_height = 4

      self.ball_x = self.bats_width // 2
      self.ball_y = 64 - (self.ball_rad + self.bats_height + 1)
      self.inc_x, self.inc_y = 1, 1
      self.score = 0

    def collision(self):

      if self.ball_x >= 128 - self.ball_rad or self.ball_x < self.ball_rad:
            self.inc_x = -self.inc_x
      if self.ball_y >= 64 - (self.ball_rad + self.bats_height) or self.ball_y <= self.ball_rad:
            self.inc_y = -self.inc_y

    def update(self):
      self.ball_x = self.ball_x + self.inc_x
      self.ball_y = self.ball_y + self.inc_y
      self.bats_position = min(max(self.bats_position, 0), 128 - self.bats_width)

    def is_hit(self):
      # print('ball:', self.ball_x, self.ball_y, 'bats:', self.bats_position)
      if self.ball_y >= 64 - (self.ball_rad + self.bats_height):
            if self.ball_x >= self.bats_position + self.bats_width + self.ball_rad or self.ball_x <= self.bats_position - self.ball_rad:

                return False
            self.score += 1
            return True

    def run(self):

      while self.running:
            if button_a.value() == 0 and button_b.value() == 1:
                self.bats_position -= 2
                self.start = True
            if button_a.value() == 1 and button_b.value() == 0:
                self.bats_position += 2
                self.start = True

            if self.start:
                self.update()
                self.collision()

                if self.is_hit() == False:
                  self.running = False
                  continue

            oled.fill(0)
            oled.fill_circle(self.ball_x, self.ball_y, self.ball_rad, 1)
            oled.fill_rect(self.bats_position, 64 - self.bats_height, self.bats_width, self.bats_height, 1)
            oled.show()

      oled.text('Game over!', 20, 20)
      oled.text('Score %d' % self.score, 20, 32)
      oled.show()


if __name__ == '__main__':
    pong = Pong()
    pong.run()

驴友花雕 发表于 2020-6-27 08:34:29

本帖最后由 驴友花雕 于 2020-6-27 08:35 编辑

#MicroPython动手做(35)——小游戏
# 乒乓球(实验视频)

https://v.youku.com/v_show/id_XN ... oneSokuUgc_1.dtitle

https://v.youku.com/v_show/id_XNDcyODQ0MzYyNA==.html?spm=a2h0c.8166622.PhoneSokuUgc_1.dtitle

驴友花雕 发表于 2020-6-27 08:41:14


13、飞行小鸟

#MicroPython动手做(35)——小游戏
#飞行小鸟

from mpython import *
from framebuf import FrameBuffer
import framebuf
import time, uos,urandom

# 16 x 12
BIRD = bytearray([
    0x7, 0xe0, 0x18, 0xf0, 0x21, 0xf8, 0x71, 0xec, 0xf9, 0xec, 0xfc, 0xfc, 0xbe, 0x7e, 0x4c, 0x81, 0x71, 0x7e, 0x40,
    0x82, 0x30, 0x7c, 0xf, 0x80
])

# 16 x 32
PIPE_TOP = bytearray([
    0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20,
    0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c,
    0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0xff, 0xff, 0x80, 0xf, 0x80,
    0xf, 0x80, 0xf, 0x80, 0xf, 0xff, 0xff
])
PIPE_DOWN = bytearray([
    0xff, 0xff, 0x80, 0xf, 0x80, 0xf, 0x80, 0xf, 0x80, 0xf, 0xff, 0xff, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c,
    0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20,
    0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c,
    0x20, 0x1c, 0x20, 0x1c, 0x20, 0x1c
])


# Bitmap images
bird_size = (16, 12)
pipe_size = (16, 32)


WIDTH = 128
HEIGHT = 64


"""飞行小鸟类"""
class Bird:
    def __init__(self):
      self.height = bird_size
      self.y = HEIGHT // 2 - self.height // 2
      self.wing_power = 4
      self.gravity = 0.8
      self.vel = -self.wing_power

    # 下落
    def drop(self):
      self.vel += self.gravity
      self.y = int(self.y + self.vel)

    # 飞行
    def flap(self):
      self.vel = -self.wing_power

    # 是否坠落
    def crashed(self):                        
      y_limit = HEIGHT - self.height
      return self.y > y_limit

"""障碍类"""
class Obstacle:
    def __init__(self, x,size ):
      self.size =size
      self.gap = urandom.randint(6 + self.size, HEIGHT - 6 - self.size)   # 随机生成间隙大小
      self.x = x            # 距离鸟大小
      self.score = 0          # 分数
      self.rate = 3         # 速率

    # 移动
    def scroll(self):         
      self.x -= self.rate   
      if self.x < -pipe_size:
            self.score += 1
            self.x = WIDTH
            self.gap = urandom.randint(6 + self.size, HEIGHT - 6 - self.size)

    # 是否碰撞
    def collided(self, y):                     
      if self.x < bird_size and self.x > -pipe_size and \
         (self.gap - y > self.size or y + bird_size - self.gap > self.size):
            return True
      else:
            return False


class Game():
    def __init__(self,gap_size):
      
      # 创建鸟和管道的framebuffer
      self.bird_fb = FrameBuffer(BIRD, bird_size, bird_size, framebuf.MONO_HLSB)         
      self.pipe_top_fb = FrameBuffer(PIPE_TOP, pipe_size, pipe_size, framebuf.MONO_HLSB)
      self.pipe_down_fb = FrameBuffer(PIPE_DOWN, pipe_size, pipe_size, framebuf.MONO_HLSB)

      self.gap_size = gap_size
      self.high_score = 0
      self.pressed= False
      self.game_state = 0
      self.flappy_bird =None
      self.obstacle_1 =None
      self.obstacle_2 =None

    # 保存最高分
    def write_high_score(self,n):
      f = open('fb_high_score.txt', 'w')
      f.write(str(n))
      f.close()

    # 读取最高分
    def read_high_score(self):
      if 'fb_high_score' in uos.listdir():
            f = open('fb_high_score.txt', 'r')
            high_score = f.read()
            f.close()
            return int(high_score)
      else:
            self.write_high_score(0)
            return 0

   # 绘制
    def draw(self):
      oled.fill(0)
      oled.blit(self.bird_fb, 0, self.flappy_bird.y)
      oled.blit(self.pipe_top_fb, self.obstacle_1.x, self.obstacle_1.gap - self.gap_size - pipe_size)
      oled.blit(self.pipe_down_fb, self.obstacle_1.x, self.obstacle_1.gap + self.gap_size)
      oled.blit(self.pipe_top_fb, self.obstacle_2.x, self.obstacle_2.gap - self.gap_size - pipe_size)
      oled.blit(self.pipe_down_fb, self.obstacle_2.x, self.obstacle_2.gap + self.gap_size)
      oled.fill_rect(WIDTH // 2 - 13, 0, 26, 9, 0)
      oled.text('%03d' % (self.obstacle_1.score + self.obstacle_2.score), WIDTH // 2 - 12, 0)
      oled.show()
   

    def _clicked(self):
      if button_a.value() == 0 and not self.pressed:
            self.pressed = True
            return True
      elif button_a.value() == 1 and self.pressed:
            self.pressed = False
      return False

    # 开机画面
    def game_start(self):
      oled.fill(0)
      oled.blit(self.pipe_down_fb, (WIDTH - pipe_size) // 2, HEIGHT - 12)
      oled.blit(self.bird_fb, (WIDTH - bird_size) // 2, HEIGHT - 12 - bird_size)
      oled.rect(0, 0, WIDTH, HEIGHT, 1)
      oled.text('F L A P P Y', WIDTH // 2 - 44, 3)
      oled.text('B I R D', WIDTH // 2 - 28, 13)
      oled.text('Record: ' + '%03d' % self.high_score, WIDTH // 2 - 44, HEIGHT // 2 - 6)
      oled.show()
      self.game_state = 1
      
    def game_waiting(self):
      if self._clicked():
            self.flappy_bird = Bird()                                                               # 实例小鸟对象
            self.obstacle_1 = Obstacle(WIDTH,self.gap_size)                                           # 实例第一个障碍对象
            self.obstacle_2 = Obstacle(WIDTH + (WIDTH + pipe_size) // 2,self.gap_size)             # 实例第二个障碍对象
            self.game_state = 2

    def game_running(self):
      if self._clicked():
            self.flappy_bird.flap()
      self.flappy_bird.drop()
      if self.flappy_bird.crashed():
            self.flappy_bird.y = HEIGHT - self.flappy_bird.height      # 边界限制
            self.game_state = 3
      self.obstacle_1.scroll()
      self.obstacle_2.scroll()
      if self.obstacle_1.collided(self.flappy_bird.y) or self.obstacle_2.collided(self.flappy_bird.y):
            self.game_state = 3
      self.draw()

    def game_over(self):
      oled.fill_rect(WIDTH // 2 - 32, 10, 64, 23, 0)
      oled.rect(WIDTH // 2 - 32, 10, 64, 23, 1)
      oled.text('G A M E', WIDTH // 2 - 28, 13)
      oled.text('O V E R', WIDTH // 2 - 28, 23)
      self.score = self.obstacle_1.score + self.obstacle_2.score
      if self.score > self.high_score:
            self.high_score = self.score
            oled.fill_rect(WIDTH // 2 - 48, 37, 96, 14, 0)
            oled.rect(WIDTH // 2 - 48, 37, 96, 14, 1)
            oled.text('New record!', WIDTH // 2 - 44, 40)
            self.write_high_score(self.high_score)
      oled.show()

      try:
            self.send_score(self.score)
      except:
            pass
      self.game_state = 1


    def run(self):
      while True:
            if self.game_state == 0: self.game_start()
            elif self.game_state == 1: self.game_waiting()
            elif self.game_state == 2: self.game_running()
            elif self.game_state == 3: self.game_over()



if __name__ == '__main__':
    game=Game(gap_size = 16)
    game.run()

驴友花雕 发表于 2020-6-27 09:42:57


且听风吟丶 发表于 2020-6-27 21:41:43

希望我也能做一个出来

驴友花雕 发表于 2020-6-28 05:25:06

且听风吟丶 发表于 2020-6-27 21:41
希望我也能做一个出来

一定可以的

驴友花雕 发表于 2020-6-28 12:29:22

14、打砖块(大于)


#MicroPython动手做(35)——小游戏
#打砖块

import time
import random
from mpython import *

random.seed(time.ticks_cpu())


my_listy = []
my_listx = []
m = 0
n = 0
score = 0
x = random.randint(35, 90)
y = 60
cx = 1
cy = -1
Lx = 50
for count in range(3):
    m = 0
    for count in range(16):
      my_listx.append(m)
      m = m + 8
n = 0
for count in range(3):
    for count in range(16):
      my_listy.append(n)
    n = n + 8
while True:
    m = 0
    n = 0
    oled.fill(0)
    for count in range(48):
      oled.rect(my_listx, my_listy, 8, 8, 1)
      if y <= my_listy + 10:
            if x >= my_listx and x <= my_listx + 8:
                my_listx = (-40)
                my_listy = (-40)
                cy = 1
                score = score + 1
      m = m + 1
      n = n + 1
    oled.fill_rect(Lx, 62, 30, 2, 1)
    oled.circle(x, y, 3, 1)
    oled.show()
    if button_a.value() == 0:
      Lx = Lx + -3
      if Lx <= 0:
            Lx = 0
    if button_b.value() == 0:
      Lx = Lx + 3
      if Lx >= 107:
            Lx = 107
    x = x + cx
    y = y + cy
    if x <= 2:
      cx = 1
    if x >= 125:
      cx = -1
    if y <= 2:
      cy = 1
    if y > 60:
      if x >= Lx - 2 and x <= Lx + 32:
            cy = -1
      else:
            oled.fill(0)
            oled.DispChar(str("游戏结束,得分为:") + str(score), 0, 16, 1)
            oled.show()
            break

驴友花雕 发表于 2020-6-28 12:33:01

mPython X 实验图形编程


驴友花雕 发表于 2020-6-28 12:36:28

mPython X 实验图形编程2


页: 1 [2] 3
查看完整版本: MicroPython动手做(35)——体验小游戏