Cocos Creator 2D 实战:触摸移动、碰撞检测与计分
一个最小可玩的 2D 游戏,通常至少要有输入、目标、碰撞反馈和分数。本篇在前一篇场景的基础上,做一个拖动 Player 收集 Coin 的小例子。
本文目标
完成后,玩家可以在手机或浏览器中触摸移动角色;角色碰到金币时金币消失,界面上的分数加一。
1. 准备场景节点
建议先建立以下结构:
Canvas
├─ Player
├─ CoinContainer
│ ├─ Coin_01
│ ├─ Coin_02
│ └─ Coin_03
└─ UI
└─ ScoreLabel
Player 和每一个 Coin 都需要有可见的 Sprite。触摸事件依赖 UITransform,通常在 UI 节点上已经存在;如果你创建的是普通节点,记得补上 UITransform 组件。
2. 配置 2D 碰撞器
选中 Player 和 Coin,分别添加 BoxCollider2D 或 CircleCollider2D。为了让碰撞事件能正常产生,至少让参与碰撞的一方拥有 RigidBody2D。
对于金币这类可收集物,建议在 Collider2D 上开启 Sensor。Sensor 仍会产生碰撞回调,但不会把角色硬生生弹开;它很适合道具、触发区和传送门。
还要检查 Physics2D 的分组碰撞矩阵:Player 所在分组必须允许和 Coin 所在分组相互碰撞。
3. 用触摸事件移动角色
将下面的脚本挂到 Player 节点:
import { _decorator, Component, EventTouch, Node } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('PlayerTouchController')
export class PlayerTouchController extends Component {
@property(Node)
target: Node | null = null;
onEnable() {
this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
}
onDisable() {
this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
}
private onTouchMove(event: EventTouch) {
const point = event.getUILocation();
this.node.setWorldPosition(point.x, point.y, 0);
}
}
这个版本刻意保持简单,适合先确认输入链路是通的。正式项目可在此基础上增加边界限制、插值移动、手势判断和拖拽状态。
4. 处理开始碰撞事件
再创建 CollectScore.ts 并挂到 Player:
import { _decorator, Collider2D, Component, Contact2DType, Label } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('CollectScore')
export class CollectScore extends Component {
@property(Label)
scoreLabel: Label | null = null;
private score = 0;
private collider: Collider2D | null = null;
onEnable() {
this.collider = this.getComponent(Collider2D);
this.collider?.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
}
onDisable() {
this.collider?.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
}
private onBeginContact(_self: Collider2D, other: Collider2D) {
if (!other.node.name.startsWith('Coin')) return;
other.node.destroy();
this.score += 1;
if (this.scoreLabel) {
this.scoreLabel.string = '得分:' + this.score;
}
}
}
在 Inspector 中把 ScoreLabel 拖到 scoreLabel 属性上。预览时碰到 Coin,分数就会更新。
5. 调试清单
- 没有碰撞回调:确认两边都有 Collider2D,至少一边有 RigidBody2D。
- 碰到金币被弹开:将 Coin 的 Collider2D 设为 Sensor。
- 分数没有更新:确认 Label 已经拖到脚本属性上。
- 手机上的触摸无效:确认事件绑在带 UITransform 的节点上,并用真机或移动模拟器测试。
可以继续完善的方向
不要长期依赖节点名称判断 Coin。后续可给金币挂一个 Coin 组件,或使用分组、标签和对象池来管理大量道具。玩法验证阶段先让链路跑通,比一开始追求复杂架构更重要。
参考
- Cocos Creator 节点触摸事件:https://docs.cocos.com/creator/3.8/manual/en/engine/event/event-node.html
- Cocos Creator 2D Collider:https://docs.cocos.com/creator/3.8/manual/en/physics-2d/physics-2d-collider.html