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

电子宠物——把状态、计时和互动组合成生命 把状态、计时和互动组合成生命

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

在没有 AI 的情况下,也能"养"出生命?

你好,我是吴老师。

上一课我们用了一堆云端 AI(语音、大模型、生图)做出菜谱。这一课我们反着来——不用任何 AI,就在板子上"养"一个电子宠物,它会饿、会开心、会睡觉。

听起来像魔法?其实不是。它的"生命",全靠三个东西:

  1. 一组状态:饥饿度、心情、年龄……
  2. 让状态自己变化的东西:时间(用 millis())
  3. 让状态被人改变的东西:触摸(喂食、玩耍)

本课一句话:电子宠物不是"AI 会思考",而是"一组数字,被时间悄悄改变,又被你的手指改变"。宠物"活不活着",取决于你有没有让"时间和互动"去动这些数字。这跟菜谱课的"AI 生成"完全不同——这是本地规则。

一、先"养"出一个宠物

先别听我讲,让板子演示一遍。

请使用课程的 esp32s3-touchboard-hardware-dev Skill,
烧录本课配套程序 assets/codes/demo01_pet:
板子屏幕上有一只"电子宠物"(一个用图形凑成的小家伙),
面板上显示它的「饥饿度」「心情」,还有三个按钮:喂食、玩耍、睡觉。
你点"喂食"它的问题会变小,点"玩耍"它心情变好,
但你不碰它,它的饥饿度会慢慢涨、心情会慢慢掉。
烧录后用中文注释。烧录后告诉我:不碰它会怎样?点"喂食"后哪里变了?

几秒后,屏幕上出现一只小东西,旁边有"饥饿度""心情"两栏和"喂食/玩耍/睡觉"三个按钮。你一直不碰它,会看到饥饿度一点点涨、心情一点点掉;你点"喂食",饥饿度立刻降下来。

二、拆开看:宠物"活着"靠三件事

1. 状态——一组会变的数字

宠物不是"一幅图",而是六个数字(一个结构体):

宠物 = {
  饥饿度:  50    // 0(不饿)~ 100(很饿)
  心情:    80    // 0(难过)~ 100(开心)
  年龄:    0     // 出生多久
  上次喂食: 0    // 上次喂食是开机后第几毫秒
  上次玩耍: 0
  上次睡觉: 0
}

这跟背单词课的"掌握度"、番茄钟课的"完成数"是同一个概念——状态 = 记住一个"现在怎么样"的数。

2. 时间让状态自然变化(关键!)

宠物最神奇的一点:你不碰它,它也在变。 靠的就是 millis() 这个"不断增长的数"。

每一帧(比如每 100 毫秒):
    现在时刻 = millis()

    如果(现在时刻 - 上次喂食)> 某个间隔:
        饥饿度 + 1        // 一段时间没喂 → 变饿

    如果(现在时刻 - 上次玩耍)> 某个间隔:
        心情 - 1          // 一段时间没玩 → 变不开心

看出重点了吗? 是时间流逝在推动数字变化,不是你在操作它。"饿"不是宠物"感觉"到的,是"上次喂食的时间距离现在够久了,所以饥饿度加一"判断出来的。 这就叫"状态随时间推移而变化"。

3. 触摸让状态被人改变

你点"喂食",就是主动改这个数字:

点喂食:
    饥饿度 = 饥饿度 - 30     // 吃饱了,不饿
    上次喂食 = 现在时刻       // 记下这次喂食时间,重新计时

所以宠物"活了"的逻辑,其实就是:时间让它慢慢变差,你用手指让它变好。 你不理它,它就会饿、会难过;你照顾它,它就精神。

三、为什么"时间"能让它"活"起来?——再讲透一点

这一课最值得琢磨的,就是这个:凭什么几个数字被时间推着走,它就"像活的"?

关键在于:状态和时间是"耦合"的。 你喂食,会重置"上次喂食"这个时间点,于是"变饿"的时钟重新开始走。宠物之所以"活",是因为:

你每一次的"照顾",都改变了它接下来的"命运"。 你不喂它,它时钟继续走、继续变饿;你一喂,时钟归零、重新计时。

这跟真实生命很像:你要定时喂、陪它玩,它才健康。它的"生命感",来自"你做的行为和它的状态之间的因果"—— 不是来自什么遥不可及的 AI 魔法。

