《Cocos Creator游戏实战》新手引导实现

新手引导实现

新建节点

完成代码


新手引导在游戏中非常有必要,笔者在本篇教程中就带大家来做一个。

运行效果如下:

Cocos Creator版本:2.2.0

公众号后台回复"新手引导",获取该教程完整代码下载地址:

新建节点

笔者在层级管理器中新建了以下节点:

场景编辑器中显示如下:

  • Button1、Button2和Button3这三个是按钮,用于新手引导演示。
  • maskNode为空节点,不过大小要和Canvas大小一样,这是完成遮罩效果的关键。
  • frame为Sprite节点,就是一个黄色框,会定位在要点击的按钮上。
  • guideLabel就是引导文本,笔者会让它逐字显示(打字机效果)。
  • hand就是引导手,用于提示玩家要点击的按钮。

完成代码

新建一个Guide.js脚本文件,将其挂到maskNode上,然后在properties中添加以下属性:

// Guide
properties: {
    frame: cc.Node,
    guideLabel: cc.Node
    hand: cc.Node,
},

在属性检查器中拖入相应节点:

现在添加对maskNode触摸监听的代码:

// Guide.js
onLoad () {
    this.guideStep = 1;
    
    // 触摸监听
    this.node.on('touchstart', this.onTouchStart, this);
},

onDestroy () {
    // 取消监听
    this.node.off('touchstart', this.onTouchStart, this);
},

onTouchStart (event) {

}

可以看到笔者在onLoad方法中添加了一个guideStep变量,该变量用来体现当前新手引导所处的位置(到第几个按钮了)。玩家每成功点击一个按钮,那guideStep就加1.这里一共要点击三个按钮,所以guideStep最大值为3。

现在编写一个guide方法,该方法会将frame、guideLabel和hand三个节点移动到相应位置:

// Guide.js
guide() {
    if (this.guideStep == 1) {
        let btn1 = this.node.parent.getChildByName('Button1');
        // 将frame节点移到第一个按钮
        this.frame.setPosition(btn1.position);
        // 引导文本
        this.showInfo('请点击第一个按钮~');
        // 手指动作
        this.setHand(btn1.position);
    }
    else if (this.guideStep == 2) {
        let btn2 = this.node.parent.getChildByName('Button2');
        // 将frame节点移到第二个按钮
        this.frame.setPosition(btn2.position);
        // 引导文本
        this.showInfo('请点击第二个按钮~');
        // 手指动作
        this.setHand(btn2.position);
    }
    else if (this.guideStep == 3) {
        let btn3 = this.node.parent.getChildByName('Button3');
        // 将frame节点移到第三个按钮
        this.frame.setPosition(btn3.position);
        // 引导文本
        this.showInfo('请点击第三个按钮~');
        // 手指动作
        this.setHand(btn3.position);
    }
},

我们首先判断guideStep值,然后获取相应按钮节点的坐标并设置frame节点的位置,再调用showInfo方法显示引导文本,最后设置hand节点的位置和动作。

showInfo方法如下:

// Guide.js
showInfo (str) {
    // 显示引导文本
    this.unscheduleAllCallbacks();

    this.guideLabel.getComponent(cc.Label).string = ''
    let i = 0;
    
    this.schedule(()=> {
        this.guideLabel.getComponent(cc.Label).string += str[i];
        i++;
    }, 0.2, str.length-1);
},

逐字显示文本的关键就是使用计时器,重复次数应为文本长度减1。注意每次运行前必须要取消所有计时器先,可以自行将 this.unscheduleAllCallbacks()去掉看下会怎么样。

setHand方法如下:

// Guide.js
setHand (pos) {
    // 设置引导手
    this.hand.setPosition(cc.v2(pos.x, pos.y-80));
    let moveForward = cc.moveBy(0.8, cc.v2(0, 50));
    let moveBack = cc.moveBy(0.8, cc.v2(0, -50));
    let repeatAction = cc.repeatForever(cc.sequence(moveForward, moveBack));
    this.hand.stopAllActions();             // 记得停止之前的动作
    this.hand.runAction(repeatAction);
},

首先设置hand节点的位置(处于按钮的下方),再设置动作。注意每次调用runAction前都要用stopAllActions方法取消之前的动作。

接下来我们完成onTouchStart方法:

// Guide.js
onTouchStart (event) {
    // 获取触摸点,转为Canvas画布上的坐标
    let pos = this.node.parent.convertToNodeSpaceAR(event.getLocation());
    
    // 获取相应按钮的大小范围
    let btn;
    if (this.guideStep == 1)
        btn = this.node.parent.getChildByName('Button1');
    else if(this.guideStep == 2)
        btn = this.node.parent.getChildByName('Button2');
    else if (this.guideStep == 3)
        btn = this.node.parent.getChildByName('Button3');
    let rect = btn.getBoundingBox();

    // 判断触摸点是否在按钮上
    if (rect.contains(pos)) {
        // 允许触摸事件传递给按钮(允许冒泡)
        this.node._touchListener.setSwallowTouches(false);
        this.guideStep++;
        
        // 如果三个按钮都点击了,则将guideStep设置为0,并隐藏所有相关节点
        if (this.guideStep > 3) {
            this.guideStep = 0;
            this.frame.active = false;
            this.guideLabel.active = false;
            this.hand.active = false;
        }
        else
            this.guide();
    } 
    else {
        // 吞噬触摸,禁止触摸事件传递给按钮(禁止冒泡)
        this.node._touchListener.setSwallowTouches(true);
    }
},

我们首先获取触摸点坐标(注意笔者这里转换成了画布上的坐标,因为触摸点坐标是按照世界坐标来的),然后根据guideStep值获取相应按钮的大小范围。如果触摸点在指定按钮上,那么我们让触摸事件冒泡,让相应按钮接收到触摸事件(其余两个按钮是不会接受到的),再将guideStep值加1。

此时如果guideStep值大于3(也就是说3个按钮已经全点完了),那么将guideStep值设为0,并将相关引导节点全部隐藏掉。否则就调用guide方法显示引导。

如果触摸点不在指定按钮上,则禁止冒泡,那么所有按钮都不会接收到触摸事件。

现在我们在onTouchStart中再套上一个判断:

// Guide.js
onTouchStart (event) {
    if(this.guideStep) {
        ...
    }
},

如果guideStep值不为0,则执行引导。

最后在onLoad方法中调用一下guide()就行了:

// Guide.js
onLoad () {
    this.guideStep = 1;

    // 触摸监听
    this.node.on('touchstart', this.onTouchStart, this);

    // 显示引导
    this.guide();
},

那新手引导实现教程就到这,希望大家多多支持~

欢迎关注我的微信公众号,发现更多有趣内容:

发布了83 篇原创文章 · 获赞 157 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/La_vie_est_belle/article/details/103182912