AI脑洞板
完整教案
自学课件
第 42 课 · 共 42/51 课

绘画软件 把触摸变成创作工具

课时
待定
器材
ESP32-S3 触摸屏板 + USB 线
前置知识
无
配套代码
见项目 demo 目录

你好,我是吴老师。这份是给你自己读的——不用等我讲,看不懂就整段复制给 AI,加一句"请一次只解释一个概念,讲完问我一个小问题"。

读完之后,你应该能:

  • 说清"用触摸画出一条连续的线"是怎么做到的;
  • 明白"画笔 = 记住上一帧位置,把上一帧和当前连成一条线";
  • 说清颜色、粗细、橡皮为什么都只是"换一个状态";
  • 明白大画布为什么用 ps_malloc(PSRAM),而不是放到栈上。

用时:约 60 分钟。 准备:烧录 demo01_touch_pen 的板子 + 一根 USB 线。

一、让板子变成你的画板

前面几课,我们用板子放音乐、讲绘本、对讲、聊天——都是在用别人做好的东西。今天换个玩法:让板子变成画板,你想画什么,就亲手画出来。

第 5 课你会画一个固定的点,第 8 课你学会用手指告诉板子"我点了哪"。今天把这两样接起来:手指按到哪,笔就画到哪,而且是一条连续的线。

先看现象:烧录后手指在屏幕上拖动,就画出一笔;右上角有个 RST,点一下画板清空。

二、我观察到的现象

✏️ 可以直接在表格里填写
现象勾选
手指按到屏幕,那个位置出现一截笔迹
手指拖动,笔迹连成一条连续线
手抬起来再按别处,不会凭空拉一条长线
笔迹是红或蓝(由 color_mask 决定)
点右上角 RST,画板清空

关键问题:手指明明是"点一下接一下",屏幕怎么画成一条连续的线? 答案:板子记住了你上一笔在哪,再把"上一个位置"和"现在的位置"两个点连起来。

三、一笔一画,走过的路

环节谁在干学过
手指在哪FT6336 触摸第 8 课
坐标传进程序touch_last_x / touch_last_y第 8 课
记住上一笔在哪lastpos[]本课
把两点连成线LCD_Draw_Line本课
显示出来TFT_eSPI 画一串小圆点第 5 课

整支画笔几乎没有新知识——触摸是第 8 课、画点是第 5 课。真正新增的只有"怎么把一个点接到上一个点"。

四、画笔,就像一支墨水笔

画画就像用墨水笔在纸上滑。手指是笔尖,屏幕是纸。

  • 手指按到屏幕 = 笔尖落纸,留下一点墨;
  • 手指拖着走 = 笔尖不断往前,墨不断留下 → 成一条线;
  • 手指抬起来 = 笔尖离开纸,不再留墨;
  • 再按到别处 = 从新的地方重新落笔。

⚠️ 比喻有边界:"墨水笔"是帮你理解落笔/拖动/抬笔三个状态,不是真涂了墨水。屏幕上其实是一串小圆点(每帧画一个圆),挨得近才像连续线。手指拖得快,点之间会有空隙。"橡皮"也不是擦掉墨水,是用背景色(比如白色)再盖画一遍。

一句话记住:画笔 = 落笔 → 拖动(把上一帧和当前连成线)→ 抬笔。

一支画笔在程序里:落笔→记住位置→连线→抬手用 0xFFFF 重置,把上一帧和当前连成线

五、两个代码名,够了

1. LCD_Draw_Line(x1, y1, x2, y2, Size, colour)——把两点连成线

x1, y1 = 上一帧手指位置
x2, y2 = 现在手指位置
Size   = 笔的粗细(demo 里写死成 2)
colour = 笔的颜色(color_mask 数组里的一个)
它做的:用 Bresenham 算法算出两点间的每一个圆点,
        再沿这条线一个个 fillCircle 画出来(Size 越大,点越粗)。

别看它叫"画线",其实是在这条线上画一串小圆点。所以"笔的粗细"不是线多宽,而是"每个圆点有多大"。

颜色数组:color_mask[] = {0xF800, 0x001F},0xF800 是红、0x001F 是蓝。把 color_mask[0] 改成 color_mask[1],笔就变蓝。

LCD_Draw_Line 把两点连成一条点串:Bresenham 算出每个圆点、粗细=每点大小;颜色从 color_mask 数组挑

2. lastpos + 0xFFFF——记住上一帧在哪、笔抬起来了

lastpos[0], lastpos[1] = 记住"上一帧手指在哪"的两个数
0xFFFF                  = 一个特殊记号:笔还没落下 / 笔抬起来了
逻辑(loop 里):
    手指按着:
        刚按下(lastpos==0xFFFF) → 先把 lastpos 设成当前位置
        把上一帧和当前连成线(LCD_Draw_Line)
        更新 lastpos = 当前
    手指抬起:
        lastpos[0] = 0xFFFF   // 记成"笔抬起来了"

