🎯实现功能
- 点击脸谱图片,随机切换脸谱;
- 摇晃手机,触发摇一摇变脸,弹出成功提示;
- ✨作业扩展:点击、摇晃两种变脸方式都统计次数,页面实时展示累计变脸总次数;
- 传感器防抖处理,避免短时间多次触发变脸;
- 页面隐藏时注销传感器监听,释放硬件资源、节约电量。
📝项目准备
新建小程序项目,不使用云服务、不使用模板。 在项目根目录新建images文件夹,放入脸谱图片:01.png ~ 14.png。
app.json
{ "pages": [ "pages/index/index" ], "window": { "navigationBarTextStyle": "black", "navigationStyle": "custom" }, "style": "v2", "renderer": "skyline", "rendererOptions": { "skyline": { "defaultDisplayBlock": true, "defaultContentBox": true, "tagNameStyleIsolation": "legacy", "disableABTest": true, "sdkVersionBegin": "3.0.0", "sdkVersionEnd": "15.255.255" } }, "componentFramework": "glass‑easel", "sitemapLocation": "sitemap.json", "lazyCodeLoading": "requiredComponents" }1、页面布局 index.wxml
- image 组件展示脸谱图片,绑定 tap 点击事件;
- 增加文本显示
累计变脸总次数;
<!--index.wxml--> <navigation-bar title="变脸游戏" back="{{false}}" color="black" background="#FFF"></navigation-bar> <scroll-view class="scrollarea" scroll-y type="list"> <view class="box"> <view class="title">wx.onAccelerometerChange示例</view> <image src="{{faces[index]}}" mode="widthFix" bind:tap="changeFace"></image> <!--作业扩展:动态展示累计变脸次数--> <view class="countText">累计变脸总次数:{{totalCount}}</view> </view> </scroll-view>2、样式代码
pages/index/index.wxss
/*index.wxss*/ page { height: 100vh; display: flex; flex-direction: column; } .scrollarea { flex: 1; overflow-y: hidden; } image { margin: 20rpx; width: 100%; } .countText { font-size: 40rpx; color: rebeccapurple; text-align: center; margin-top: 20rpx; font-weight: bold; }app.wxss 全局样式
/**app.wxss**/ .box { margin: 20rpx; padding: 20rpx; border: 2rpx solid purple; } .title { font-size: 40rpx; font-weight: bolder; text-align: center; margin-bottom: 30rpx; color: rebeccapurple; }3、业务逻辑 index.js【完整核心代码】
关键点:
totalCount记录变脸总次数,点击、摇晃变脸都自增;wx.onAccelerometerChange监听手机加速度变化,识别摇晃动作;wx.offAccelerometerChange页面隐藏取消传感器监听;- 防抖标记
isShaking,防止摇晃一瞬间连续变脸。
// index.js Page({ data: { index: 0, // 作业扩展:累计变脸总次数 totalCount: 0, faces: [ '/images/01.png', '/images/02.png', '/images/03.png', '/images/04.png', '/images/05.png', '/images/06.png', '/images/07.png', '/images/08.png', '/images/09.png', '/images/10.png', '/images/11.png', '/images/12.png', '/images/13.png', '/images/14.png' ] }, // 防抖标记,防止短时间重复触发摇晃变脸 isShaking: false, // 生成 [0,n) 的随机整数 createRandomIndex(n) { return Math.floor(Math.random() * n) }, // 变脸:切换图片,变脸次数+1 changeFace() { let newIdx = this.createRandomIndex(this.data.faces.length) this.setData({ index: newIdx, totalCount: this.data.totalCount + 1 }) }, // 加速度传感器回调函数 accelerometerListener(res) { if (this.isShaking) return; // 判断摇晃阈值,x/y/z任意轴超过阈值判定为摇晃 if (res.x > 0.5 || res.y > 0.5 || res.z > 0.5) { this.isShaking = true; this.changeFace(); wx.showToast({ title: '摇一摇成功', icon: 'success', duration: 2000 }) // 800ms防抖冷却时间 setTimeout(() => { this.isShaking = false }, 800) } }, onShow() { // 页面显示,注册加速度传感器监听 wx.onAccelerometerChange(this.accelerometerListener) }, onHide() { // 页面隐藏,取消监听,释放硬件资源 wx.offAccelerometerChange(this.accelerometerListener) } })🖼运行效果说明
- 页面初始化:加载第一张脸谱,累计变脸总次数初始为 0;
- 点击脸谱图片:随机切换一张脸谱,累计变脸总次数加 1;
- 真机摇晃手机:触发摇一摇,弹出
摇一摇成功提示,脸谱切换,累计变脸总次数加 1; - 页面切后台,自动关闭加速度监听,不会后台持续检测摇晃。
⚠注意:加速度传感器 API 在开发者工具模拟器无法模拟摇晃效果,必须真机调试!
📚核心知识点总结
1. 加速度传感器 API
表格
| API | 作用 |
|---|---|
wx.onAccelerometerChange(cb) | 监听手机加速度变化,手机摇晃会触发回调 |
wx.offAccelerometerChange(cb) | 取消加速度监听,必须成对使用,节约电量 |
回调返回res.x、res.y、res.z分别代表三个轴的加速度,数值绝对值越大代表摇晃幅度越大。
2. 随机数生成
Math.floor(Math.random() * n):生成 0 ~ n‑1 之间的整数,用来随机取脸谱数组下标。
3. 防抖处理
摇晃手机传感器回调会高频触发,使用布尔标记 + 延时冷却,避免短时间多次变脸。
4. 作业扩展逻辑
变脸统一封装到changeFace()函数,点击、摇晃变脸共用同一个方法,每次调用自动让totalCount +1,直接实现累计计数。
⚠踩坑记录
- 模拟器摇一摇没效果:加速度传感器依赖手机硬件,必须真机调试;
- 退出页面还会变脸:忘记
onHide调用wx.offAccelerometerChange取消监听; - 摇晃一次连续变脸好几次:缺少防抖逻辑,传感器高频回调重复执行;
- 图片不显示:检查 images 文件夹图片文件名是否和代码完全一致,大小写不能错。