使用M5StickC绘制带有物理特性的小球(只与屏幕边框碰撞)
约莫有一年没有碰M5StickC了,最近打算用micropython制作一个生日礼物,所以特意回来熟悉熟悉一些基本操作。
不知道是多久以前写过一个Flutter版本的物理小球,写完以后感慨原来小球的物理效果是这样实现的。所以这次决定要在M5StickC上实现这个效果。(好像并没有什么直接联系,嘿嘿嘿)
分析
运动的小球具有速度(矢量)这一关键物理属性,还有颜色和大小两个次要的物理属性。在编程过程中,需将速度(矢量)分解为x轴方向速度和y轴方向速度。
过程
直接构建出小球的类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| class Ball: def __init__(self,x,y,r): self.x = x self.y = y self.r = r self.vx = randint(1,4) self.vy = randint(1,4) self.old_x = x self.old_y = y self.color = randint(0,16579836) def update(self): self.old_x = self.x self.old_y = self.y self.x = self.x + self.vx self.y = self.y + self.vy if self.x - self.r <= 0 or self.x + self.r > 80: self.vx = -self.vx if self.y - self.r <= 0 or self.y + self.r > 160: self.vy = -self.vy def render(self): self._clear() lcd.setColor(self.color) lcd.fillCircle(self.x, self.y, self.r) def _clear(self): lcd.setColor(lcd.BLACK) lcd.fillCircle(self.old_x, self.old_y, self.r)
|
此时只要在主程序中创建一个Ball对象,然后循环调用Ball对象的update和render,就可以看到具有物理效果(伪)小球在屏幕中运动
下面编写游戏主循环,每当按下按钮A,就会生成一个新的球,按住则会一直生成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| balls = [] print(len(balls)) press_delay = 0 while True: press_delay +=1 if buttonA.read() and press_delay > 10: balls.append(Ball(randint(6,75),randint(6,155),randint(1,5))) press_delay = 0 if buttonB.read() and press_delay > 10: press_delay = 0 if len(balls) != 0: balls[0].clear() balls.pop(0) for ball in balls: ball.update() ball.render()
|
下面是固定数量的小球
1 2 3 4 5 6 7 8
| balls = [] for _ in range(randint(10,15)): balls.append(Ball(randint(6,80),randint(6,160),randint(1,5))) while True: for ball in balls: ball.update() ball.render()
|
代码头部引用的moduels
1 2 3 4
| from m5stack import lcd lcd.clear(lcd.BLACK) import time from urandom import randint
|
完整代码地址
效果
设备:M5StickC
环境:
参考资料
Flutter动画之粒子精讲