⚠️ 给比喻划边界:说宠物"活"了,是很形象的形容,但它没有生命、没有感觉。它只是一组数字,在按规则变。你连续一个月不理它,它不是"死了",只是"饥饿度到了 100、心情到了 0"这两组数字而已。它不会心碎,也不会恨你。

四、不让它"死":再加一个规则

电子宠物的"寿命"其实很残酷——不理它,它就一直恶化。为了让你有"照顾"的动力,我们加一条规则:当饥饿度或心情到某个极限,就提示"宠物生病了,快照顾它"。

如果 饥饿度 > 80 或 心情 < 20:
    屏幕提示"它有点难受,快喂它/陪它玩"
    宠物表情变"苦脸"

你看,这又是一个条件判断——数字到了某个值,就触发一件事。跟番茄钟"到点提醒"、背单词"答错进错题本"是同类的判断。

五、分析:这个电子宠物用了哪些技术?

不用 AI,但它用到的编程概念其实不少:

技术 / 概念在这里干什么你之前在哪学过
结构体把饥饿度/心情/年龄打包成"一个宠物"第 36 课(掌握度状态)
millis() 计时"现在 - 上次发生时间"判断该不该变化第 6/37 课
状态随时间的条件判断时间够久了,就加/减一个数本课核心
触摸区域判断"喂食/玩耍/睡觉"三个按钮第 8 课(按钮=区域判断)
重绘状态一变就重画宠物画面第 6/7 课
图形绘制用 fillCircle/drawString 凑出宠物第 3 章(绘图)
TF 卡(可选)"今天照顾了几次"存本地,断电不忘第 14 课

⚠️ 重要理解:这个宠物不联网、不用云 API、不用大模型。 它活得好不好,完全是板上这段"写死的规则"在起作用。这就是"本地规则"和"AI 云端"的区别——菜谱课靠 AI 生成创意,电子宠物靠你写死的规则体现"生命"。

六、改一个条件,看它能怎么"活"

我想改该动哪部分我预测会发生什么
把"变饿"变慢(让宠物更耐饿)变饿的那个时间间隔胃饿得更慢
心情掉得更快心情减的值更容易难过
喂食加的分更多喂食减的数字一下就不饿了
饥饿度到 100 就"生病"提示那个极限值更早生病提示
加一个"今天喂了 X 次"存 TF 卡状态 + 存储断电不忘

先预测,再验证。 你会发现:改的全是"数字"和"规则"(多快变饿、变多少、何时生病),宠物"活"的底层逻辑(时间推动 + 触摸改变)一点没变。

七、如果它没按你想的来

现象先查什么
宠物不"变"millis() 用对了吗?是不是"现在时刻 - 上次发生时间"而不是"数秒"?
状态永远不变算状态的逻辑放在 loop 里了吗?有没有每帧去查?
点了按钮没反应触摸区域判断对吗?"喂食"按钮的坐标写对了吗?
状态跳变太剧烈判断间隔够不够?是不是每帧都加了 1?
断电后"照顾次数"没了存了内存——要持久得存 TF 卡(第 14 课)

记住:宠物"变"是每帧去查"时间距离",不是"它自己会动"。查得对,它就"活";查得不对,它就"不动"。

八、下课前,把"电子宠物"讲给我听

先别看 AI 的回答,自己说一遍:

  1. 电子宠物的"生命"靠哪三样东西?没有 AI,它怎么"活"?
  2. 宠物"变饿"是"感觉"到还是"判断"出来的?怎么判断?
  3. 为什么你"喂食"会重置时间?它和"变饿的时钟"是什么关系?
  4. 宠物生病提示是怎么来的?本质是什么?
  5. 这个项目用了哪些技术?哪个是"它像活的一样"的关键?
  6. 电子宠物和菜谱课(用 AI)最大区别是什么?

今天请留下三样东西:一只你调"养"过的宠物(改过一个参数)、一句"它为什么像活的"的解释、以及一个你加的规则(比如"生病提示")。

九、最后留给你:状态 + 时间 = 一切"会动"的东西

这一课你掌握了一个超通用的编程思维:

任何"看起来会自己动"的程序,背后都是"一组状态 + 时间推动 + 条件和手指改变"。