为什么抬手要记 0xFFFF?因为不记,抬起来再按别处,程序会从旧位置凭空画一条长线到新位置——那根本不是你想画的。

最该记住的:画笔 = 记住上一帧位置 lastpos,用 LCD_Draw_Line 把上一帧和当前连起来;0xFFFF 记着"笔抬起来了",抬手后重置,好让下一笔从新位置开始。

六、颜色、粗细、橡皮——都是"状态在变"

demo01 只画红色、粗细固定。想换颜色、变粗、加橡皮,思路一模一样——都只是"换一个状态",画线动作不变。

  • 把 color_mask[0] 改成 color_mask[1] → 笔变蓝;
  • 把 2(Size)改成更大的数 → 笔变粗;
  • 把颜色改成背景色(白色)再画一遍 → 就是"橡皮",把旧笔迹盖掉。

这就是"工具切换":画面怎么画永远不变,变的只是"当前用哪种状态"(颜色、粗细、画笔还是橡皮)。

颜色/粗细/橡皮 = 换一个状态(画面怎么画不变);大画布用 ps_malloc 放 PSRAM,别放栈上会 crash

✏️ 可以直接在表格里填写
对照思考(可自己写)勾选
color_mask[1] → 笔变蓝
Size 2→6 → 笔明显变粗
画线颜色改白色 → 等于橡皮

⚠️ 注意:demo 里颜色其实是写死的(每帧都画 color_mask[0])。真正让"点一下颜色就变"的,是"点色块 → 改一个全局状态变量",那需要你扩展时自己加上。别把"规律"当"代码里已有"。

七、改一个条件:把"连线"去掉

思想实验:把 LCD_Draw_Line 去掉,改成每帧只画当前这个点,会怎样?

✏️ 可以直接在表格里填写
我改了什么我预测实际
去掉连线,每帧只画当前点手指挪得快两点之间有缝 → 必须把上一帧和当前连起来
抬手时不把 lastpos 设成 0xFFFF下次按下用旧位置连到新位置,画出不该有的直线 → 抬手必须重置

"连成一条线"和"记住上一帧位置"是同一件事的两面:要连线就记住上一帧;要每次重新起笔就抬手清掉它。

八、一条完整的"画一笔"链路

手指按下屏幕 → FT6336 读出坐标 (touch_last_x, touch_last_y)
    → 这次是不是刚按下?lastpos==0xFFFF
        是(新一笔)→ 先把 lastpos 设成当前位置(落笔)
        否(还在同一笔)→ 直接用上次记的 lastpos
    → LCD_Draw_Line(上一个位置, 当前, 粗细2, 颜色)
    → 屏幕沿这条线画一串小圆点(就是笔迹)
    → 把上一个位置更新成当前(lastpos=当前)
    → 手指还按着 → 回去再连下一次,线一直往前画
    → 手指抬起 → lastpos 记成 0xFFFF(笔抬起来了)
    → 下次再按 → 从新位置重新开始

真正要记住的只有一句:画笔 = 记住上一帧位置,把上一帧和当前两个点连成一条线;每动一点就连一点,笔迹就连起来了。

九、过关检查

  1. 一支画笔,程序靠什么知道"笔现在在哪"?
  2. 为什么不能每帧只画一个点,非要连成一条线?
  3. 抬起来再按别处,怎么避免从旧位置拉一条长线?
  4. 想换颜色、变粗、加橡皮,分别改哪个"状态值"?哪个动作永远不变?
  5. 大画布为什么要用 ps_malloc 放到 PSRAM,而不是放栈上?
  6. 想把画保存/截图,为什么不能用 readRect 去读屏幕?

留下三样东西:你画的第一笔的样子、你换颜色后画的那一笔、以及"一支画笔在程序里到底是什么"的一句话。

十、还能玩什么

作品方向描述给 AI 的效果再想想
调色盘屏幕上几个色块,点一下换颜色怎么让"点色块"改变颜色下标?
橡皮擦手指擦掉画过的笔迹背景不是白色时,橡皮怎么"盖"?
笔的粗细点按钮换粗细LCD_Draw_Line 的 Size 怎么跟着状态变?
保存图片画完存成 PNG / 存进 TF 卡为什么截图用内存画布(ps_malloc)而不是 readRect?
你画我猜画好传给另一块板子,让对方猜怎么把这一串坐标打包发过去?

下节课预告:第 8 章到此收官,你已经在板子上做出一个又一个能玩的作品。下一章(第 9 章)板子要"更聪明"——第 43 课,让板子走进"AI 生活",把它和你每天的学习、生活真正连在一起。

第 42 课 · 触摸绘画软件

第 42 课 · 触摸绘画软件

手指在屏幕上拖动就留下一道线,抬笔就断开,点右上角的 RST 可以清屏重画。

42触摸绘图逐帧