
网罗开发 (小红书、快手、视频号同名)
大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。
图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验 。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索"展菲",即可纵览我在各大平台的知识足迹。
每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
文章目录
-
- 引言
- 一、手势的本质是什么?
- 二、很多项目为什么会失控?
- [三、正确架构:Input System](#三、正确架构:Input System)
- 四、第一步:统一输入模型
- [五、第二步:InputSystem 接管手势](#五、第二步:InputSystem 接管手势)
- 六、拖拽为什么最容易写崩?
- 七、摇杆系统其实是手势系统
- 八、技能释放如何设计?
- 九、多端场景为什么更重要?
- [十、AISystem 其实也是输入源](#十、AISystem 其实也是输入源)
- 十一、一个关键认知升级
- 总结
引言
很多开发者第一次做鸿蒙游戏时,对"手势"都有一个非常简单的理解:
ts
TapGesture()
或者:
ts
PanGesture()
然后就结束了。但当游戏复杂起来以后,你会发现:
点击只是开始
拖拽需要状态
缩放需要协同
摇杆需要持续输入
技能释放需要组合手势
这时候问题就来了:
手势到底是 UI 功能,还是游戏系统?
很多项目后期越来越乱,根本原因就在这里:
ts
UI处理手势
UI修改状态
UI触发逻辑
最后变成:
UI = 输入层
UI = 逻辑层
UI = 状态层
整个架构直接失控,所以我们讨论一个核心问题:
鸿蒙游戏中的手势系统,到底应该如何设计?
一、手势的本质是什么?
很多人认为:
手势 = 操作
实际上不是,对于游戏来说:
手势本质是输入事件(Input Event)
例如:
点击
ts
Tap
代表:
用户发起了一次输入
拖拽
ts
Pan
代表:
用户持续输入方向信息
双指缩放
ts
Pinch
代表:
用户希望改变视角
所以:
手势不是业务逻辑,而是输入信号。
二、很多项目为什么会失控?
先看一个真实项目经常出现的代码:
ts
TapGesture()
.onAction(() => {
store.hp -= 10
enemy.hp -= 20
dropSystem.drop()
})
看起来很方便,但问题巨大:
UI直接改状态
UI直接调System
UI知道业务细节
结果:
无法复用
无法测试
无法扩展
三、正确架构:Input System
正确模型应该是:
text
Gesture
↓
InputSystem
↓
System
↓
Store
↓
UI
这里有一个关键变化:
手势不再驱动游戏,而是驱动 InputSystem。
四、第一步:统一输入模型
不要让:
ts
TapGesture
PanGesture
PinchGesture
直接进入业务层,统一转换为:
ts
enum InputAction {
ATTACK,
MOVE,
SKILL,
CAMERA
}
例如:
点击攻击按钮
ts
TapGesture()
转换:
ts
InputAction.ATTACK
摇杆拖动
ts
PanGesture()
转换:
ts
InputAction.MOVE
这样:
System 永远不知道用户用了什么手势。
它只知道:
ts
用户要移动
五、第二步:InputSystem 接管手势
ts
class InputSystem {
dispatch(action: InputAction) {
switch(action) {
case ATTACK:
battleSystem.attack(store)
break
case MOVE:
moveSystem.move(store)
break
}
}
}
这里非常关键:
UI 不知道 BattleSystem
UI 不知道 MoveSystem
全部通过:
ts
InputSystem
转发。
六、拖拽为什么最容易写崩?
因为拖拽不是:
text
一次事件
而是:
text
连续事件
例如:
ts
PanGesture()
.onActionUpdate(...)
会不断触发:
text
x
y
dx
dy
如果直接写:
ts
store.playerX += dx
很快就会出问题:
性能下降
状态混乱
多端不同步
正确方式:
ts
InputAction.MOVE
传递给:
ts
MoveSystem
由系统统一计算。
七、摇杆系统其实是手势系统
很多人以为:
摇杆是UI组件
其实不是,本质上:
text
摇杆 = PanGesture
只是经过转换:
ts
(dx, dy)
变成:
ts
(directionX, directionY)
然后交给:
ts
MoveSystem
处理,所以:
摇杆本质是持续输入系统。
八、技能释放如何设计?
复杂游戏经常会出现:
text
点击
长按
滑动
组合拖拽
例如:
text
点击 = 普攻
长按 = 蓄力
拖动 = 指定方向
很多项目会写:
ts
if (...)
然后:
ts
if (...)
再:
ts
if (...)
最后变成:
一团乱麻
正确方式,统一进入:
ts
SkillInputSystem
例如:
ts
SkillCommand {
type: CHARGE_ATTACK
direction: vector
}
然后:
ts
SkillSystem.execute()
九、多端场景为什么更重要?
鸿蒙最大的特点:
手机
平板
PC
TV
输入方式完全不同。
手机:
text
触摸
PC:
text
鼠标
键盘
TV:
text
遥控器
如果业务层直接依赖:
ts
TapGesture
就废了。
正确做法,统一转换:
ts
InputAction
例如:
text
Tap
MouseClick
RemoteClick
全部映射:
ts
ATTACK
于是:
System 永远不关心输入设备。
十、AISystem 其实也是输入源
这是很多人忽略的一点,玩家输入:
ts
ATTACK
AI输入:
ts
ATTACK
本质一样,所以:
text
UserInput
AIInput
都应该进入:
ts
InputSystem
最终形成:
text
Gesture
Keyboard
Mouse
AI
↓
InputSystem
↓
System
↓
Store
↓
UI
十一、一个关键认知升级
初学者理解:
text
手势 = UI功能
进阶之后理解:
text
手势 = 输入设备
再进一步:
手势只是游戏状态变化的触发器。
真正决定世界如何变化的,仍然是:
text
System
总结
鸿蒙游戏中的手势系统,本质不是:
text
TapGesture
PanGesture
PinchGesture
而是:
text
Input System
推荐最终架构:
text
Gesture
Keyboard
Mouse
AI
↓
InputSystem
↓
BattleSystem
MoveSystem
SkillSystem
↓
Store
↓
UI
如果用一句话总结:
在鸿蒙游戏中,手势只是输入,System 才是行为的真正执行者。