程序状态时间推动你改变它
电子宠物饥饿度/心情时间变饿变难过喂食/玩耍
番茄钟剩余时间每秒减少开始/暂停
背单词"掌握度"0/1/2/3(答错掉回去)答题
游戏里的血条生命值受击减少加血
签到打卡连续天数一天一天过当天签到

一旦你摸清这个模式,几乎所有"会动"的程序你都能看透了。

下一课我们再加上 AI——让板子不仅"记住"你的心情,还能听懂它、回应它。但你会发现:情绪识别靠 AI,情绪管理还是靠"状态 + 规则"。


教师备课备注(不作为课堂口播)

课程定位

  • 第九章「AI 生活」唯一的纯本地课。与第 43 课(用 AI)形成对照:菜谱课"靠云端生成创意",电子宠物"靠本地规则体现生命"。核心落点是"状态随时间推移而变化"这一编程思维,不是宠物画得多好看。
  • 不联网、不用云 API、不用大模型。难点不是代码,而是让学生理解"为什么一组数字被时间推着走,它就像活的"——答案是"状态与时间耦合,你的行为改变它的命运"。
  • 与第 36 课(掌握度)、第 37 课(番茄钟状态机)、第 14 课(TF 卡)呼应。millis() 计时 + 状态更新是知识点核心。

本课新增的核心知识点

  1. 状态 = 一组会变的数字(结构体:饥饿度/心情/年龄等)。
  2. 时间推动状态(现在时刻 - 上次发生时间 超阈值就增减)——"状态随时间而变化",这是"像活的"的关键。
  3. 触摸改变状态(喂食重置 上次喂食,让时钟重走)——"你的行为改变它的命运"。
  4. 条件判断触发事件(饥饿/心情到极限 → 生病提示)。
  5. 本地规则 vs AI 云端:电子宠物纯本地,与第 43 课对照。

必须避免的错误

  • 不要说"宠物会思考/有感觉/伤心了"。它是一组数字在按规则变。要说"它只是饥饿度到了某个值"。
  • 不要说"宠物自己会动"。是每帧去检查"时间距离",到了就改数字。
  • 不要引入复杂的 AI 或联网。本课重点就是"本地规则 + 状态 + 时间"。
  • 不要过度追求"宠物画得好看"。重点讲"状态如何被时间改变"。

执行约束

  • FQBN:esp32:esp32:esp32s3:FlashSize=16M,PartitionScheme=app3M_fat9M_16MB,CDCOnBoot=cdc,PSRAM=opi
  • 依赖:TFT_eSPI、FT6336、Adafruit_NeoPixel(可选,灯反馈)、font/ChineseFont16.h;本课不需要网络/云 API。
  • 屏幕/触摸引脚同前课;中文用 drawUtf8(与第 34 课一致的 util)。
  • 若加"照顾次数存 TF 卡",用 SD_MMC 6 线 setPins(38,40,39,41,48,47)(第 14 课)。

课堂执行要点

  • 顺序建议:demo01(现象:不碰它变饿、喂食变好)→ 状态拆解 → 时间推动讲透 → 触摸改变 → 生病提示规则 → 改一个条件 → 下课前复述。
  • 灵魂追问 ①:"它不碰为什么会变?"——引出 millis(现在-上次) 的超阈值判。
  • 灵魂追问 ②:"为什么喂食能救它?"——引出"重置上次喂食时间"= 影响它接下来的命运。
  • 观察表先预测后实测。
  • 可与第 43 课对照小实验:同一个"饲养",一个靠 AI、一个靠规则,哪种更像"真的"?——引导认识"本地规则的可控性"vs"AI 的生成性"。

待办与遗留

  • demo01_pet 源码已写(纯本地,状态机+触摸+图形),尚未实板验证。吴老师实板验收重点:① 状态随时间变化是否平滑;② 触摸区域判断;③ 生病提示触发;④ 图形绘制是否像"宠物"。
  • 若做"认识几天/照顾次数存 TF 卡"扩展,需接第 14 课,待实板验证 SD 读写。

第 44 课 · 电子宠物

第 44 课 · 电子宠物

养一只屏幕上的小家伙:喂食、玩耍、睡觉能哄好它,不管它就会慢慢变饿、心情变差。

44状态机计时触摸