监听触摸事件

触摸事件可以通过监听 Input.EventType.TOUCH_START 来接收屏幕或者鼠标的事件。

监听方式有两种:

  • 通过 input.on 的方式监听,这种方式会监听屏幕上所有的触摸
  • 通过 node.on 的方式监听时,可以监听某个范围内的触摸事件

考虑到我们需要操作角色跳一步或者两步,因此我们选择将屏幕的左边的触摸用于处理跳一步的输入,而右边用于跳两步。

在 UI 层级里,也就是 UICanvas 节点下方创建两个空的节点,并分别命名为 LeftTouch 和 RightTouch:

create-touch.png

参考下图设定好他们的位置和大小:

left-touch.png

right-touch.png

回到 PlayerController 在里面添加下列属性可以在角色上配置触摸区域:

  1. @property(Node)
  2. leftTouch: Node = null;
  3. @property(Node)
  4. rightTouch: Node = null;

并将刚才创建好的节点拖拽到上面去:

config-touch-nodes.png

PlayerController 里面添加下面的代码:

  • 监听触摸输入:

    1. setInputActive(active: boolean) {
    2. if (active) {
    3. this.leftTouch.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
    4. this.rightTouch.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
    5. } else {
    6. this.leftTouch.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
    7. this.rightTouch.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
    8. }
    9. }
  • 添加响应触摸的回调:

    1. onTouchStart(event: EventTouch) {
    2. const target = event.target as Node;
    3. if (target?.name == 'LeftTouch') {
    4. this.jumpByStep(1);
    5. } else {
    6. this.jumpByStep(2);
    7. }
    8. }

    target 在定义中是 any 类型,因此我们需要通过 as 关键字将其转化为 Node 类型。

    通过 as 关键字可以进行类型转换,当前前提是您得知道他是什么类型。

    取到触摸的目标后,我们就可以通过 name 这个属性来区分用户点击的是右侧的触摸区域还是左侧。

之后运行游戏就可以观察到触摸时的跳跃情况,此时可以通过手机应用扫描下图中的 QR 码来在移动设备上游玩(注意要在一个局域网内)。

完整的 Playercontroller 代码参考如下:

  1. import { _decorator, Component, Vec3, EventMouse, input, Input, Animation, EventTouch, Node } from "cc";
  2. const { ccclass, property } = _decorator;
  3. export const BLOCK_SIZE = 40;
  4. @ccclass("PlayerController")
  5. export class PlayerController extends Component {
  6. @property(Animation)
  7. BodyAnim: Animation = null;
  8. private _startJump: boolean = false;
  9. private _jumpStep: number = 0;
  10. private _curJumpTime: number = 0;
  11. private _jumpTime: number = 0.3;
  12. private _curJumpSpeed: number = 0;
  13. private _curPos: Vec3 = new Vec3();
  14. private _deltaPos: Vec3 = new Vec3(0, 0, 0);
  15. private _targetPos: Vec3 = new Vec3();
  16. private _curMoveIndex = 0;
  17. @property(Node)
  18. leftTouch: Node = null;
  19. @property(Node)
  20. rightTouch: Node = null;
  21. start() {
  22. //input.on(Input.EventType.MOUSE_UP, this.onMouseUp, this);
  23. }
  24. setInputActive(active: boolean) {
  25. if (active) {
  26. //input.on(Input.EventType.MOUSE_UP, this.onMouseUp, this);
  27. this.leftTouch.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
  28. this.rightTouch.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
  29. } else {
  30. //input.off(Input.EventType.MOUSE_UP, this.onMouseUp, this);
  31. this.leftTouch.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
  32. this.rightTouch.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
  33. }
  34. }
  35. reset() {
  36. this._curMoveIndex = 0;
  37. }
  38. onTouchStart(event: EventTouch) {
  39. const target = event.target as Node;
  40. if (target?.name == 'LeftTouch') {
  41. this.jumpByStep(1);
  42. } else {
  43. this.jumpByStep(2);
  44. }
  45. }
  46. onMouseUp(event: EventMouse) {
  47. if (event.getButton() === 0) {
  48. this.jumpByStep(1);
  49. } else if (event.getButton() === 2) {
  50. this.jumpByStep(2);
  51. }
  52. }
  53. jumpByStep(step: number) {
  54. if (this._startJump) {
  55. return;
  56. }
  57. this._startJump = true;
  58. this._jumpStep = step;
  59. this._curJumpTime = 0;
  60. const clipName = step == 1 ? 'oneStep' : 'twoStep';
  61. const state = this.BodyAnim.getState(clipName);
  62. this._jumpTime = state.duration;
  63. this._curJumpSpeed = this._jumpStep * BLOCK_SIZE / this._jumpTime;
  64. this.node.getPosition(this._curPos);
  65. Vec3.add(this._targetPos, this._curPos, new Vec3(this._jumpStep * BLOCK_SIZE, 0, 0));
  66. if (this.BodyAnim) {
  67. if (step === 1) {
  68. this.BodyAnim.play('oneStep');
  69. } else if (step === 2) {
  70. this.BodyAnim.play('twoStep');
  71. }
  72. }
  73. this._curMoveIndex += step;
  74. }
  75. onOnceJumpEnd() {
  76. this.node.emit('JumpEnd', this._curMoveIndex);
  77. }
  78. update(deltaTime: number) {
  79. if (this._startJump) {
  80. this._curJumpTime += deltaTime;
  81. if (this._curJumpTime > this._jumpTime) {
  82. // end
  83. this.node.setPosition(this._targetPos);
  84. this._startJump = false;
  85. this.onOnceJumpEnd();
  86. } else {
  87. // tween
  88. this.node.getPosition(this._curPos);
  89. this._deltaPos.x = this._curJumpSpeed * deltaTime;
  90. Vec3.add(this._curPos, this._curPos, this._deltaPos);
  91. this.node.setPosition(this._curPos);
  92. }
  93. }
  94. }
  95. }