Cocos Creator游戏开发教程 学习笔记

学完提问几个问题吧:

position的锚点位置数值原点在哪里?

        因为position是相对坐标,所以原点是父节点的锚点 。所以Canvas下面的直属节点原点就是世界坐标系的原点Canvas的锚点。Cocos Creator游戏开发教程 学习笔记_第1张图片

 如何设置默认浏览器?设置--预览运行--预览使用浏览器--选择浏览.exe--确认按钮。

Cocos Creator游戏开发教程 学习笔记_第2张图片

1.创建渲染节点:  

        Sprite(精灵):创建节点-》创建渲染节点-》Sprite(精灵)。是新建图片节点,在这个节点引入图片,要设置SpriteFrame(图片帧)。

        Label(文字):创建节点-》创建渲染节点-》Label(文字)。是新建文本节点,可以设置属性:String,Font,Font Size。(还可以在某个节点下方,选择添加组件-》渲染组件-》Label。)

2.创建UI节点:

        Button(按钮):创建节点-》创建UI节点-》Button(按钮)。

        EditBox(输入框):创建节点-》创建UI节点-》EditBox(输入框)。

        节点可以单独存在,也可以在节点下方挂上多个组件,实现功能。但是一个节点只能选择一个渲染类的组件。

Cocos Creator游戏开发教程 学习笔记_第3张图片

 给节点添加音频资源:

Cocos Creator游戏开发教程 学习笔记_第4张图片

Cocos Creator游戏开发教程 学习笔记_第5张图片

API获取节点:

        获取当前脚本绑定的节点: let node : cc.Node = this.node;

        父节点:this.node.parent;

        子节点: this.node.children : cc.Node[ ];

全局查找:target = cc.find("Canvas/佩奇/名字");

let node : cc.Node = cc.find("Canvas/佩奇/名字");//找到路径

node.setPosition(0,-200);//使这个节点向下移动200px。

 }

查找子节点:target = cc.find("Canvas/佩奇/名字",someNode);

                对于已经定义的节点node,可以获取他挂载的组件对象。

获取组件:let label : cc.Label = node.getComponet(cc.Label);

获取自定义类型的组件(脚本组件):let script = node.getComponent("YourScript");

键盘事件(全局事件):cc.systemEvent.on();

        cc.systemEvent.on('keydown',this.onKeyDown,this);

                onKeyDown( evt : cc.Event.EventKeyboard ){

                        键盘事件的按键值使用:假如使用的是右键

                        if(evt.keyCode == cc.macro.KEY.right){...}

                }

        使用x,y轴修改节点:this.node.x += 10;this.node.y += 10;

动态显示图片:

        翻转:this.node.scaleX = 0 - this.node.scaleX;

changeFace(){
 cc.log("改变行走方向,脸朝" + (this.faceLeft ? '左' : '右'));
//大前提:  初始图片脸朝右 且 this.node.scaleX >0
 if(this.faceLeft && (this.node.scaleX >0)||((!this.faceLeft) && (this.node.scaleX <0)))
 {//向左走 现在图片是脸朝右的,需要图片脸朝左     //向右走  现在图片是脸朝左的,需要图片脸朝右
      this.node.scaleX = 0 - this.node.scaleX;
 }else{  
//((this.faceLeft && (this.node.scaleX <0))||((!this.faceLeft) && (this.node.scaleX >0)))
//向左走 现在图片是脸朝左的,不需要改变图片脸朝向 //向右走  现在图片是脸朝右的,不需要改变图片脸朝向  
      this.node.scaleX = this.node.scaleX;
 }
}   

        直接换图片:
                图片放在资源管理其中;

                添加属性加载图片帧:

// 两种状态的图片帧
@property(cc.SpriteFrame)
face1: cc.SpriteFrame = null;
@property(cc.SpriteFrame)
 face2: cc.SpriteFrame = null;

                根据条件切换图片:

 changeFace(){
  cc.log("改变行走方向,脸朝" + (this.faceLeft ? '左' : '右'));
  // 获取 Sprite 组件
  let sprite : cc.Sprite = this.node.getComponent(cc.Sprite);
  // 修改 Sprite 组件的 Sprite Frame 属性
  //无论初始图片是脸朝左还是脸朝右,都没关系。
  if(this.faceLeft){
     sprite.spriteFrame = this.face1; //需要图片脸朝左         
  }else{
     sprite.spriteFrame = this.face2; //需要图片脸朝右
  }
}   

Cocos Creator游戏开发教程 学习笔记_第6张图片

 脚本组件的调用:

        找路径的时候:鼠标右键“显示节点UUID和路径。”

        let node : cc.Node = cc.find('Canvas/佩奇_右');//找到脚本的节点路径

        let script = node.getComponent('PigScript');//根据脚本的节点找到这个脚本。

坐标系:

        二维和三维:

        let pos = new cc.Vec2(100,100);   简写,省略new:let pos =  cc.Vec2(100,100); 

        let pos = new cc.Vec3(100,100,100);  简写,省略new:let pos =  cc.Vec3(100,100,100); 

        设置一个节点的坐标: node.setPosition( cc.v2(250,250) );//相对坐标,相对父节点

        设置一个节点的缩放:node.setScale( cc.v3(1,1,0) );//2D游戏,所以z轴设置为0.

缓动系统:

      cc.tween(node)
        .to(1,{position:cc.v3(250,120,0)})
        .start();

  Cocos Creator游戏开发教程 学习笔记_第7张图片Cocos Creator游戏开发教程 学习笔记_第8张图片

 动画:

        update(dt){  }帧动画的绘制:默认: 这个方法每秒钟会被调用60次。

                // onLoad () {}  //初始化加载
    start () { }    //第一次启动的时候
            //update() 方法 就是 帧动画的绘制。
    update (dt) {//cc.log("update() is called , time = " + new Date().getTime());

                                //打印设置每一帧的刷新时间
        if(this.node.x>= 200){
            return;  //总距离移动200像素。 然后停止运动。
        }else{
            this.node.x += 5; //将节点移动5像素。
        }
    }

        要调节这个次数,需要:把GameInitScript挂在Canvas中。因为游戏是从根节点Canvas开始运行的,所以先加载Canvas下面的组件,故我们可以把所有的全局设置放在GameInitScript中,从根节点加载就开始运行组件GameInitScript。

onLoad () {
        cc.log('Pig Script : onload()');
        cc.game.setFrameRate(30);  //设置帧率为30帧/秒
    }
    start () {}
   // update (dt) {}

 11.3根据键盘控制上下左右运动

11.4 计时器:间隔多少时间,回调什么函数方法,(可省略:重复几次,延迟几秒;省略时,默认一直重复,不延迟。)。

 手柄拖动,

世界坐标坐标转换为父节点的本地坐标:

        //需要把世界坐标转换为本地坐标
        let parent : cc.Node = this.node.parent;//父节点(圆形底盘)
            //e.getLocation() 获得触摸点的世界坐标(触点位置)
            //把触摸点的世界坐标转换为父节点(圆形底盘)的本地坐标 ,pos代表触摸点的本地坐标
        let pos : cc.Vec2 = parent.convertToNodeSpaceAR(e.getLocation());
            //根据pos触摸点的本地坐标,使用setPosition()设置手柄在父节点的本地坐标
        this.node.setPosition(pos);

const {ccclass, property} = cc._decorator;
 
@ccclass
export default class NewClass extends cc.Component {
        // onLoad () {}
    start () {
        this.node.on('touchstart',this.onTouchStart,this);
        this.node.on('touchmove',this.onTouchMove,this);
        this.node.on('touchend',this.onTouchCancel,this);
        this.node.on('touchcancel',this.onTouchCancel,this);
    }
    onTouchStart( e : cc.Event.EventTouch ){}//暂时没有用到,置空
            //计算触摸点的当前位置,把手柄的位置移动到触摸点所在的位置
    onTouchMove( e : cc.Event.EventTouch ){
            //e.getLocation()为触摸点的位置,是世界坐标
            //需要把世界坐标转换为本地坐标
        cc.log("世界坐标touch move : x=" + e.getLocationX() + ",y=" +e.getLocationY());
        let parent : cc.Node = this.node.parent;//父节点(圆形底盘)
            //e.getLocation() 获得触摸点的世界坐标(触点位置)
            //把触摸点的世界坐标转换为父节点(圆形底盘)的本地坐标 ,pos代表触摸点的本地坐标
        let pos : cc.Vec2 = parent.convertToNodeSpaceAR(e.getLocation());
            //根据pos触摸点的本地坐标,使用setPosition()设置手柄在父节点的本地坐标
        this.node.setPosition(pos);
        cc.log("转换成本地坐标convert to local: x=" +  pos.x + ",y=" + pos.y); 
    }
    onTouchCancel( e : cc.Event.EventTouch ){
            //触摸松开的时候,把手柄的位置移动到中央
        this.node.setPosition( cc.v3(0,0,0));
    }
    // update (dt) {}
}

方位角:let direction : cc.Vec2 = pos.normalize(); 最后得到direction =(cos值,sin值)。

角度表示: let angle:number =45;

计算两点之间的实际距离:此时两点都在同一个坐标系中。

        let d: number = cc.Vec2.distance( pos,cc.v2(0,0) );
求a,b两个向量的夹角:radian = a.angle(b) ;

        a位于b的顺时针方向:角度为正; a位于b的逆时针方向:角度为负。
弧度值:let radian = pos.signAngle(cc.v2(1,0)); 其中 cc.v2(1,0) 表示x轴方向的单位向量
把弧度制转换成角度值:let angle = radian / Math.PI * 180; 
        this.car.angle = -angle; // 按API要求,angle是按逆时针为正的
       // this.car.rotation = angle; //这样写也行,但是不如 this.car.angle = -angle;

显示Gif图参见13章。

一次加载多个资源参见14章。

触摸事件的事件冒泡机制:

         加上 e.stopPropagation();(停止传递当前事件。)就不会上浮到父节点“道路”。而是只打印子节点汽车。

遮罩效果:

        加上一个单色节点,然后调整节点的active激活或者非激活状态。 

onTouch( e : cc.Event.EventTouch){

        //设置节点状态处于非激活的状态。

        this.node.active = false;

        // e.stopPropagation();

}

使用Widget组件进行优化:

        使得遮罩自适应屏幕,且和父节点(Canvas)同样大小遮满屏幕。把上下左右边距全部调成0px。

  

  1. 声明:全文 根据 B站博主阿发你好 的视频教程学习并记录。笔记持续学习更新中......

  2. B站博主阿发你好  的网址:Cocos Creator游戏开发教程_60集教学视频_哔哩哔哩_bilibili  https://www.bilibili.com/video/BV1sA411Y7x4?p=1

  3. 课程内容:学完之后制作2D小游戏。制作不需要安装打开就可以玩的小游戏。

    1. Cocos Creator游戏开发教程 学习笔记_第9张图片
    2.  Cocos Creator游戏开发教程 学习笔记_第10张图片

       Cocos Creator游戏开发教程 学习笔记_第11张图片

       地道的中文,便于阅读、学习。

    3. Cocos Creator游戏开发教程 学习笔记_第12张图片

    4. 官网的开发文档:Introduction · Cocos Creator  https://docs.cocos.com/creator/manual/zh/

    打开之后就是这个:

    Cocos Creator游戏开发教程 学习笔记_第13张图片

    1.  要会程序设计:Swing入门和Swing高级。这个要自学。

    2.  Cocos Creator游戏开发教程 学习笔记_第14张图片

    3. Cocos Creator游戏开发教程 学习笔记_第15张图片

      (发现下载需要付费10元。)

    4. 资料下载:Cocos Creator游戏开发教程 学习笔记_第16张图片

       Cocos Creator游戏开发教程 学习笔记_第17张图片

    5. Cocos Creator 开发环境安装_时时师师的博客-CSDN博客

    Cocos Creator游戏开发教程 学习笔记_第18张图片

     

    3.1编辑器界面Cocos Creator游戏开发教程 学习笔记_第19张图片

     Cocos Creator游戏开发教程 学习笔记_第20张图片

     Cocos Creator游戏开发教程 学习笔记_第21张图片

    场景Scene 

    资源 Asset(Texture 图片素材;audioClip 音频素材;)

    Cocos Creator游戏开发教程 学习笔记_第22张图片

     Cocos Creator游戏开发教程 学习笔记_第23张图片

     Cocos Creator游戏开发教程 学习笔记_第24张图片

     4.1场景编辑器

     Cocos Creator游戏开发教程 学习笔记_第25张图片

     Cocos Creator游戏开发教程 学习笔记_第26张图片

     Cocos Creator游戏开发教程 学习笔记_第27张图片Cocos Creator游戏开发教程 学习笔记_第28张图片Cocos Creator游戏开发教程 学习笔记_第29张图片

    4.2添加节点 

     Cocos Creator游戏开发教程 学习笔记_第30张图片

    把图片拖拽进入Canvas下面。

     Cocos Creator游戏开发教程 学习笔记_第31张图片

     Cocos Creator游戏开发教程 学习笔记_第32张图片

     

     Main Scene场景文件中使用json代码保存了图片的路径和名称。

     Cocos Creator游戏开发教程 学习笔记_第33张图片

    4.3节点的操作Cocos Creator游戏开发教程 学习笔记_第34张图片

     Cocos Creator游戏开发教程 学习笔记_第35张图片

     疑惑:缩放和矩形变换有什么区别?

    Cocos Creator游戏开发教程 学习笔记_第36张图片

    Cocos Creator游戏开发教程 学习笔记_第37张图片

    Cocos Creator游戏开发教程 学习笔记_第38张图片

    Cocos Creator游戏开发教程 学习笔记_第39张图片

     Cocos Creator游戏开发教程 学习笔记_第40张图片

    Cocos Creator游戏开发教程 学习笔记_第41张图片

    Cocos Creator游戏开发教程 学习笔记_第42张图片

     在属性检查器中设置才是一个精确的数值。

    Cocos Creator游戏开发教程 学习笔记_第43张图片

     Cocos Creator游戏开发教程 学习笔记_第44张图片

     4.4位置与锚点Cocos Creator游戏开发教程 学习笔记_第45张图片

     Cocos Creator游戏开发教程 学习笔记_第46张图片

     Cocos Creator游戏开发教程 学习笔记_第47张图片

     如下图,图片的坐标轴原点就是锚点(Anchor)

    Cocos Creator游戏开发教程 学习笔记_第48张图片

     

     Cocos Creator游戏开发教程 学习笔记_第49张图片

    相对坐标

    父节点(Canvas)、子节点(佩奇、Main Camera)。

     佩奇的坐标是相对于世界坐标系的原点Canvas的(480,320)这个点来定坐标的。佩奇的position和Canvas这个点重合时,position=(0,0)。Cocos Creator游戏开发教程 学习笔记_第50张图片

     Cocos Creator游戏开发教程 学习笔记_第51张图片

     Cocos Creator游戏开发教程 学习笔记_第52张图片

     4.5 游戏的运行

            Cocos Creator游戏开发教程 学习笔记_第53张图片

     

     两种方式任选其一。

     设置默认浏览器:

    Cocos Creator游戏开发教程 学习笔记_第54张图片Cocos Creator游戏开发教程 学习笔记_第55张图片

    浏览器运行之后这里也可以选择设置中已有的功能。

    Cocos Creator游戏开发教程 学习笔记_第56张图片

    5.1添加图片节点

     Cocos Creator游戏开发教程 学习笔记_第57张图片

     Cocos Creator游戏开发教程 学习笔记_第58张图片Cocos Creator游戏开发教程 学习笔记_第59张图片

    Cocos Creator游戏开发教程 学习笔记_第60张图片

     在右侧添加组件,这样就可以看到Sprite。

     Cocos Creator游戏开发教程 学习笔记_第61张图片

     操作步骤:

    Cocos Creator游戏开发教程 学习笔记_第62张图片

     Cocos Creator游戏开发教程 学习笔记_第63张图片

     Cocos Creator游戏开发教程 学习笔记_第64张图片

    拖拽:鼠标移动到节点上,然后拖动到Sprite Frame就可以了,不要单击。

     5.2 文本节点

    Cocos Creator游戏开发教程 学习笔记_第65张图片

    Cocos Creator游戏开发教程 学习笔记_第66张图片

    右侧也可以选择添加组件来调整文本节点的细节:字体、颜色、大小、等等。

    Cocos Creator游戏开发教程 学习笔记_第67张图片

     5.3添加UI节点Cocos Creator游戏开发教程 学习笔记_第68张图片

     Cocos Creator游戏开发教程 学习笔记_第69张图片

     Cocos Creator游戏开发教程 学习笔记_第70张图片

     Cocos Creator游戏开发教程 学习笔记_第71张图片

     鼠标移到文字上:能显示这个属性的具体描述

     Cocos Creator游戏开发教程 学习笔记_第72张图片

    创建一个输入框:

    Cocos Creator游戏开发教程 学习笔记_第73张图片

     Cocos Creator游戏开发教程 学习笔记_第74张图片

    一些输入框的名字。

     5.5节点与组件Cocos Creator游戏开发教程 学习笔记_第75张图片

     Cocos Creator游戏开发教程 学习笔记_第76张图片

     节点Node的功能是由它下面的XX组件(Sprite图片、Label文本等)来决定的。

    在右侧的“添加组件”中选择。  渲染类型组件只能选择一个。

    Cocos Creator游戏开发教程 学习笔记_第77张图片Cocos Creator游戏开发教程 学习笔记_第78张图片

    5.5父子节点Cocos Creator游戏开发教程 学习笔记_第79张图片

     Cocos Creator游戏开发教程 学习笔记_第80张图片

     Cocos Creator游戏开发教程 学习笔记_第81张图片

    6.1 VSCode环境Cocos Creator游戏开发教程 学习笔记_第82张图片

     Cocos Creator游戏开发教程 学习笔记_第83张图片Cocos Creator游戏开发教程 学习笔记_第84张图片

     6.2创建游戏脚本

    TypeScript其实就是JavaScript的加强版。

    解释: JavaScript是无类型的,所以在编写的时候没有工具提示,比较麻烦。所以就发明了强类型的TypeScript,具有工具提示。

     Cocos Creator游戏开发教程 学习笔记_第85张图片Cocos Creator游戏开发教程 学习笔记_第86张图片

     Cocos Creator游戏开发教程 学习笔记_第87张图片

    按照默认的VS Code 安装步骤,安装之后,在cocos中配置VS Code,浏览,然后搜索 VS Code,找到Code.exe。点击保存。

    Cocos Creator游戏开发教程 学习笔记_第88张图片

    新建游戏脚本,就会自动打开VS Code。

    Cocos Creator游戏开发教程 学习笔记_第89张图片

    假如输入状态紊乱,那么可以切换一下中文,或者切换到其他窗口,再切回来。

    Cocos Creator游戏开发教程 学习笔记_第90张图片

     Cocos Creator游戏开发教程 学习笔记_第91张图片

    步骤演示:

    创建文件夹,然后点击选中图片佩奇,在右下角添加组件——用户脚本组件——Pigscript。

     Cocos Creator游戏开发教程 学习笔记_第92张图片

    选中之后会出现蓝色的边框。

     

    在cocos中不能直接编辑脚本,需要双击这个脚本,就会自动打开VS Code脚本窗口编辑。

    Cocos Creator游戏开发教程 学习笔记_第93张图片

     在VS Code中编辑完成之后,Ctrl+S保存cocos会自动刷新右侧的代码内容

    Cocos Creator游戏开发教程 学习笔记_第94张图片

    Cocos Creator游戏开发教程 学习笔记_第95张图片

     Cocos Creator游戏开发教程 学习笔记_第96张图片

     6.3 脚本的运行

    Cocos Creator游戏开发教程 学习笔记_第97张图片

    双击打开脚本之后先关闭脚本窗口(因为这样打开的窗口,直接进行编辑有一个BUG,所以需要先把这个脚本关闭),然后在右侧重新找到代码打开,再进行编辑。

    Cocos Creator游戏开发教程 学习笔记_第98张图片Cocos Creator游戏开发教程 学习笔记_第99张图片

    选择模拟器,还有下方的Resume script execution按钮(继续脚本执行),才能出现打印的日志。Cocos Creator游戏开发教程 学习笔记_第100张图片

    Cocos Creator游戏开发教程 学习笔记_第101张图片

     伪代码理解:

     Cocos Creator游戏开发教程 学习笔记_第102张图片Cocos Creator游戏开发教程 学习笔记_第103张图片

     生命周期回调 · Cocos Creator  https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html

    Cocos Creator游戏开发教程 学习笔记_第104张图片

    Cocos Creator游戏开发教程 学习笔记_第105张图片

     6.4 事件响应处理Cocos Creator游戏开发教程 学习笔记_第106张图片

    方法名不加()。并不是要调用它。

    Cocos Creator游戏开发教程 学习笔记_第107张图片

    Cocos Creator游戏开发教程 学习笔记_第108张图片

     6.5脚本的调试Cocos Creator游戏开发教程 学习笔记_第109张图片

     Cocos Creator游戏开发教程 学习笔记_第110张图片Cocos Creator游戏开发教程 学习笔记_第111张图片

     Cocos Creator游戏开发教程 学习笔记_第112张图片

     7.1 TypeScript 具体用法Cocos Creator游戏开发教程 学习笔记_第113张图片

    官网地址: TypeScript: JavaScript With Syntax For Types.  https://www.typescriptlang.org/zh/

     Cocos Creator游戏开发教程 学习笔记_第114张图片Cocos Creator游戏开发教程 学习笔记_第115张图片

     Cocos Creator游戏开发教程 学习笔记_第116张图片Cocos Creator游戏开发教程 学习笔记_第117张图片

     这样如下图,就有提示了:Cocos Creator游戏开发教程 学习笔记_第118张图片

     Cocos Creator游戏开发教程 学习笔记_第119张图片

     7.2 属性的定义Cocos Creator游戏开发教程 学习笔记_第120张图片

     

     加了@property之后,用户脚本组件的PigeScript中就会自动加上这个time属性。开发者就可以从这个属性面板中进行初始化设置。但是这里的修改不会影响代码,只会影响编译结果。Cocos Creator游戏开发教程 学习笔记_第121张图片

    Cocos Creator游戏开发教程 学习笔记_第122张图片

 7.3基本类型的属性Cocos Creator游戏开发教程 学习笔记_第123张图片

 Cocos Creator游戏开发教程 学习笔记_第124张图片


const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    @property(cc.Label)
    label: cc.Label = null;
    
    // 每一步的大小,单位为像素。
    @property
    step : number = 20 ;

    //行走方向
    @property
    towardsLeft : boolean = true;

    // LIFE-CYCLE CALLBACKS:


    //调用move方法
    onLoad () {
        this.node.on("mousedown",this.move,this);
    }
    

    start () {
        cc.log("组件PigeScript开始运行!"+1123);

    }
    // 在TypeScript里,方法的末尾不需要加分号或者逗号
    move(evt : cc.Event.EventMouse){
        if(this.towardsLeft){
            this.node.x -= this.step;//向左走

        }else{
            this.node.x += this.step;//向右走
        }
    }
   
    // update (dt) {}
}

Cocos Creator游戏开发教程 学习笔记_第125张图片Cocos Creator游戏开发教程 学习笔记_第126张图片

 选择勾选(向左)或者不勾选(向右)属性“Towards Left”来控制方向。

新建的节点也可以通过添加组件使用这个PigeScript脚本的代码。

 Cocos Creator游戏开发教程 学习笔记_第127张图片

 7.4引用类型的使用Cocos Creator游戏开发教程 学习笔记_第128张图片

 Cocos Creator游戏开发教程 学习笔记_第129张图片Cocos Creator游戏开发教程 学习笔记_第130张图片

 全部代码:


const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    @property(cc.Label)
    label: cc.Label = null;
    
    // 每一步的大小,单位为像素。
    @property
    step : number = 20 ;

    //行走方向
    @property
    towardsLeft : boolean = true;

    //脚步声(cc.AudioClip 表示一个音频资源,例如一个mp3)
    @property(cc.AudioClip)
    audio : cc.AudioClip = null;


    // LIFE-CYCLE CALLBACKS:



    onLoad () {
        this.node.on("mousedown",this.move,this);
    }
    

    start () {
        cc.log("组件PigeScript开始运行!"+1123);

    }
    // 在TypeScript里,方法的末尾不需要加分号或者逗号
    move(evt : cc.Event.EventMouse){
        if(this.towardsLeft){
            this.node.x -= this.step;//向左走

        }else{
            this.node.x += this.step;//向右走
        }
        
        //播放脚步声音频
        if(this.audio != null){
            cc.audioEngine.play(this.audio,false,1);
        }
    }

   
    // update (dt) {}
}

 添加脚步声的关键代码:Cocos Creator游戏开发教程 学习笔记_第131张图片

Cocos Creator游戏开发教程 学习笔记_第132张图片  新建文件夹audio,里面加入音频,然后把这个音频拖拽到 Audio 这个属性框中进行添加。

 Cocos Creator游戏开发教程 学习笔记_第133张图片

 Cocos Creator游戏开发教程 学习笔记_第134张图片

 8.1API获取节点Cocos Creator游戏开发教程 学习笔记_第135张图片

 Cocos Creator游戏开发教程 学习笔记_第136张图片

 Cocos Creator游戏开发教程 学习笔记_第137张图片Cocos Creator游戏开发教程 学习笔记_第138张图片

操作结果:点一下测试按钮,就能把名字放到佩奇的脚下。(点击测试按钮之前,名字在佩奇的头上。)

 Cocos Creator游戏开发教程 学习笔记_第139张图片Cocos Creator游戏开发教程 学习笔记_第140张图片

创建新脚本ButtonScript,添加给测试按钮。

Cocos Creator游戏开发教程 学习笔记_第141张图片

代码:注意路径名称必须要区分大小写。

const {ccclass, property} = cc._decorator;
@ccclass
export default class NewClass extends cc.Component {
    onLoad () {//鼠标点击事件 onClicked()
        this.node.on("mousedown",this.onClicked,this);
    }
    start () {}
    onClicked(){
        let node : cc.Node = cc.find("Canvas/佩奇/名字");//找到路径
        node.setPosition(0,-200);//使这个节点向下移动200px。
    }
    // update (dt) {}
}

 Cocos Creator游戏开发教程 学习笔记_第142张图片

 查看文档,寻找API。

 Cocos Creator游戏开发教程 学习笔记_第143张图片

 Cocos Creator游戏开发教程 学习笔记_第144张图片

8.2API获取组件Cocos Creator游戏开发教程 学习笔记_第145张图片

 Cocos Creator游戏开发教程 学习笔记_第146张图片

 Cocos Creator游戏开发教程 学习笔记_第147张图片

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {
    // LIFE-CYCLE CALLBACKS:
    onLoad () {
        this.node.on("mousedown",this.onClicked,this);
    }
    start () {}
    onClicked(){
        let targetNode : cc.Node = cc.find("Canvas/佩奇/名字");//根据路径找到节点 名字
        let label : cc.Label = targetNode.getComponent(cc.Label);//获取节点的组件Lable
        label.string = "小猪佩奇";//给属性string赋值
    }
    // update (dt) {}
}

8.3脚本组件的访问Cocos Creator游戏开发教程 学习笔记_第148张图片

 Cocos Creator游戏开发教程 学习笔记_第149张图片Cocos Creator游戏开发教程 学习笔记_第150张图片

为节点“名字”添加组件SimpleScript。

在按钮的组件ButtoScript中找到节点“名字”并调用它的组件SimpleScript中的方法doChange()。

方法doChange():每次,点击测试按钮,都让节点“名字”的y位置的值为相反值。

Cocos Creator游戏开发教程 学习笔记_第151张图片

 P31 9.0小游戏:行走的佩奇Cocos Creator游戏开发教程 学习笔记_第152张图片

Cocos Creator游戏开发教程 学习笔记_第153张图片B站的视频里没有详细介绍怎么制作,发现需要购买B站上阿发博主的学习资料才能看到详细教程。下面是详细制作教程的学习笔记。

9.1 实例:行走的佩奇Cocos Creator游戏开发教程 学习笔记_第154张图片

 Cocos Creator游戏开发教程 学习笔记_第155张图片Cocos Creator游戏开发教程 学习笔记_第156张图片

9.2场景布局Cocos Creator游戏开发教程 学习笔记_第157张图片

步骤如下:

 Cocos Creator游戏开发教程 学习笔记_第158张图片

效果如图:

Cocos Creator游戏开发教程 学习笔记_第159张图片

 制作图片按钮:

Cocos Creator游戏开发教程 学习笔记_第160张图片

Label代表的就是按钮的文字button,可以删掉button换成图片。

Cocos Creator游戏开发教程 学习笔记_第161张图片

Cocos Creator游戏开发教程 学习笔记_第162张图片直接把图片拖动到Background下面就好了,右边就会直接显示这个图片。还可以修改按钮在不同鼠标状态下的的背景颜色。

Cocos Creator游戏开发教程 学习笔记_第163张图片

Cocos Creator游戏开发教程 学习笔记_第164张图片

 右按钮可以直接点击复制左按钮,然后修改名称并替换图片获得。然后移动位置即可。

Cocos Creator游戏开发教程 学习笔记_第165张图片

 Cocos Creator游戏开发教程 学习笔记_第166张图片

(如果想要调节两个按钮之间的间距,需要先调节间距,再调节水平对齐的状态。) 

  1. 按下Ctrl键然后选中两个按钮,
  2. 使用场景编辑器中的工具“垂直居中对齐”来使两个按钮位于同一条水平线上。
  3. 然后点击移动点拖动按钮整体移动位置。

Cocos Creator游戏开发教程 学习笔记_第167张图片

或者把背景图片勾掉禁用,暂时不显示,然后利用网格来实现对齐。

 Cocos Creator游戏开发教程 学习笔记_第168张图片

 Cocos Creator游戏开发教程 学习笔记_第169张图片

 9.3键盘事件

 Cocos Creator游戏开发教程 学习笔记_第170张图片Cocos Creator游戏开发教程 学习笔记_第171张图片

 点击佩奇这个组件,然后把这个脚本直接拖动到添加组件按钮里面,就可以直接添加脚本。Cocos Creator游戏开发教程 学习笔记_第172张图片

 Ctri+S保存脚本,然后看看这个脚本。

Cocos Creator游戏开发教程 学习笔记_第173张图片

 Left和Right就是左右箭头。Cocos Creator游戏开发教程 学习笔记_第174张图片

 Cocos Creator游戏开发教程 学习笔记_第175张图片

 运行浏览器,看看这个脚本:需要先点击一下我们的游戏页面,让游戏捕捉到鼠标,然后点击键盘上的左右键才会出现打印日志。

Cocos Creator游戏开发教程 学习笔记_第176张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    @property(cc.Label)
    label: cc.Label = null;

    @property
    text: string = 'hello';

    // LIFE-CYCLE CALLBACKS:
   
     onLoad () {
         cc.systemEvent.on('keydown',this.onKeyDown,this);
            //在onload中添加键盘监听事件onKeyDown
     }

    start () {

    }

    onKeyDown(evt : cc.Event.EventKeyboard){//参数evt类型是cc.事件和键盘事件。
        if(evt.keyCode == cc.macro.KEY.left)
        {
            cc.log("Pig:向左一步");
        }
        else if(evt.keyCode == cc.macro.KEY.right)
        {
            cc.log("Pig:向右一步");
        }
    }


    // update (dt) {}
}

 Cocos Creator游戏开发教程 学习笔记_第177张图片

 9.4角色的移动

 Cocos Creator游戏开发教程 学习笔记_第178张图片Cocos Creator游戏开发教程 学习笔记_第179张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    // @property(cc.Label)
    // label: cc.Label = null;

    // @property
    // text: string = 'hello';

    //当前脸的朝向 : true,脸朝左;false,脸朝右。
    faceLeft : boolean = true;
    // LIFE-CYCLE CALLBACKS:
     onLoad () {
         cc.systemEvent.on('keydown',this.onKeyDown,this);
            //在onload中添加键盘监听事件onKeyDown
     }
    start () {}
    onKeyDown(evt : cc.Event.EventKeyboard){
        if(evt.keyCode == cc.macro.KEY.left)
        {
            cc.log("Pig:向左一步");
            this.moveLeft();
        }
        else if(evt.keyCode == cc.macro.KEY.right)
        {
            cc.log("Pig:向右一步");
            this.moveRight();
        }
    }
    // update (dt) {}
    moveLeft(){
        if( ! this.faceLeft){
            this.faceLeft = true;
            this.changeFace();//改变脸的朝向
        }
        this.move();//移动一步
    }
    moveRight(){
        if( this.faceLeft){
            this.faceLeft = false;
            this.changeFace();//改变脸的朝向
        }
        this.move();//移动一步
    }
   
   move(){
       if(this.faceLeft){
        this.node.x -= 10;//向左移动
       }else{
        this.node.x += 10;//向右移动
       }
    }
    changeFace(){ //改变脸的朝向
        cc.log("改变行走方向,脸朝" + (this.faceLeft ? '左' : '右'));
    }   
}

Cocos Creator游戏开发教程 学习笔记_第180张图片 Cocos Creator游戏开发教程 学习笔记_第181张图片

Cocos Creator游戏开发教程 学习笔记_第182张图片Cocos Creator游戏开发教程 学习笔记_第183张图片

9.5动态显示图片 Cocos Creator游戏开发教程 学习笔记_第184张图片

 Cocos Creator游戏开发教程 学习笔记_第185张图片

图文教程如下:

第一种方式:直接翻转(需要根据初始图片脸的朝向  分析代码)

this.node.scaleX = 0 - this.node.scaleX;

比如,原来节点的 scale 为 (0.7 , 0.7 ) ,翻转后为 (-0.7,  0.7)。

但这并不是一个好办法,因为直正的人可能比较复杂,翻转之后可能穿帮。

changeFace(){
 cc.log("改变行走方向,脸朝" + (this.faceLeft ? '左' : '右'));
//大前提:  初始图片脸朝右 且 this.node.scaleX >0
 if(this.faceLeft && (this.node.scaleX >0)||((!this.faceLeft) && (this.node.scaleX <0)))
 {//向左走 现在图片是脸朝右的,需要图片脸朝左     //向右走  现在图片是脸朝左的,需要图片脸朝右
      this.node.scaleX = 0 - this.node.scaleX;
 }else{  
//((this.faceLeft && (this.node.scaleX <0))||((!this.faceLeft) && (this.node.scaleX >0)))
//向左走 现在图片是脸朝左的,不需要改变图片脸朝向 //向右走  现在图片是脸朝右的,不需要改变图片脸朝向  
      this.node.scaleX = this.node.scaleX;
 }
}   

第二种方式:(不需要判断初始图片脸的朝向。直接换图片,然后移动位置就可以了。)

1 准备素材

朝左、朝右两种状态的图片,放在资源管理器里。

2 添加属性   

// 两种状态的图片帧
@property(cc.SpriteFrame)
face1: cc.SpriteFrame = null;
@property(cc.SpriteFrame)
face2: cc.SpriteFrame = null;

3 在Cocos Creator里,给face1 face2指定资源图片

Cocos Creator游戏开发教程 学习笔记_第186张图片

4 动态切换图片          

 changeFace(){
  cc.log("改变行走方向,脸朝" + (this.faceLeft ? '左' : '右'));
  // 获取 Sprite 组件
  let sprite : cc.Sprite = this.node.getComponent(cc.Sprite);
  // 修改 Sprite 组件的 Sprite Frame 属性
  //无论初始图片是脸朝左还是脸朝右,都没关系。
  if(this.faceLeft){
     sprite.spriteFrame = this.face1; //需要图片脸朝左         
  }else{
     sprite.spriteFrame = this.face2; //需要图片脸朝右
  }
}   

Cocos Creator游戏开发教程 学习笔记_第187张图片

Cocos Creator游戏开发教程 学习笔记_第188张图片

 9.6脚本的调用

 Cocos Creator游戏开发教程 学习笔记_第189张图片

 实现左右移动的按钮:

Cocos Creator游戏开发教程 学习笔记_第190张图片

 想办法在按钮ButtonScript.ts中调用PigScript.ts中的moveLeft()和moveRight()方法就可以了。找路径的时候可以使用显示节点的UUID和路径。

Cocos Creator游戏开发教程 学习笔记_第191张图片

 然后添加进按钮组件中。

注意右按钮的toLeft属性要去掉。

Cocos Creator游戏开发教程 学习笔记_第192张图片

 Cocos Creator游戏开发教程 学习笔记_第193张图片

@property
toLeft : boolean = true;
// LIFE-CYCLE CALLBACKS:
onLoad () {
  this.node.on('mousedown',this.onClicked,this);
}
start () {}
onClicked(){
  let node : cc.Node = cc.find('Canvas/佩奇_右');
  let script = node.getComponent('PigScript');
  if(this.toLeft){
    script.moveLeft();
  }else{
    script.moveRight();
  }
}

至此按钮功能实现了。

接下来需要为行走添加音效:

参照:

Cocos Creator游戏开发教程 学习笔记_第194张图片

 Cocos Creator游戏开发教程 学习笔记_第195张图片

 Cocos Creator游戏开发教程 学习笔记_第196张图片

 先在PigScript.ts中添加

Cocos Creator游戏开发教程 学习笔记_第197张图片

 Cocos Creator游戏开发教程 学习笔记_第198张图片

Cocos Creator游戏开发教程 学习笔记_第199张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;
//PigScript.ts
@ccclass
export default class NewClass extends cc.Component {

    // @property(cc.Label)
    // label: cc.Label = null;

    // @property
    // text: string = 'hello';
    //cc.AudioClip 表示一个音频资源,例如一个MP3
    @property(cc.AudioClip)
    audio : cc.AudioClip = null;


    //当前脸的朝向 : true,脸朝左;false,脸朝右。
    faceLeft : boolean = true;

    //两种状态的图片帧
    @property(cc.SpriteFrame)
    face1 : cc.SpriteFrame = null;
    @property(cc.SpriteFrame)
    face2 : cc.SpriteFrame = null;

    // LIFE-CYCLE CALLBACKS:
     onLoad () {
         cc.systemEvent.on('keydown',this.onKeyDown,this);
            //在onload中添加键盘监听事件onKeyDown
     }
    start () {}
    onKeyDown(evt : cc.Event.EventKeyboard){
        if(evt.keyCode == cc.macro.KEY.left)
        {
            cc.log("Pig:向左一步");
            this.moveLeft();
        }
        else if(evt.keyCode == cc.macro.KEY.right)
        {
            cc.log("Pig:向右一步");
            this.moveRight();
        }
        //播放脚步声音频
        if(this.audio != null){
            cc.audioEngine.play(this.audio,false,1);
        }
    }
    // update (dt) {}
    moveLeft(){
        if( ! this.faceLeft){
            this.faceLeft = true;//向左走
            this.changeFace();//改变脸的朝向
        }
        this.move();//移动一步
    }
    moveRight(){
        if(this.faceLeft){
            this.faceLeft = false;//向右走
            this.changeFace();//改变脸的朝向
        }
        this.move();//移动一步
    }
    //改变脸的朝向
   move(){
       if(this.faceLeft){
        this.node.x -= 10;//向左移动
       }else{
        this.node.x += 10;//向右移动
       }
    }
    changeFace(){
        cc.log("改变行走方向,脸朝" + (this.faceLeft ? '左' : '右'));
        // 获取 Sprite 组件
// TODO: 为了优化效率,可以在onLoad()里就把这个 cc.Sprite引用给准备好
        let sprite : cc.Sprite = this.node.getComponent(cc.Sprite);
        // 修改 Sprite 组件的 Sprite Frame 属性
        //无论初始图片是脸朝左还是脸朝右,都没关系。
        if(this.faceLeft){//向左走
            sprite.spriteFrame = this.face1; //需要图片脸朝左        
        }else{//向右走
            sprite.spriteFrame = this.face2; //需要图片脸朝右
        }
    }   
    // changeFace(){
    //     cc.log("改变行走方向,脸朝" + (this.faceLeft ? '左' : '右'));
    //大前提:   初始图片脸朝右 且 this.node.scaleX >0
    //     if(this.faceLeft && (this.node.scaleX >0) ||( (!this.faceLeft) && (this.node.scaleX <0) ))
    //     { //向左走 现在图片是脸朝右的,需要图片脸朝左     //向右走  现在图片是脸朝左的,需要图片脸朝右
    //         this.node.scaleX = 0 - this.node.scaleX;
    //     }else{  ((this.faceLeft && (this.node.scaleX <0) ) || ((!this.faceLeft) && (this.node.scaleX >0)) )
    //             //向左走 现在图片是脸朝左的,不需要改变图片脸朝向     //向右走  现在图片是脸朝右的,不需要改变图片脸朝向  
    //         this.node.scaleX = this.node.scaleX;
    //     }
    // }   
}

然后在ButtonScript.ts中添加音频,两个按钮都要添加:

Cocos Creator游戏开发教程 学习笔记_第200张图片

 Cocos Creator游戏开发教程 学习笔记_第201张图片

 

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;
//ButtonScript.ts
@ccclass
export default class NewClass extends cc.Component {
    // @property(cc.Label)
    // label: cc.Label = null;
    // @property
    // text: string = 'hello';
    //cc.AudioClip 表示一个音频资源,例如一个MP3
    @property(cc.AudioClip)
    audio : cc.AudioClip = null;
    @property
    toLeft : boolean = true;
    // LIFE-CYCLE CALLBACKS:
    onLoad () {
        this.node.on('mousedown',this.onClicked,this);
    }
    start () {}
    onClicked(){
        let node : cc.Node = cc.find('Canvas/佩奇_右');
        let script = node.getComponent('PigScript');
        if(this.toLeft){
            script.moveLeft();
        }else{
            script.moveRight();
        }
        //播放脚步声音频
        if(this.audio != null){//audio engine音频引擎
            cc.audioEngine.play(this.audio,false,1);
        }

    }
    // update (dt) {}
}

Cocos Creator游戏开发教程 学习笔记_第202张图片Cocos Creator游戏开发教程 学习笔记_第203张图片

//播放音频
var id = cc.audioEngine.play(path, loop, volume ); 
//参数path代表音频路径,loop代表是否循环, volume代表音量范围0~1.0

//设置音频是否循环
cc.audioEngine.setLoop(id, loop);   //id代表由play获得的id,loop代表是否循环

//获取音频的循环状态
cc.audioEngine.isLoop(id);   //id代表由play获得的id

//设置音量(0.0 ~ 1.0)
cc.audioEngine.setVolume(id, volume);   //id代表由play获得的id, volume代表音量范围0~1.0

//获取音量(0.0 ~ 1.0)
var volume = cc.audioEngine.getVolume(id);    //id代表由play获得的id

//设置当前的音频时间
cc.audioEngine.setCurrentTime(id, time);    //id代表由play获得的id,time代表播放的当前位置
(单位为秒)

//获取当前的音频播放时间
var time = cc.audioEngine.getCurrentTime(id);   //id代表由play获得的id

//获取音频总时长
var time = cc.audioEngine.getDuration(id);    //id代表由play获得的id

//获取音频状态
var state = cc.audioEngine.getState(id);      //id代表由play获得的id

//设置一个音频结束后的回调
cc.audioEngine.setFinishCallback(id, function () {});//id代表由play获得的id,第二个参数是自己的回调哦

//暂停正在播放音频
cc.audioEngine.pause(id);      //id代表由play获得的id

//暂停现在正在播放的所有音频
cc.audioEngine.pauseAll();

//恢复播放指定的音频
cc.audioEngine.resume(id);     //id代表由play获得的id

Cocos Creator游戏开发教程 学习笔记_第204张图片

Cocos Creator游戏开发教程 学习笔记_第205张图片

10.1坐标系

 Cocos Creator游戏开发教程 学习笔记_第206张图片

 Cocos Creator游戏开发教程 学习笔记_第207张图片

 二维坐标:Cocos Creator游戏开发教程 学习笔记_第208张图片

Cocos Creator游戏开发教程 学习笔记_第209张图片

三维坐标:

 Cocos Creator游戏开发教程 学习笔记_第210张图片

Cocos Creator游戏开发教程 学习笔记_第211张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    @property(cc.Label)
    label: cc.Label = null;

    @property
    text: string = 'hello';
    // LIFE-CYCLE CALLBACKS:
    onLoad () {
        this.node.on('mousedown',this.OnClicked,this);
    }

    start () {

    }
    OnClicked(){
        let node : cc.Node= cc.find('Canvas/佩奇_右');
        //二维坐标两种写法:
        //比较长:
        let pos =  new  cc.Vec2(100,100);
        //cocos还提供了一个方法,更简略的写法:
        //更常用
        let pos2 =  cc.v2(100,100);
        //三维坐标
        let pos3 = new cc.Vec3(1000,100,100);
        let pos4 = cc.v3(1000,100,100);
    }

    // update (dt) {}
}

 Cocos Creator游戏开发教程 学习笔记_第212张图片

 Cocos Creator游戏开发教程 学习笔记_第213张图片

 Cocos Creator游戏开发教程 学习笔记_第214张图片

  OnClicked(){
        let node : cc.Node= cc.find('Canvas/佩奇_右');
        let pos : cc.Vec2 = node.getPosition();
        cc.log(pos);
    }

 发现返回的是一个三维向量,所以,以后写的时候可以直接把z写为0。

let pos1 = cc.v3(100,100,0);
node.setPosition(cc.v3(250,-120,0);//设置一个节点的坐标

 例如设置佩奇的节点坐标:使它发生平移。

OnClicked(){
   let node : cc.Node= cc.find('Canvas/佩奇_右');
   let pos : cc.Vec2 = node.getPosition();
   //平移佩奇
   node.setPosition(cc.v3(155.907,-29.374,0));
}

设置一个节点的缩放

node.setScale(cc.v3(1,1,0));

例如:

OnClicked(){
  let node : cc.Node= cc.find('Canvas/佩奇_右');
  let pos : cc.Vec2 = node.getPosition();
  //平移佩奇
  node.setPosition(cc.v3(155.907,-29.374,0));
  //设置大小缩放
  node.setScale(cc.v3(2,2,0));
}

Cocos Creator游戏开发教程 学习笔记_第215张图片

 Cocos Creator游戏开发教程 学习笔记_第216张图片

10.2缓动系统Cocos Creator游戏开发教程 学习笔记_第217张图片

 Cocos Creator游戏开发教程 学习笔记_第218张图片

 Cocos Creator游戏开发教程 学习笔记_第219张图片Cocos Creator游戏开发教程 学习笔记_第220张图片

 Cocos Creator游戏开发教程 学习笔记_第221张图片

 OnClicked(){
        let node : cc.Node= cc.find('Canvas/佩奇_右');
        //平移佩奇
        node.setPosition(cc.v3(250,-120,0));
}

 缓动:

position:

 OnClicked(){
        let node : cc.Node= cc.find('Canvas/佩奇_右');
        //平移佩奇
        //node.setPosition(cc.v3(250,-120,0));
        //缓动 用1s的时间实现从(-250,-120)移动到(250,-120)
        cc.tween(node).to(1,{position:cc.v3(250,-120,0)}).start();
}

 Cocos Creator游戏开发教程 学习笔记_第222张图片

图文教程:

链式调用,是 Java / C# 中的常用形式

cc.tween(node)

   .to(1, { position : cc.v3(250, -120, 0) } )

   .start();

相当于:

// 创建一个 cc.Tween 类型的对象

let tween = cc.tween ( node ); 

// tween.to()的返回值就是tween对象自身

tween = tween. to(1, { position : cc.v3(250, -120, 0) } ) ;  

// 开始动作

tween.start();

Cocos Creator游戏开发教程 学习笔记_第223张图片

OnClicked(){
   let node : cc.Node= cc.find('Canvas/佩奇_右');
   //平移佩奇
   //node.setPosition(cc.v3(250,-120,0));
   //缓动 用5s的时间实现从(-250,-120)移动到(250,-120)
   // cc.tween(node).to(5,{position:cc.v3(250,-120,0)}).start();  
   //先用3s缓慢移动,然后再 用2s旋转360度。
   cc.tween(node).to(3,{position:cc.v3(250,-120,0)}).to(2,{rotation:360}).start();
   //另一种写法:一边旋转一边移动
   // cc.tween(node).to(1,{position:cc.v3(250,-120,0),rotation:360}).start();

    }

10.3 cc.tween的用法

 Cocos Creator游戏开发教程 学习笔记_第224张图片Cocos Creator游戏开发教程 学习笔记_第225张图片

文档--》 功能模块--》缓动系统。 缓动系统 · Cocos Creator

Cocos Creator游戏开发教程 学习笔记_第226张图片

 Cocos Creator游戏开发教程 学习笔记_第227张图片

 Cocos Creator游戏开发教程 学习笔记_第228张图片

 Cocos Creator游戏开发教程 学习笔记_第229张图片

 佩奇的运动轨迹是画了个正方形。

 OnClicked(){
        let node : cc.Node= cc.find('Canvas/佩奇_右');
        //实现从(-250,-120,0)
        cc.tween(node)
            .by(1,{position:cc.v3(400,0,0)})//到(150,-120,0)
            .by(1,{position:cc.v3(0,400,0)})//到(150,280,0)
            .by(1,{position:cc.v3(-400,0,0)})//到(-250,280,0)
            .by(1,{position:cc.v3(0,-400,0)})//到(-250,-120,0)
            .start();
        cc.tween(node)
            .to(1,{position:cc.v3(150,-120,0)})//到(150,-120,0)
            .to(1,{position:cc.v3(150,280,0)})//到(150,280,0)
            .to(1,{position:cc.v3(-250,280,0)})//到(-250,280,0)
            .to(1,{position:cc.v3(-250,-120,0)})//到(-250,-120,0)
            .start();
 }

Cocos Creator游戏开发教程 学习笔记_第230张图片

 Cocos Creator游戏开发教程 学习笔记_第231张图片Cocos Creator游戏开发教程 学习笔记_第232张图片Cocos Creator游戏开发教程 学习笔记_第233张图片

 Cocos Creator游戏开发教程 学习笔记_第234张图片

 时间duration,目标参数props,速度easing。

OnClicked(){
        let node : cc.Node= cc.find('Canvas/佩奇_右');
        //easing
        cc.tween(node)
            .by(5,{position:cc.v3(0,400,0)},{easing:'quadOut'})
            .by(5,{position:cc.v3(800,0,0)},{easing:'quadOut'})
            .by(5,{position:cc.v3(0,-400,0)},{easing:'quadOut'})
            .by(5,{position:cc.v3(-800,0,0)},{easing:'quadOut'})
            .start();
    }

Cocos Creator游戏开发教程 学习笔记_第235张图片

类型别名: TweenEasing

导入示例:

import { TweenEasing } from "cc";

TweenEasing

内置缓动函数的字符串值定义。

public TweenEasing : "linear" | "smooth" | "fade" | "constant" | "quadIn" | "quadOut" | "quadInOut" | "quadOutIn" | "cubicIn" | "cubicOut" | "cubicInOut" | "cubicOutIn" | "quartIn" | "quartOut" | "quartInOut" | "quartOutIn" | "quintIn" | "quintOut" | "quintInOut" | "quintOutIn" | "sineIn" | "sineOut" | "sineInOut" | "sineOutIn" | "expoIn" | "expoOut" | "expoInOut" | "expoOutIn" | "circIn" | "circOut" | "circInOut" | "circOutIn" | "elasticIn" | "elasticOut" | "elasticInOut" | "elasticOutIn" | "backIn" | "backOut" | "backInOut" | "backOutIn" | "bounceIn" | "bounceOut" | "bounceInOut" | "bounceOutIn"

内置缓动函数的字符串值定义。

Defined in cocos/tween/export-api.ts:33

 Cocos Creator游戏开发教程 学习笔记_第236张图片

找不到这个文档。 可以在csdn上直接搜索“tween 缓动 ”。

(14条消息) tween的缓动效果大全和使用方法_飞浪纪元[FWC–FE]的博客-CSDN博客_tween 缓动  https://blog.csdn.net/weixin_38531633/article/details/115480255

Cocos Creator游戏开发教程 学习笔记_第237张图片

10.4拍球Cocos Creator游戏开发教程 学习笔记_第238张图片

 Cocos Creator游戏开发教程 学习笔记_第239张图片

onLoad () {
     this.node.on('touchstart',this.onClicked,this);
    }
start () {}
onClicked(){
     let h : number = 400;
     cc.tween(this.node)
        .by(0.5,{position : cc.v3(0,-h,0)},{easing:"quardIn"})  //加速,下降
        .by(0.2,{position : cc.v3(0,h/4,0)},{easing:"quardOut"}) //反弹,减速,上升
        .by(0.2,{position : cc.v3(0,-h/4,0)},{easing:"quardIn"}) //加速,再下降
        .start();

 }

Cocos Creator游戏开发教程 学习笔记_第240张图片Cocos Creator游戏开发教程 学习笔记_第241张图片

Cocos Creator游戏开发教程 学习笔记_第242张图片 

 得到一个白色方块,修改名称为 地面。 

修改锚点anchor的y值为0,让它的中心点在图像篮球的下边缘。

Cocos Creator游戏开发教程 学习笔记_第243张图片

 地面的锚点anchor的y值为1,让它的中心点在图像地面的上边缘。计算Positon的y=180-400=-220.

Cocos Creator游戏开发教程 学习笔记_第244张图片

 运行:篮球掉落到地平线上。

Cocos Creator游戏开发教程 学习笔记_第245张图片

11.1动画Cocos Creator游戏开发教程 学习笔记_第246张图片

 Cocos Creator游戏开发教程 学习笔记_第247张图片

 创建这个文件夹列表,然后把PigScript组件添加给佩奇。

Cocos Creator游戏开发教程 学习笔记_第248张图片

 Cocos Creator游戏开发教程 学习笔记_第249张图片

 update()方法 默认 每秒钟会被这个动画调用60次。可以使用日志看一眼:

update (dt) {
    cc.log("update() is called , time = " + new Date().getTime());
}

Cocos Creator游戏开发教程 学习笔记_第250张图片Cocos Creator游戏开发教程 学习笔记_第251张图片

// onLoad () {}  //初始化加载
    start () { }    //第一次启动的时候
    //update() 方法 就是 帧动画的绘制。
    update (dt) {
        //cc.log("update() is called , time = " + new Date().getTime());//打印设置每一帧的刷新时间
        if(this.node.x>= 200){
            return;  //总距离移动200像素。 然后停止运动。
        }else{
            this.node.x += 5; //将节点移动5像素。
        }
    }

Cocos Creator游戏开发教程 学习笔记_第252张图片

Cocos Creator游戏开发教程 学习笔记_第253张图片

 11.2帧率Cocos Creator游戏开发教程 学习笔记_第254张图片

 Cocos Creator游戏开发教程 学习笔记_第255张图片

 Cocos Creator游戏开发教程 学习笔记_第256张图片Cocos Creator游戏开发教程 学习笔记_第257张图片

 update (dt) {
        //cc.log("update() is called , time = " + new Date().getTime());//打印设置每一帧的刷新时间
        cc.log('delta time=' + dt);   //打印设置每一帧的时间间隔
        if(this.node.x>= 200){
            return;  //总距离移动200像素。 然后停止运动。
        }else{
            this.node.x += 5; //将节点移动5像素。
        }
    }

 Cocos Creator游戏开发教程 学习笔记_第258张图片

 可以看到0.016s。

Cocos Creator游戏开发教程 学习笔记_第259张图片

把GameInitScript挂在Canvas中。因为游戏是从根节点Canvas开始运行的,所以先加载Canvas下面的组件,故我们可以把所有的全局设置放在GameInitScript中,从根节点加载就开始运行组件GameInitScript。

 Cocos Creator游戏开发教程 学习笔记_第260张图片

GameInitScript.ts 中:

onLoad () {
        cc.log('Pig Script : onload()');
        cc.game.setFrameRate(30);  //设置帧率为30帧/秒
    }

    start () {

    }

   // update (dt) {}

 Cocos Creator游戏开发教程 学习笔记_第261张图片FPS大概是30帧/秒。

 Cocos Creator游戏开发教程 学习笔记_第262张图片

 11.3状态控制Cocos Creator游戏开发教程 学习笔记_第263张图片

 Cocos Creator游戏开发教程 学习笔记_第264张图片Cocos Creator游戏开发教程 学习笔记_第265张图片

Cocos Creator游戏开发教程 学习笔记_第266张图片

Cocos Creator游戏开发教程 学习笔记_第267张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

//PigScript.ts的代码
@ccclass
export default class NewClass extends cc.Component {
    //速度(每次移动多少像素)
    speed : number = 3;
    //方向
    //例如,水平向右(1,0) 数直向下(0,-1)
    direction : cc.Vec2 = null;
    // LIFE-CYCLE CALLBACKS:
    //初始化加载
    onLoad () {
        cc.log('Pig Script : onload()');
        cc.systemEvent.on('keydown',this.onKeyPress,this);
    } 
    //第一次启动的时候
    start () {}  
    //onKeyPress()
    onKeyPress(e : cc.Event.EventKeyboard){
        if(e.keyCode == cc.macro.KEY.left){
            this.direction = cc.v2(-1,0);
        }else if(e.keyCode == cc.macro.KEY.right){
            this.direction = cc.v2(1,0);
        }else if(e.keyCode == cc.macro.KEY.up){
            this.direction = cc.v2(0,1);
        }else if(e.keyCode == cc.macro.KEY.down){
            this.direction = cc.v2(0,-1);
        }else if(e.keyCode == cc.macro.KEY.space){
            this.direction = null;
        }
    } 
    //update() 方法 就是 帧动画的绘制。
    update (dt) {
        if(this.direction == null) return; //原地不动
        let pos:cc.Vec2 = this.node.getPosition();
        pos.x += this.speed * this.direction.x;
        pos.y += this.speed * this.direction.y;
        this.node.setPosition(pos);       
    }
}

Cocos Creator游戏开发教程 学习笔记_第268张图片

11.4计时器Cocos Creator游戏开发教程 学习笔记_第269张图片

Cocos Creator游戏开发教程 学习笔记_第270张图片Cocos Creator游戏开发教程 学习笔记_第271张图片

 Cocos Creator游戏开发教程 学习笔记_第272张图片Cocos Creator游戏开发教程 学习笔记_第273张图片Cocos Creator游戏开发教程 学习笔记_第274张图片

 

使用计时器 · Cocos Creator  https://docs.cocos.com/creator/manual/zh/scripting/scheduler.html

Cocos Creator游戏开发教程 学习笔记_第275张图片

下面是 Component 中所有关于计时器的函数:

  • schedule:开始一个计时器
  • scheduleOnce:开始一个只执行一次的计时器
  • unschedule:取消一个计时器
  • unscheduleAllCallbacks:取消这个组件的所有计时器

 计时器的应用:

Cocos Creator游戏开发教程 学习笔记_第276张图片

Cocos Creator游戏开发教程 学习笔记_第277张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    label : cc.Label = null ;
    text : string = null;
    index : number = 0;

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        this.label = this.getComponent(cc.Label);
        this.text = this.label.string;//取得完整的文本
        this.label.string = '';//清空文本,从头显示 

        this.schedule(this.onTimer,0.3);//无限运行下去,每次间隔0.3秒
                            //显示每个字“恭喜请领取奖励”
    }
    start () {}
    onTimer(){
        this.index ++;
        let str : string = this.text.substring(0,this.index);
        this.label.string = str;
        cc.log('显示label=' + str);
        if(this.index >= this.text.length){
            this.unschedule(this.onTimer);//取消这个onTimer()计时器
        }      
    }
    // update (dt) {}
}

Cocos Creator游戏开发教程 学习笔记_第278张图片

 Cocos Creator游戏开发教程 学习笔记_第279张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    label : cc.Label = null ;
    text : string = null;
    index : number = 0;

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        this.label = this.getComponent(cc.Label);
        this.text = this.label.string;//取得完整的文本
        cc.log('显示this.text=' + this.text);

        this.label.string = '';//清空文本,从头显示 
        cc.log('显示this.label.string=' + this.label.string);

        this.schedule(this.onTimer,0.3);//无限运行下去,每次间隔0.3秒
                            //显示每个字“恭喜请领取奖励”
    }
    start () {}
    onTimer(){
        this.index ++;
        cc.log('显示this.index=' + this.index);
        let str : string = this.text.substring(0,this.index);
        this.label.string = str;
        cc.log('显示label=' + str);
        if(this.index >= this.text.length){
            this.unschedule(this.onTimer);//取消这个onTimer()计时器
        }      
    }
    // update (dt) {}
}

Cocos Creator游戏开发教程 学习笔记_第280张图片

Cocos Creator游戏开发教程 学习笔记_第281张图片

 间隔0.3秒,文字“恭喜请领取奖励”一个个的出现。

Cocos Creator游戏开发教程 学习笔记_第282张图片

Cocos Creator游戏开发教程 学习笔记_第283张图片

 Cocos Creator游戏开发教程 学习笔记_第284张图片

 再次优化,在文字上面添加一个灰字的效果:

复制,提示文字,命名为 灰字(不要ShowTips代码),修改原来的为 高亮(要ShowTips代码)。

Cocos Creator游戏开发教程 学习笔记_第285张图片

Cocos Creator游戏开发教程 学习笔记_第286张图片

Cocos Creator游戏开发教程 学习笔记_第287张图片

显示效果如图:

 Cocos Creator游戏开发教程 学习笔记_第288张图片

Cocos Creator游戏开发教程 学习笔记_第289张图片

Cocos Creator游戏开发教程 学习笔记_第290张图片

 Cocos Creator游戏开发教程 学习笔记_第291张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
const {ccclass, property} = cc._decorator;
@ccclass
export default class NewClass extends cc.Component {
    //作为全局变量,在方法中使用
    label : cc.Label = null;//每次更新组件label
    text : string = null; //按照text的值显示字段的长度并赋值给组件label中的string
    index : number = 0;//指定字段的长度最大值
   
    onLoad () {
        /*获得这个代码绑定的文字节点中的其他组件Label,
        并赋值给全局变量cc.Label类型的label。 */
        this.label = this.getComponent(cc.Label);
        //获取全局变量cc.Label组件的label的string值,赋值给text
        this.text = this.label.string;
        //清空全局变量 labal 中的string值。
        this.label.string = '';
        //在脚本 计时器方法schedule中,回调onTimer计时器方法。
        /* comp.schedule(
                callback(回调 赋值this.onTimer) , interval(时间间隔 赋值0.3) ,
                repeat(重复次数 未赋值) , delay(延迟时间 未赋值)
            );
         */
        this.schedule(this.onTimer,0.3);      
    }
    start () {}
    //onTimer计时器方法
    onTimer(){
        this.index ++;//指定string需要显示的字段的长度最大值
        //使用substring()获取对象中指定位置的字符串
        let str : string = this.text.substring(0,this.index);
        //赋值给 被清空的全局变量 labal 中的string。
        this.label.string = str;   cc.log('显示label=' + str);
        //如果index大于字符串的总长度,那么结束回调方法
        if(this.index >= this.text.length){
            this.unschedule(this.onTimer);
        }    
    }
    // update (dt) {}
}

 12.1小游戏实例:手柄控制器Cocos Creator游戏开发教程 学习笔记_第292张图片

 

Cocos Creator游戏开发教程 学习笔记_第293张图片

 12.2布置场景Cocos Creator游戏开发教程 学习笔记_第294张图片

 Cocos Creator游戏开发教程 学习笔记_第295张图片

 Cocos Creator游戏开发教程 学习笔记_第296张图片Cocos Creator游戏开发教程 学习笔记_第297张图片

 然后再创建一个纯色的背景,并修改相关的参数:

Cocos Creator游戏开发教程 学习笔记_第298张图片

Cocos Creator游戏开发教程 学习笔记_第299张图片

 Cocos Creator游戏开发教程 学习笔记_第300张图片Cocos Creator游戏开发教程 学习笔记_第301张图片

 调整缩放Scale让小车也变小一点。

12.3手柄的拖动Cocos Creator游戏开发教程 学习笔记_第302张图片

 Cocos Creator游戏开发教程 学习笔记_第303张图片

 因为我们的游戏最终都是要放到手机上进行的(所以不采用原来单一的mousedown等(鼠标类型))。换成touch~等事件,可以使用鼠标或者触摸屏操作。

Cocos Creator游戏开发教程 学习笔记_第304张图片

 把脚本GamePad.ts添加到手柄下面,作为组件:

Cocos Creator游戏开发教程 学习笔记_第305张图片Cocos Creator游戏开发教程 学习笔记_第306张图片

 this.node.on()方法:Cocos Creator游戏开发教程 学习笔记_第307张图片

 (method) cc.Node.on<(e: cc.Event.EventTouch) => void>(type: string, callback: (e: cc.Event.EventTouch) => void, target?: any, useCapture?: boolean): (e: cc.Event.EventTouch) => void

!#en Register a callback of a specific event type on Node. Use this method to register touch or mouse event permit propagation based on scene graph, These kinds of event are triggered with dispatchEvent, the dispatch process has three steps:

  1. Capturing phase: dispatch in capture targets (_getCapturingTargets), e.g. parents in node tree, from root to the real target
  2. At target phase: dispatch to the listeners of the real target
  3. Bubbling phase: dispatch in bubble targets (_getBubblingTargets), e.g. parents in node tree, from the real target to root In any moment of the dispatching process, it can be stopped via event.stopPropagation() or event.stopPropagationImmidiate(). It's the recommended way to register touch/mouse event for Node, please do not use cc.eventManager directly for Node. You can also register custom event and use emit to trigger custom event on Node. For such events, there won't be capturing and bubbling phase, your event will be dispatched directly to its listeners registered on the same node. You can also pass event callback parameters with emit by passing parameters after type. !#zh 在节点上注册指定类型的回调函数,也可以设置 target 用于绑定响应函数的 this 对象。 鼠标或触摸事件会被系统调用 dispatchEvent 方法触发,触发的过程包含三个阶段:
  4. 捕获阶段:派发事件给捕获目标(通过 _getCapturingTargets 获取),比如,节点树中注册了捕获阶段的父节点,从根节点开始派发直到目标节点。
  5. 目标阶段:派发给目标节点的监听器。
  6. 冒泡阶段:派发事件给冒泡目标(通过 _getBubblingTargets 获取),比如,节点树中注册了冒泡阶段的父节点,从目标节点开始派发直到根节点。 同时您可以将事件派发到父节点或者通过调用 stopPropagation 拦截它。 推荐使用这种方式来监听节点上的触摸或鼠标事件,请不要在节点上直接使用 cc.eventManager。 你也可以注册自定义事件到节点上,并通过 emit 方法触发此类事件,对于这类事件,不会发生捕获冒泡阶段,只会直接派发给注册在该节点上的监听器 你可以通过在 emit 方法调用时在 type 之后传递额外的参数作为事件回调的参数列表

@param type — A string representing the event type to listen for.See {{#crossLink "Node/EventTyupe/POSITION_CHANGED"}}Node Events{{/crossLink}} for all builtin events.

(表示要侦听的事件类型的字符串。 所有内置事件请参见{{#crossLink"Node/EventTyupe/POSITION_CHANGED"}}Node Events{{/crossLink}}。  )

@param callback — The callback that will be invoked when the event is dispatched. The callback is ignored if it is a duplicate (the callbacks are unique).(当事件被分派时将被调用的回调。 如果回调是重复的(回调是唯一的),则忽略回调。 )

@param target — The target (this object) to invoke the callback, can be null(调用回调的目标(此对象)可以为空  )

@param useCapture — When set to true, the listener will be triggered at capturing phase which is ahead of the final target emit, otherwise it will be triggered during bubbling phase.(当设置为true时,侦听器将在捕获阶段(在最终目标发出之前)触发,否则将在冒泡阶段触发。  )

@example

this.node.on(cc.Node.EventType.TOUCH_START, this.memberFunction, this); // if "this" is component and the "memberFunction" declared in CCClass.
node.on(cc.Node.EventType.TOUCH_START, callback, this);
node.on(cc.Node.EventType.TOUCH_MOVE, callback, this);
node.on(cc.Node.EventType.TOUCH_END, callback, this);
node.on(cc.Node.EventType.TOUCH_CANCEL, callback, this);
node.on(cc.Node.EventType.ANCHOR_CHANGED, callback);
node.on(cc.Node.EventType.COLOR_CHANGED, callback);

 另外几个方法:

getLocation()方法:

Cocos Creator游戏开发教程 学习笔记_第308张图片

 convertToNodeSpaceAR()方法:Cocos Creator游戏开发教程 学习笔记_第309张图片

 setPosition()方法:

(method) cc.Node.setPosition(newPosOrX: number | cc.Vec2 | cc.Vec3, y?: number, z?: number): void

!#en Sets the position (x, y, z) of the node in its parent's coordinates. Usually we use cc.v2(x, y) to compose cc.Vec2 object, and passing two numbers (x, y) is more efficient than passing cc.Vec2 object. For 3D node we can use cc.v3(x, y, z) to compose cc.Vec3 object, and passing three numbers (x, y, z) is more efficient than passing cc.Vec3 object. !#zh 设置节点在父节点坐标系中的位置。 可以通过下面的方式设置坐标点:

  1. 传入 2 个数值 x, y。
  2. 传入 cc.v2(x, y) 类型为 cc.Vec2 的对象。
  3. 对于 3D 节点可以传入 3 个数值 x, y, z。
  4. 对于 3D 节点可以传入 cc.v3(x, y, z) 类型为 cc.Vec3 的对象。

@param newPosOrX — X coordinate for position or the position (x, y, z) of the node in coordinates

@param y — Y coordinate for position

@param z — Z coordinate for position

Cocos Creator游戏开发教程 学习笔记_第310张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    // onLoad () {}

    start () {
        this.node.on('touchstart',this.onTouchStart,this);
        this.node.on('touchmove',this.onTouchMove,this);
        this.node.on('touchend',this.onTouchCancel,this);
        this.node.on('touchcancel',this.onTouchCancel,this);
    }
    onTouchStart( e : cc.Event.EventTouch ){}//暂时没有用到,置空
    //计算触摸点的当前位置,把手柄的位置移动到触摸点所在的位置
    onTouchMove( e : cc.Event.EventTouch ){
        //e.getLocation()为触摸点的位置,是世界坐标
        //需要把世界坐标转换为本地坐标
        cc.log("世界坐标touch move : x=" + e.getLocationX() + ",y=" +e.getLocationY());
        let parent : cc.Node = this.node.parent;//父节点(圆形底盘)
        //e.getLocation() 获得触摸点的世界坐标(触点位置)
        //把触摸点的世界坐标转换为父节点(圆形底盘)的本地坐标 ,pos代表触摸点的本地坐标
        let pos : cc.Vec2 = parent.convertToNodeSpaceAR(e.getLocation());
        //根据pos触摸点的本地坐标,使用setPosition()设置手柄在父节点的本地坐标
        this.node.setPosition(pos);
        cc.log("转换成本地坐标convert to local: x=" +  pos.x + ",y=" + pos.y); 
    }
    onTouchCancel( e : cc.Event.EventTouch ){
        //触摸松开的时候,把手柄的位置移动到中央
        this.node.setPosition( cc.v3(0,0,0));
    }
    // update (dt) {}
}

Cocos Creator游戏开发教程 学习笔记_第311张图片 Cocos Creator游戏开发教程 学习笔记_第312张图片

世界坐标是Canvas的原点,本地坐标是游戏摇杆的底盘原点。

Cocos Creator游戏开发教程 学习笔记_第313张图片

12.4方位角Cocos Creator游戏开发教程 学习笔记_第314张图片

 这个点 连接 原点形成的线和x轴的夹角就是方位角。Cocos Creator游戏开发教程 学习笔记_第315张图片

 Cocos Creator游戏开发教程 学习笔记_第316张图片

Cocos Creator游戏开发教程 学习笔记_第317张图片Cocos Creator游戏开发教程 学习笔记_第318张图片

 单位圆的x值就是cos值,y值就是sin值。 使用normalize()就可以得到这个方位角的(x,y)值。

Cocos Creator游戏开发教程 学习笔记_第319张图片

 Cocos Creator游戏开发教程 学习笔记_第320张图片

 有了方位角之后,我们来给手柄一个拖动范围的限制:

  Cocos Creator游戏开发教程 学习笔记_第321张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    // onLoad () {}

    start () {
        this.node.on('touchstart',this.onTouchStart,this);
        this.node.on('touchmove',this.onTouchMove,this);
        this.node.on('touchend',this.onTouchCancel,this);
        this.node.on('touchcancel',this.onTouchCancel,this);
    }
    onTouchStart( e : cc.Event.EventTouch ){}//暂时没有用到,置空
    //计算触摸点的当前位置,把手柄的位置移动到触摸点所在的位置
    onTouchMove( e : cc.Event.EventTouch ){
        //e.getLocation()为触摸点的位置,是世界坐标
        //1.需要把世界坐标转换为本地坐标
             cc.log("世界坐标touch move : x=" + e.getLocationX() + ",y=" +e.getLocationY());
        let parent : cc.Node = this.node.parent;//父节点(圆形底盘)
        //e.getLocation() 获得触摸点的世界坐标(触点位置)
        //把触摸点的世界坐标转换为父节点(圆形底盘)的本地坐标 ,pos代表触摸点的本地坐标
        let pos : cc.Vec2 = parent.convertToNodeSpaceAR(e.getLocation());
        
        // 该点所在的方位(cos,sin)
        let direction : cc.Vec2 = pos.normalize();
            cc.log("方位 : cos=" + direction.x + ", sin=" + direction.y);

        //2.限制手柄在“圆形底盘”的边界之内
        //最大距离圆形底盘的半径R=100,手柄的半径r=40;maxD=R-r=60;
        let maxD = 100 * 0.6; 
        //“触摸点”和“手柄圆心”两点之间的实际距离△d(在二维空间中的欧氏距离就是两点之间的直线段距离)
        let d: number = cc.Vec2.distance( pos , cc.v2(0,0) );
            cc.log("欧氏距离 :△d=" + d);
        if( d > maxD ){
            pos.x = maxD * direction.x;//d * cos
            pos.y = maxD * direction.y;//d * sin
        }
        //根据pos触摸点的本地坐标,使用setPosition()设置手柄在父节点的本地坐标
        this.node.setPosition(pos);
            cc.log("转换成本地坐标convert to local: x=" +  pos.x + ",y=" + pos.y); 
    }
    onTouchCancel( e : cc.Event.EventTouch ){
        //触摸松开的时候,把手柄的位置移动到父节点(圆形底盘)的中央
        this.node.setPosition( cc.v3(0,0,0));
    }
    // update (dt) {}
}

 Cocos Creator游戏开发教程 学习笔记_第322张图片

 找到相似的触摸点,从△d≈59可以看出,以上图是正确的:(因为两张图不是一次截的,有一点是后期修改了,请不要介意。因为数据是对的。)

Cocos Creator游戏开发教程 学习笔记_第323张图片

12.5小车的旋转Cocos Creator游戏开发教程 学习笔记_第324张图片

 添加节点小车:Cocos Creator游戏开发教程 学习笔记_第325张图片

Cocos Creator游戏开发教程 学习笔记_第326张图片

Cocos Creator游戏开发教程 学习笔记_第327张图片

 关于角度的解释,以下为正确解释:

1 cc.Node.angle

表示旋转的角度,逆时针为正

官方建议不要使用 cc.Node.rotation

2 a.signAngle( b)

a和b为两个向量,返回值是一a,b的夹角 (弧度值)

radian = a.signAngle(b)

分两种情况:

(1) a位于b的顺时针方向:角度为正

Cocos Creator游戏开发教程 学习笔记_第328张图片

(2) a位于b的逆时针方向:角度为负

Cocos Creator游戏开发教程 学习笔记_第329张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    //目标小车  节点
    car : cc.Node = null;
        
    onLoad(){
        this.car = cc.find('Canvas/小车');
    }

    start () {
        this.node.on('touchstart',this.onTouchStart,this);
        this.node.on('touchmove',this.onTouchMove,this);
        this.node.on('touchend',this.onTouchCancel,this);
        this.node.on('touchcancel',this.onTouchCancel,this);
    }
    onTouchStart( e : cc.Event.EventTouch ){}//暂时没有用到,置空
    //计算触摸点的当前位置,把手柄的位置移动到触摸点所在的位置
    onTouchMove( e : cc.Event.EventTouch ){
        
        //e.getLocation()为触摸点的位置,是世界坐标
        //1.需要把世界坐标转换为本地坐标
             cc.log("世界坐标touch move : x=" + e.getLocationX() + ",y=" +e.getLocationY());
        let parent : cc.Node = this.node.parent;//父节点(圆形底盘)
        //e.getLocation() 获得触摸点的世界坐标(触点位置)
        //把触摸点的世界坐标转换为父节点(圆形底盘)的本地坐标 ,pos代表触摸点的本地坐标
        let pos : cc.Vec2 = parent.convertToNodeSpaceAR(e.getLocation());
        
        // 该点所在的方位(cos,sin)
        let direction : cc.Vec2 = pos.normalize();
            cc.log("方位 : cos=" + direction.x + ", sin=" + direction.y);

        //2.限制手柄在“圆形底盘”的边界之内
        //最大距离圆形底盘的半径R=100,手柄的半径r=40;maxD=R-r=60;
        let maxD = 100 * 0.6; 
        //“触摸点”和“手柄圆心”两点之间的实际距离△d(在二维空间中的欧氏距离就是两点之间的直线段距离)
        let d: number = cc.Vec2.distance( pos , cc.v2(0,0) );
            cc.log("欧氏距离 :△d=" + d);
        if( d > maxD ){
            pos.x = maxD * direction.x;//d * cos
            pos.y = maxD * direction.y;//d * sin
        }
        //根据pos触摸点的本地坐标,使用setPosition()设置手柄在父节点的本地坐标
        this.node.setPosition(pos);
            cc.log("转换成本地坐标convert to local: x=" +  pos.x + ",y=" + pos.y); 

        //3.操纵目标小车
        //  radian = a.angle(b) 求a,b两个向量的夹角
        //  其中 cc.v2(1,0) 表示x轴方向的单位向量
        let radian = pos.signAngle(cc.v2(1,0)); //弧度值
        let angle = radian / Math.PI * 180; //把弧度制转换成角度值
        this.car.angle = -angle; // 按API要求,angle是按逆时针为正的
       // this.car.rotation = angle; //这样写也行,但是不如 this.car.angle = -angle;

    }
    onTouchCancel( e : cc.Event.EventTouch ){
        //触摸松开的时候,把手柄的位置移动到父节点(圆形底盘)的中央
        this.node.setPosition( cc.v3(0,0,0));
    }
    // update (dt) {}
}

 12.6小车的运动Cocos Creator游戏开发教程 学习笔记_第330张图片

 Cocos Creator游戏开发教程 学习笔记_第331张图片

新建并添加脚本CarScript.ts到小车节点。

 Cocos Creator游戏开发教程 学习笔记_第332张图片

CarScript.ts 的代码:

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {
    //每次刷新小车移动的距离
    @property
    speed :number = 3;
    //小车移动的方向
    @property
    direction : cc.Vec2 = null;
    // LIFE-CYCLE CALLBACKS:
    onLoad () {
        // 小车的初始方向测试 this.direction = cc.v2(1,0);
    }
    start () {}
    update (dt) {
        //静止
        if(this.direction == null){return;}
        // speed 步长
        // direction 方向
        let dx = this.speed * this.direction.x;
        let dy = this.speed * this.direction.y;
        let pos = this.node.getPosition();
        pos.x += dx;
        pos.y += dy;
        this.node.setPosition(pos);
    }
}

Cocos Creator游戏开发教程 学习笔记_第333张图片

 GamePad.ts 的代码:

Cocos Creator游戏开发教程 学习笔记_第334张图片

Cocos Creator游戏开发教程 学习笔记_第335张图片

 红色下划线没关系。

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    //目标小车  节点
    car : cc.Node = null;
    //控制小车的脚本
    carScript : cc.Component = null; 
    onLoad(){
        this.car = cc.find('Canvas/小车');
        //获取 控制小车的脚本
        this.carScript = this.car.getComponent('CarScript');
    }

    start () {
        this.node.on('touchstart',this.onTouchStart,this);
        this.node.on('touchmove',this.onTouchMove,this);
        this.node.on('touchend',this.onTouchCancel,this);
        this.node.on('touchcancel',this.onTouchCancel,this);
    }
    onTouchStart( e : cc.Event.EventTouch ){}//暂时没有用到,置空
    //计算触摸点的当前位置,把手柄的位置移动到触摸点所在的位置
    onTouchMove( e : cc.Event.EventTouch ){
        
        //e.getLocation()为触摸点的位置,是世界坐标
        //1.需要把世界坐标转换为本地坐标
             cc.log("世界坐标touch move : x=" + e.getLocationX() + ",y=" +e.getLocationY());
        let parent : cc.Node = this.node.parent;//父节点(圆形底盘)
        //e.getLocation() 获得触摸点的世界坐标(触点位置)
        //把触摸点的世界坐标转换为父节点(圆形底盘)的本地坐标 ,pos代表触摸点的本地坐标
        let pos : cc.Vec2 = parent.convertToNodeSpaceAR(e.getLocation());
        
        // 触摸点所在的方位(cos,sin)
        let direction : cc.Vec2 = pos.normalize();
            cc.log("方位 : cos=" + direction.x + ", sin=" + direction.y);

        //2.限制手柄在“圆形底盘”的边界之内
        //最大距离圆形底盘的半径R=100,手柄的半径r=40;maxD=R-r=60;
        let maxD = 100 * 0.6; 
        //“触摸点”和“手柄圆心”两点之间的实际距离△d(在二维空间中的欧氏距离就是两点之间的直线段距离)
        let d: number = cc.Vec2.distance( pos , cc.v2(0,0) );
            cc.log("欧氏距离 :△d=" + d);
        if( d > maxD ){
            pos.x = maxD * direction.x;//d * cos
            pos.y = maxD * direction.y;//d * sin
        }
        //根据pos触摸点的本地坐标,使用setPosition()设置手柄在父节点的本地坐标
        this.node.setPosition(pos);
            cc.log("转换成本地坐标convert to local: x=" +  pos.x + ",y=" + pos.y); 

        //3.操纵目标小车
        //  radian = a.angle(b) 求a,b两个向量的夹角
        //  其中 cc.v2(1,0) 表示x轴方向的单位向量
        let radian = pos.signAngle(cc.v2(1,0)); //弧度值
        let angle = radian / Math.PI * 180; //把弧度制转换成角度值
        this.car.angle = -angle; // 按API要求,angle是按逆时针为正的
        // this.car.rotation = angle; //这样写也行,但是不如 this.car.angle = -angle;
        
        //把触摸点所在的方位(cos,sin) 赋值给小车的方位
        this.carScript.direction = direction;

    }
    onTouchCancel( e : cc.Event.EventTouch ){
        //触摸松开的时候,把手柄的位置移动到父节点(圆形底盘)的中央
        this.node.setPosition( cc.v3(0,0,0));

        // 松开手柄 小车停止
        this.carScript.direction = null;
    }
    // update (dt) {}
}

13.1GIF图的显示Cocos Creator游戏开发教程 学习笔记_第336张图片

Cocos Creator游戏开发教程 学习笔记_第337张图片

 13.2准备GIF素材Cocos Creator游戏开发教程 学习笔记_第338张图片

 Cocos Creator游戏开发教程 学习笔记_第339张图片

在PS中打开就能看到这些图片。

Cocos Creator游戏开发教程 学习笔记_第340张图片

Cocos Creator游戏开发教程 学习笔记_第341张图片

GIF提取教程:1.每次只显示一张,然后另存为png图片。Cocos Creator游戏开发教程 学习笔记_第342张图片

 Cocos Creator游戏开发教程 学习笔记_第343张图片

2.把这0~11的12张图片加入到项目中。

 Cocos Creator游戏开发教程 学习笔记_第344张图片自动剪裁红色框内容大小是不一样的。

 3.选中图片,然后把属性检查器中的Sprite中的Trim Type(裁剪类型)属性设置为None,然后点击应用。每一张图片都要设置。(因为每一张图片自动裁剪的大小不一样,使用不是方便。)

Cocos Creator游戏开发教程 学习笔记_第345张图片

 13.3GIfPlayerCocos Creator游戏开发教程 学习笔记_第346张图片

 Cocos Creator游戏开发教程 学习笔记_第347张图片

1.新建图片节点

Cocos Creator游戏开发教程 学习笔记_第348张图片

给节点添加默认显示的图片帧,例如第一张图片0。

Cocos Creator游戏开发教程 学习笔记_第349张图片

 2.添加一个脚本GifPlayer.ts,挂在这个图片节点上。

Cocos Creator游戏开发教程 学习笔记_第350张图片

 Cocos Creator游戏开发教程 学习笔记_第351张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {
    @property( [cc.SpriteFrame] )
    frames : cc.SpriteFrame[] = [];//数组

    sprite : cc.Sprite = null; //Sprite组件
    index : number = 0; //当前显示第n张图片
    interval : number = 0.1; //定时器的间隔
    // LIFE-CYCLE CALLBACKS:
    onLoad () {
        this.sprite = this.getComponent(cc.Sprite);
    }

    start () {
        this.schedule(this.onTimer,this.interval);
    }
    onTimer(){
        if(this.frames.length ==0){return;}

        this.sprite.spriteFrame = this.frames[this.index];
        //下一帧
        this.index ++;
        if(this.index >= this.frames.length){
            this.index = 0;
        }
    }
    onDestroy(){
        this.unschedule(this.onTimer);
    }

    // update (dt) {}
}

在Frames中输入12点击回车,就会出现下列数组,就可以逐一添加图片啦。

Cocos Creator游戏开发教程 学习笔记_第352张图片Cocos Creator游戏开发教程 学习笔记_第353张图片

就可以了:

 Cocos Creator游戏开发教程 学习笔记_第354张图片

13.4图集AtlasCocos Creator游戏开发教程 学习笔记_第355张图片

 Cocos Creator游戏开发教程 学习笔记_第356张图片Cocos Creator游戏开发教程 学习笔记_第357张图片

Cocos Creator游戏开发教程 学习笔记_第358张图片

 图集资源 · Cocos Creator  https://docs.cocos.com/creator/manual/zh/asset/atlas.html

Cocos Creator游戏开发教程 学习笔记_第359张图片

Atlas的制作教程:

Cocos Creator游戏开发教程 学习笔记_第360张图片

 文档中写的这两个都是外国的收费软件。百度搜索,然后点击进入官网。

Cocos Creator游戏开发教程 学习笔记_第361张图片

 下载这个试用版:

Cocos Creator游戏开发教程 学习笔记_第362张图片

 Cocos Creator游戏开发教程 学习笔记_第363张图片

把所有图片一张张拖到中间这个小人的区域:

一般情况下 希望不要修剪,修剪模式改成“没有”(修剪的话合成的图片更小但是可能裁剪掉一些东西):

Cocos Creator游戏开发教程 学习笔记_第364张图片

 设置好之后,点击“发布精灵表”就可以得到.plist文件和.png文件

 

 

 Cocos Creator游戏开发教程 学习笔记_第365张图片在plist中代码描述,大图中的内容和每一张小图的位置和相关信息。

 Cocos Creator游戏开发教程 学习笔记_第366张图片Cocos Creator游戏开发教程 学习笔记_第367张图片

Cocos Creator游戏开发教程 学习笔记_第368张图片

可以在飞羽图集中看到那时12张图片。

Cocos Creator游戏开发教程 学习笔记_第369张图片

Cocos Creator游戏开发教程 学习笔记_第370张图片选中这些图片,然后把Trim Type选为None。

Cocos Creator游戏开发教程 学习笔记_第371张图片

 现在改成AtlasPlayer.ts,把GifPlayer.ts勾选掉。

代码:

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {
    @property( [cc.SpriteAtlas] )
    atlas : cc.SpriteAtlas = null;

    frames : cc.SpriteFrame[] = [];
    sprite : cc.Sprite = null; //Sprite组件
    index : number = 0; //当前显示第n张图片
    interval : number = 0.1; //定时器的间隔
    // LIFE-CYCLE CALLBACKS:
    onLoad () {
        this.sprite = this.getComponent(cc.Sprite);
        if(this.atlas != null){
            this.frames = this.atlas.getSpriteFrames();
        }
    }

    start () {
        this.schedule(this.onTimer,this.interval);
    }
    onTimer(){
        if(this.frames.length ==0){return;}

        this.sprite.spriteFrame = this.frames[this.index];
        //下一帧
        this.index ++;
        if(this.index >= this.frames.length){
            this.index = 0;
        }
    }
    onDestroy(){
        this.unschedule(this.onTimer);
    }

    // update (dt) {}
   
}

Cocos Creator游戏开发教程 学习笔记_第372张图片

14.1动态加载资源(一次加载一个资源)

 Cocos Creator游戏开发教程 学习笔记_第373张图片

1.静态加载资源:节点引用图片资源(在Sprite中的SpriteFrame引用飞机这个图片)。

 Cocos Creator游戏开发教程 学习笔记_第374张图片

Cocos Creator游戏开发教程 学习笔记_第375张图片

2.动态加载:在脚本中使用cc.resources.load() 加载资源。

把脚本Demo1.ts挂到“图片”节点上。实现点击图片飞机后,出现图片汽车。

Cocos Creator游戏开发教程 学习笔记_第376张图片Cocos Creator游戏开发教程 学习笔记_第377张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    onLoad () {
        this.node.on('touchstart', this.onClicked, this);
    }

    start () {

    }

    onClicked(){
        let self = this;
        
        cc.resources.load("icon/汽车", cc.SpriteFrame, function (err, assets ) {
            // if(err) { cc.log(err); return }
            
            self.node.getComponent(cc.Sprite).spriteFrame =  assets;
        });
    }
    
    // update (dt) {}
}

《 图文教程》

cc.resources.load() 加载资源

示例:

    onClicked(){

        let self = this;    // 这是JS中的闭包语法

        cc.resources.load("icon/汽车", cc.SpriteFrame, function (err, assets) {

            self.node.getComponent(cc.Sprite).spriteFrame = assets;

        });

}

其中,方法的原型:

cc.resources.load( path, type, onComplete)

第1个参数:  path 表示要加载的资源的路径。

例如,icon/汽车 指的是 assets/resources/icon/汽车。

(*) 待加载的资源必须放在resources目录下。

(*) 路径不能加后缀名。

第2个参数:type 指定资源对象类型,可以省略。例如:cc.SpriteFrame , cc.AudioClip

第3个参数:onComplete指定回调方法,当资源加载完毕时调用。

function( err, assets ) {

}

方法含两个参数(err错误原因,assets资源对象)

若err == null ,表示资源加载成功,assets即为加载得到的资源对象。

若err!=null ,表示资源加载出错,err即为出错的原因。

相关语法说明:

(1) 闭包

在回调中无法直接调用this,所以先定义一个 self = this ,以便在回调中调用

    let self = this; 

    cc.resources.load("icon/汽车", cc.SpriteFrame, function (err, assets) {

        self.node.getComponent(cc.Sprite).spriteFrame = assets;

});

(2) 类型转换

assets是cc.Asset类型,使用类型转换 (左边是类型,右边是类型):

self.node.getComponent(cc.Sprite).spriteFrame = assets;

 在官方文档中,也可以找到资源加载介绍:

获取和加载资源 · Cocos Creator  https://docs.cocos.com/creator/manual/zh/scripting/load-assets.html?h=%E8%8E%B7%E5%8F%96%E5%92%8C

Cocos Creator游戏开发教程 学习笔记_第378张图片

 动态加载 · Cocos Creator  https://docs.cocos.com/creator/manual/zh/asset/dynamic-load-resources.html

14.2一次加载多个资源Cocos Creator游戏开发教程 学习笔记_第379张图片

Cocos Creator游戏开发教程 学习笔记_第380张图片

1.指定多个资源路径

cc.resources.load(paths,callback(err,assets){ ... })

其中,paths类型[cc.String](路径),assets类型[cc.Assets](数组),

我们可以使用paths指定一个路径或者一个路径的数组。如果我们指定一个路径的数组,那么在回调方法callback(err,assets){ ... }中就会传回一个assets数组。

Cocos Creator游戏开发教程 学习笔记_第381张图片

 2.指定一个资源目录

cc.resources.loadDir(path,callback(err,assets){ ... })

其中,loadDir(文件管理器),path是一个文件夹路径,assets是[cc.Asset]。

Cocos Creator游戏开发教程 学习笔记_第382张图片

 

Cocos Creator游戏开发教程 学习笔记_第383张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {
    frames : cc.SpriteFrame[] = new Array(); //数组帧 
    sprite : cc.Sprite = null; //Script组件
    index : number = 0; //当前显示第N张图片
    interval : number = 0.1; //定时器的间隔秒数

    flag : number = 0; //判断是正数(1)还是倒数(-1)图片

    onLoad () {
        this.sprite = this.getComponent(cc.Sprite);
        // 动态加载一个目录下的所有资源
        let self = this;
        cc.resources.loadDir("飞羽gif/",cc.SpriteFrame, function(err,assets:[cc.SpriteFrame]){
            self.frames = assets;
        });
    }
    start () {
        //schedule(callback: Function, interval?: number, repeat?: number, delay?: number): void;		
        //调度一个只运行一次的回调函数,可以指定 0 让回调函数在下一帧立即执行或者在一定的延时之后执行。
        this.schedule(this.onTimer , this.interval);//时间表:onTimer,每隔0.1秒显示。
    }
    onTimer(){
        if(this.frames.length == 0){
            return;
        }else{//居然识别不了 else if !!!!!只能用if了。
            this.sprite.spriteFrame = this.frames[this.index];
            cc.log("this.index="+this.index +"; this.flag="+this.flag);
            if(this.flag == 1 || this.index == 0){//从第一张图片开始正数显示(因为在cocos中添加的默认是第一张this.frames[0])
                this.index ++;//下一帧
                this.flag = 1;
            }
            if(this.flag == -1){
                this.index --;//下一帧
                this.flag = -1;
            }
            if(this.index >= this.frames.length){//循环到最后一张
                this.index = this.frames.length-2; //从最后一张图片开始倒数显示this.frames[11]
                this.flag = -1;
            }
            
        }
        
    }
    // update (dt) {}
    onDestroy(){
        this.unschedule(this.onTimer);
    }
}

Cocos Creator游戏开发教程 学习笔记_第384张图片

 Cocos Creator游戏开发教程 学习笔记_第385张图片

居然识别不了else if!!!!!只能用if!!!

看来需要学一学TypeScript的语法。

变量声明 - TypeScript 中文手册  https://typescript.bootcss.com/variable-declarations.html

15.1触摸事件Cocos Creator游戏开发教程 学习笔记_第386张图片

 Cocos Creator游戏开发教程 学习笔记_第387张图片

 Cocos Creator游戏开发教程 学习笔记_第388张图片节点事件系统 · Cocos Creator  https://docs.cocos.com/creator/manual/zh/engine/event/event-node.htmlCocos Creator游戏开发教程 学习笔记_第389张图片

 事件 API · Cocos Creator  https://docs.cocos.com/creator/manual/zh/engine/event/event-api.html

Cocos Creator游戏开发教程 学习笔记_第390张图片

Cocos Creator游戏开发教程 学习笔记_第391张图片

Cocos Creator游戏开发教程 学习笔记_第392张图片

 15.2事件冒泡机制Cocos Creator游戏开发教程 学习笔记_第393张图片

 Cocos Creator游戏开发教程 学习笔记_第394张图片Cocos Creator游戏开发教程 学习笔记_第395张图片

 只点击“汽车”或者“停车标志”会上浮到父节点“道路”:日志打印了被点击的子节点和上浮到的父节点。

Cocos Creator游戏开发教程 学习笔记_第396张图片

 Cocos Creator游戏开发教程 学习笔记_第397张图片

 加上 e.stopPropagation();(停止传递当前事件。)就不会上浮到父节点“道路”。而是只打印子节点汽车。Cocos Creator游戏开发教程 学习笔记_第398张图片

 onLoad () {
       this.node.on('touchstart',this.onTouch,this);
    }
    start () {}
    onTouch(e: cc.Event.EventTouch){
        cc.log('汽车 onTouch(): ');
        // e.stopPropagation();
        // (method) cc.Event.stopPropagation(): void
        // !#en Stops propagation for current event. !#zh 停止传递当前事件。
    }

Cocos Creator游戏开发教程 学习笔记_第399张图片

 Cocos Creator游戏开发教程 学习笔记_第400张图片

 15.3(练习)遮罩效果Cocos Creator游戏开发教程 学习笔记_第401张图片

 Cocos Creator游戏开发教程 学习笔记_第402张图片

Cocos Creator游戏开发教程 学习笔记_第403张图片

Cocos Creator游戏开发教程 学习笔记_第404张图片

 把脚本附加给遮罩这个节点。

Cocos Creator游戏开发教程 学习笔记_第405张图片

 onLoad () {
        this.node.on('touchstart', this.onTouch, this);
    }
    start () {}
    onTouch( e : cc.Event.EventTouch){
        //设置节点状态处于非激活的状态。
        this.node.active = false;
        // e.stopPropagation();
    }
    // update (dt) {}

 可以发现:只有点击“灰色区域”才能使得遮罩处于非激活状态,即去掉遮罩。而点击“游戏主画面”背景图是没有用的。

Cocos Creator游戏开发教程 学习笔记_第406张图片Cocos Creator游戏开发教程 学习笔记_第407张图片

 Cocos Creator游戏开发教程 学习笔记_第408张图片

使用Widget组件进行优化,使得遮罩自适应屏幕,且和父节点(Canvas)同样大小遮满屏幕。把上下左右边距全部调成0px。

 Cocos Creator游戏开发教程 学习笔记_第409张图片

 Cocos Creator游戏开发教程 学习笔记_第410张图片Cocos Creator游戏开发教程 学习笔记_第411张图片

可以发现,调整之后:场景编辑器中的遮罩范围自动适应了整个相机大小。且运行后效果也是满屏遮罩。

 15.4(练习)模态提示框

 Cocos Creator游戏开发教程 学习笔记_第412张图片

 设置提示框大小和Canvas同等大小960x640。Cocos Creator游戏开发教程 学习笔记_第413张图片

 在提示框下面添加单色节点“遮罩层”,设置不透明度Opacity、大小Size和自适应边距Widget。Cocos Creator游戏开发教程 学习笔记_第414张图片

添加按钮节点,并让他们对齐:

Cocos Creator游戏开发教程 学习笔记_第415张图片

 然后添加脚本:

下一关按钮:

Cocos Creator游戏开发教程 学习笔记_第416张图片

 再玩一遍按钮:

Cocos Creator游戏开发教程 学习笔记_第417张图片

 代码是一样的:

@ccclass
export default class NewClass extends cc.Component {
    onLoad () {
        this.node.on('touchstart', this.onTouch, this);
    }
    start () {}
    onTouch( e ){
        // 隐藏对话框   
        let node : cc.Node = cc.find('Canvas/提示框');
        node.active = false;
        // 下面的代码省略,仅为模拟操作
    }
    // update (dt) {}
}

 我们可以先把提示框隐藏掉,然后多加一个按钮“结束”。把脚本附加到结束按钮中。

@ccclass
export default class NewClass extends cc.Component {
    onLoad () {
        this.node.on('touchstart', this.onTouch, this);
    }
    start () {}
    onTouch( e ){
        // 显示对话框
        let node : cc.Node = cc.find('Canvas/提示框');
        node.active = true;
    }
}

 效果:Cocos Creator游戏开发教程 学习笔记_第418张图片

15.5组件Block Input EventsCocos Creator游戏开发教程 学习笔记_第419张图片

用于实现遮罩层出现之后,使得遮罩层后面的内容不能再被点击。这个阻止输入事件BlockInputEvents的按钮加在遮罩层上:

Cocos Creator游戏开发教程 学习笔记_第420张图片Cocos Creator游戏开发教程 学习笔记_第421张图片Cocos Creator游戏开发教程 学习笔记_第422张图片

 Cocos Creator游戏开发教程 学习笔记_第423张图片

(提示框中)点击遮罩层上的按钮“再玩一局”的代码(结束对话框EndDialogBox.ts添加在提示框这个父结点上,结束整个遮罩层生显示的内容),使得遮罩层的状态为未激活false:

Cocos Creator游戏开发教程 学习笔记_第424张图片

@ccclass
export default class NewClass extends cc.Component {
    onLoad () {
        let replayButton : cc.Node = cc.find('再玩一局', this.node);
        replayButton.on('touchstart', this.onReplay, this);
    }
    start () {}
    onReplay(){//当前节点的自身激活状态。
        this.node.active = false;
    }
    // update (dt) {}
}

游戏主画面上兔子随鼠标可以被拖动到鼠标移动停止的位置(Rabbit.ts代码):

Cocos Creator游戏开发教程 学习笔记_第425张图片


@ccclass
export default class Rabbit extends cc.Component {
    startPoint : cc.Vec2 = null; // 开始的触摸点
    startNodePos : cc.Vec2 = null; // 节点的初始位置
    num : number = 1; //推断一次运行游戏的移动过程中,调用计算了多少次TouchMove
    onLoad () {
        this.num=0;//移动一次清零一次。
        this.node.on('touchstart', this.onTouchStart, this);
        this.node.on('touchmove', this.onTouchMove, this);
    }
    start () {}
    onTouchStart( e : cc.Event.EventTouch){
//Path: Canvas/游戏主画面/兔子, UUID: 2fGs7432NHZ5nIZXxcf1qr
        //1.把初始点(只需获取)和触点(世界坐标需要转换)都转换成父节点(游戏主画面)空间坐标系的位置
        this.startNodePos = this.node.getPosition();//获取初始点的节点在父节点坐标系中的位置(x, y, z)
        cc.log("startNodePos"+ this.startNodePos);
            // 转换到父节点的本地坐标{.convertToNodeSpaceAR(将(e.getLocation()触点位置)转换到节点 (局部父节点) 空间坐标系。)}
        this.startPoint = this.node.parent.convertToNodeSpaceAR(e.getLocation());
        cc.log("e.getLocation()"+ e.getLocation());
    }
    onTouchMove( e: cc.Event.EventTouch){
        //把移动的终点endPoint转换到父节点的本地坐标    
        let endPoint : cc.Vec2 = this.node.parent.convertToNodeSpaceAR(e.getLocation()); 
        cc.log("endPoint"+ endPoint);
        cc.log("startPoint"+ this.startPoint);
        // 两个向量可以直接加减
        // 加法: result = a.add(b)
        // 减法:result = a.sub(b)        
        //移动的终点endPoint坐标减去初始点startPoint坐标 = 两点之间的间距distance
        let distance : cc.Vec2 =  endPoint.sub( this.startPoint);
        cc.log("distance=endPoint-startPoint="+ distance);
        let pos = this.startNodePos.add( distance);//初始节点加上间距distance得到节点在父节点坐标系的具体位置数值

        this.node.setPosition( pos );
        cc.log("pos=startNodePos+distance="+ pos);  
        
        cc.log("num"+this.num);
        this.num ++;
    }
    
}

Cocos Creator游戏开发教程 学习笔记_第426张图片

Cocos Creator游戏开发教程 学习笔记_第427张图片

点击“结束按钮”触发遮罩层的代码,使得对话框的状态为true激活状态:

@ccclass
export default class NewClass extends cc.Component {
    onLoad () {
        this.node.on('touchstart', this.onTouch, this);
    }
    start () {}
    onTouch(){//Tooltip 提示框; dialog 对话、会话、对话框
        let dialogNode : cc.Node = cc.find('Canvas/提示框');
        dialogNode.active = true;
    }
    // update (dt) {}
}

 Cocos Creator游戏开发教程 学习笔记_第428张图片

 还可以自己写一个脚本,使得遮罩层出现后,遮罩层后面的内容不能被操作。其他内容不变,只修改这里就可以了。

Cocos Creator游戏开发教程 学习笔记_第429张图片

// 提示:
// 可以自己写一个脚本组件,也可以直接使用系统自带的 BlockInputEvents 组件
@ccclass
export default class StopInputEvent extends cc.Component {
    onLoad(){
        this.node.on('touchstart', this.stopEvents, this);
        this.node.on('touchmove', this.stopEvents, this);
        this.node.on('touchend', this.stopEvents, this);
        this.node.on('touchcancel', this.stopEvents, this);
    }
    stopEvents( e : cc.Event){
        e.stopPropagation();
    }
}

Cocos Creator游戏开发教程 学习笔记_第430张图片

16.1小游戏:子弹发射效果Cocos Creator游戏开发教程 学习笔记_第431张图片

Cocos Creator游戏开发教程 学习笔记_第432张图片Cocos Creator游戏开发教程 学习笔记_第433张图片

 16.2布置场景Cocos Creator游戏开发教程 学习笔记_第434张图片

 Cocos Creator游戏开发教程 学习笔记_第435张图片Cocos Creator游戏开发教程 学习笔记_第436张图片

添加单色背景:画布Canvas》创建节点》创建渲染节点》Sprite单色,设置:颜色color淡蓝色,背景大小960X640(和我们的画布Canvas分辨率相同。),还要添加UI组件Widget,使得背景自适应屏幕画布。

Cocos Creator游戏开发教程 学习笔记_第437张图片Cocos Creator游戏开发教程 学习笔记_第438张图片

添加炮塔节点:直接拖动图片拖上来。然后调整一下大小就可以了。

 Cocos Creator游戏开发教程 学习笔记_第439张图片

 子弹需要动态创建,所以不需要创建。

16.3动态创建节点Cocos Creator游戏开发教程 学习笔记_第440张图片

 

 Cocos Creator游戏开发教程 学习笔记_第441张图片

 Cocos Creator游戏开发教程 学习笔记_第442张图片Cocos Creator游戏开发教程 学习笔记_第443张图片

创建脚本 CannonSprite.ts,加进节点“炮塔”中,然后把子弹图片添加进“Bullet Icon”子弹图标属性中。点击炮塔之后,子弹出现的效果如下图:

@ccclass
export default class NewClass extends cc.Component {
    //添加新属性,把子弹图片添加去。
    @property(cc.SpriteFrame)
    bulletIcon : cc.SpriteFrame = null;  //子弹Icon

    onLoad () {//点击炮塔
        this.node.on('touchstart',this.onTouch,this);
    }
    start () {}
    onTouch(){
        this.fire();
    }
    fire(){
        if(this.bulletIcon==null){
            cc.log('请设置bulletIcon图片');
            return;
        }
        //动态创建一个Node(节点作为子弹的节点),添加Sprite组件()
        let bullet : cc.Node = new cc.Node();
        let sprite : cc.Sprite = bullet.addComponent(cc.Sprite);
        //把图片添加到Sprite组件的spriteFrame图片帧中
        sprite.spriteFrame = this.bulletIcon;
        bullet.parent = this.node;//把这个动态创建的子弹节点作为子节点,挂到大炮下面
        bullet.setPosition(cc.v3(0,65,0));//设置初始位置

    }

    // update (dt) {}
}

Cocos Creator游戏开发教程 学习笔记_第444张图片Cocos Creator游戏开发教程 学习笔记_第445张图片Cocos Creator游戏开发教程 学习笔记_第446张图片

 16.4附加脚本组件Cocos Creator游戏开发教程 学习笔记_第447张图片

Cocos Creator游戏开发教程 学习笔记_第448张图片

 先创建一个脚本BulletScript.ts(只创建,不用挂到节点上。最后从CannonScript.ts引入即可。),并且规范化类名class写成BulletScript。

@ccclass
export default class BulletScript extends cc.Component {
    onLoad () {
        this.schedule(this.onTimer,0.016);
    }
    start () {}
    onTimer(){
        if(this.node.y>300){//子弹最多飞300px,(超过300px则)
            this.unschedule(this.onTimer);//停止定时器
            this.node.destroy();//销毁节点,使子弹消失。
            return;
        }
        this.node.y += 10;//每0.016s移动10px。
    }
}

然后在CannonScript.ts中也要修改类名:

 然后加挂一个脚本组件,并点击“快速修复”,自动得到import地址。

Cocos Creator游戏开发教程 学习笔记_第449张图片Cocos Creator游戏开发教程 学习笔记_第450张图片

 效果:点击加农炮之后子弹会一直向上飞,然后到y=300停止并消失。


import BulletScript from "./BulletScript";

const {ccclass, property} = cc._decorator;

@ccclass
export default class CannonScript extends cc.Component {
    //添加新属性,把子弹图片添加去。
    @property(cc.SpriteFrame)
    bulletIcon : cc.SpriteFrame = null;  //子弹Icon

    onLoad () {//点击炮塔
        this.node.on('touchstart',this.onTouch,this);
    }
    start () {}
    onTouch(){
        this.fire();
    }
    fire(){
        if(this.bulletIcon==null){
            cc.log('请设置bulletIcon图片');
            return;
        }
        //动态创建一个Node(节点作为子弹的节点),添加Sprite组件()
        let bullet : cc.Node = new cc.Node();
        let sprite : cc.Sprite = bullet.addComponent(cc.Sprite);
        //把图片添加到Sprite组件的spriteFrame图片帧中
        sprite.spriteFrame = this.bulletIcon;
        bullet.parent = this.node;//把这个动态创建的子弹节点作为子节点,挂到大炮下面
        bullet.setPosition(cc.v3(0,65,0));//设置初始位置
        //加挂一个脚本组件
        let script = bullet.addComponent(BulletScript);

    }

    // update (dt) {}
}

16.5爆炸效果Cocos Creator游戏开发教程 学习笔记_第451张图片

Cocos Creator游戏开发教程 学习笔记_第452张图片

Cocos Creator游戏开发教程 学习笔记_第453张图片

 打开BulletScript.ts脚本,

Cocos Creator游戏开发教程 学习笔记_第454张图片

  


const {ccclass, property} = cc._decorator;

@ccclass
export default class BulletScript extends cc.Component {
    //添加属性爆炸效果 图片帧
    @property(cc.SpriteFrame)
    explodeEffect : cc.SpriteFrame = null;

    onLoad () {
        this.schedule(this.onTimer,0.016);
    }
    start () {}
    onTimer(){
        if(this.node.y>300){//子弹最多飞300px,(超过300px则)
            this.unschedule(this.onTimer);//停止定时器
            //this.node.destroy();//销毁节点,使子弹消失。
            this.beginExplode();//开始执行爆炸效果
            return;
        }
        this.node.y += 10;//每0.016s移动10px。
    }
    beginExplode(){
        //XX.getComponent获取节点上指定类型的组件(例如:cc.Sprite),如果节点有附加指定类型的组件,则返回,如果没有则为空。 传入参数也可以是脚本的名称。
        let sprite : cc.Sprite = this.node.getComponent(cc.Sprite);
        sprite.spriteFrame = this.explodeEffect;//显示爆炸图片
        this.node.scale =0.1;//初始的爆炸图片 缩放为0.1倍(默认是1倍。)
        //透明度的初始值。默认就是255。不用设置。
        let self = this;//使用闭包语法
        //使用缓动系统tween。在0.5s时间内把爆炸图片放大到0.5倍,然后透明度逐渐变淡到0。
        cc.tween(this.node).to(0.5,{scale:0.5,opacity:0})
                           .call(function(){self.afterExplode();})
                           .start();
    }
    afterExplode() {
        this.node.destroy();//销毁这个节点,使子弹消失。
    }
}

10.3中学习了缓动系统:(to(时间0.5s,最终值:缩放0.5,透明度为0):对属性进行绝对值计算,传入最终值;by是变化值);

14.1中用到了“闭包”:在回调中无法直接调用this,所以先定义一个 self = this ,以便在回调中调用。

打开CannonScript.ts脚本,添加新属性爆炸效果,把图片加进去。

Cocos Creator游戏开发教程 学习笔记_第455张图片Cocos Creator游戏开发教程 学习笔记_第456张图片Cocos Creator游戏开发教程 学习笔记_第457张图片

 Cocos Creator游戏开发教程 学习笔记_第458张图片


import BulletScript from "./BulletScript";



const {ccclass, property} = cc._decorator;

@ccclass
export default class CannonScript extends cc.Component {
    //添加新属性,把子弹图片添加去。
    @property(cc.SpriteFrame)
    bulletIcon : cc.SpriteFrame = null;  //子弹Icon

    //添加新属性,把爆炸图片添加去。
    @property(cc.SpriteFrame)
    explodeEffect : cc.SpriteFrame = null;  //子弹Icon

    onLoad () {//点击炮塔
        this.node.on('touchstart',this.onTouch,this);
    }
    start () {}
    onTouch(){
        this.fire();
    }
    fire(){
        if(this.bulletIcon==null){
            cc.log('请设置bulletIcon图片');
            return;
        }
        //动态创建一个Node(节点作为子弹的节点),添加Sprite组件()
        let bullet : cc.Node = new cc.Node();
        let sprite : cc.Sprite = bullet.addComponent(cc.Sprite);
        //把图片添加到Sprite组件的spriteFrame图片帧中
        sprite.spriteFrame = this.bulletIcon;
        bullet.parent = this.node;//把这个动态创建的子弹节点作为子节点,挂到大炮下面
        bullet.setPosition(cc.v3(0,65,0));//设置初始位置
        
        //加挂一个脚本组件“子弹脚本”script->(BulletScript)
        let script : BulletScript = bullet.addComponent(BulletScript);
        //把爆炸效果图片交给“子弹脚本”script
        script.explodeEffect = this.explodeEffect;
    }

    // update (dt) {}
}

 效果:

Cocos Creator游戏开发教程 学习笔记_第459张图片

17.1(综合)雪地射击小游戏

Cocos Creator游戏开发教程 学习笔记_第460张图片

 会移动的靶标,加农炮的炮口会随着鼠标的方向转动,点击出现射击的子弹。射中的时候出现爆炸的效果,没射中就只是出现子弹射出。一共有10发子弹。

Cocos Creator游戏开发教程 学习笔记_第461张图片

17.2添加场景Cocos Creator游戏开发教程 学习笔记_第462张图片

 

先把需要的材料加入资源管理器。然后把“雪地背景”、“靶子”拖动上去到Canvas下面作为节点。适当调整这两个图片的大小(“雪地背景”:960X240px,加:UI组件->widget。或者只是调整大小到覆盖整个Main Camera。)。新建一个空节点,命名为射击系统。然后把半圆和炮塔都拖动到这个节点下方。

Cocos Creator游戏开发教程 学习笔记_第463张图片Cocos Creator游戏开发教程 学习笔记_第464张图片大致位置在中间(x=500),然后把加农炮的基准点调整到中心(使用矩形变换工具或者调整Anchor数值)。

Cocos Creator游戏开发教程 学习笔记_第465张图片

 效果如下图所示:

Cocos Creator游戏开发教程 学习笔记_第466张图片

17.3炮口的旋转

Cocos Creator游戏开发教程 学习笔记_第467张图片Cocos Creator游戏开发教程 学习笔记_第468张图片

新建Cannon.ts,添加到炮塔的下面。弧度值:c在b的右侧,在顺时针方向,所以c.signAngle(b)=π/4,为正;a在b的左侧,在逆时针方向,所以a.signAngle(b)=-π/4,为负。

Cocos Creator游戏开发教程 学习笔记_第469张图片Cocos Creator游戏开发教程 学习笔记_第470张图片

Cocos Creator游戏开发教程 学习笔记_第471张图片

Cannon.ts的代码:

const {ccclass, property} = cc._decorator;

@ccclass
export default class Cannon extends cc.Component {
    //内部属性
    startPos : cc.Vec2 = null;
    startAngle : number = null;//炮口的角度
    // LIFE-CYCLE CALLBACKS:
    onLoad () {
        this.node.angle = 90; // 初始值设置为90度
        this.node.on('touchstart',this.onTouchStart,this);
        this.node.on('touchmove',this.onTouchMove,this);
        this.node.on('touchend',this.onTouchEnd,this);
        this.node.on('touchcancle',this.onTouchCancle,this);
    }
    start () {}
    // update (dt) {}
    onTouchStart(e:cc.Event.EventTouch) {
        // startPos :触点开始的位置 (将一个点转换到节点 (局部:父节点) 空间坐标系。)
        this.startPos = this.node.parent.convertToNodeSpaceAR(e.getLocation());
        // startAngle:炮口的初始角度(x轴方向为0度)
        this.startAngle = this.node.angle;
    }
    onTouchMove(e:cc.Event.EventTouch) {
        // 触点的当前位置
        let pos = this.node.parent.convertToNodeSpaceAR(e.getLocation());
        //摆动的角度,a.signAngle(b)即a向量与b向量之间的夹角。
        let sweep_radian = pos.signAngle(this.startPos);//弧度radian值,例如π/4
        let sweep_angle = 180 * (sweep_radian / Math.PI); //弧度radian值 转化成 角度angle值
        /*炮口的新指向:
            比如,原来炮口90度,向右摆动15度,则炮口应该指向90-15=75度;
            比如,原来炮口90度,向左摆动15度,则炮口应该指向90-(-15)=105度; 
        */
        let angle = this.startAngle - sweep_angle;//炮口的新角度
        // 炮口角度限制在45~135度之间
        if(angle < 45){
            angle = 45;
        }
        if(angle > 135){
            angle = 135;
        }
        cc.log("炮口摆动:" + sweep_angle+ ",修正后的角度:" +angle);
        this.node.angle = angle;
   }
    onTouchEnd(e:cc.Event.EventTouch) {}
    onTouchCancle(e:cc.Event.EventTouch) {}   
}

Cocos Creator游戏开发教程 学习笔记_第472张图片

17.4发射子弹Cocos Creator游戏开发教程 学习笔记_第473张图片

 

 在Cannon.ts中添加代码:

添加子弹Icon属性,并给他赋值为 子弹图片。

Cocos Creator游戏开发教程 学习笔记_第474张图片

 鼠标松开,开火出现子弹。

const {ccclass, property} = cc._decorator;

@ccclass
export default class Cannon extends cc.Component {
    //内部属性
    startPos : cc.Vec2 = null;
    startAngle : number = null;//炮口的角度
    //添加子弹Icon
    @property(cc.SpriteFrame)
    bulletIcon: cc.SpriteFrame = null;
    // LIFE-CYCLE CALLBACKS:
    onLoad () {
        this.node.angle = 90; // 初始值设置为90度
        this.node.on('touchstart',this.onTouchStart,this);
        this.node.on('touchmove',this.onTouchMove,this);
        this.node.on('touchend',this.onTouchEnd,this);
        this.node.on('touchcancle',this.onTouchCancle,this);
    }
    start () {}
    // update (dt) {}
    onTouchStart(e:cc.Event.EventTouch) {
        // startPos :触点开始的位置 (将一个点转换到节点 (局部:父节点) 空间坐标系。)
        this.startPos = this.node.parent.convertToNodeSpaceAR(e.getLocation());
        // startAngle:炮口的初始角度(x轴方向为0度)
        this.startAngle = this.node.angle;
    }
    onTouchMove(e:cc.Event.EventTouch) {
        // 触点的当前位置
        let pos = this.node.parent.convertToNodeSpaceAR(e.getLocation());
        //摆动的角度,a.signAngle(b)即a向量与b向量之间的夹角。
        let sweep_radian = pos.signAngle(this.startPos);//弧度radian值,例如π/4
        let sweep_angle = 180 * sweep_radian / Math.PI; //弧度radian值 转化成 角度angle值
        /*炮口的新指向:
            比如,原来炮口90度,向右摆动15度,则炮口应该指向90-15=75度;
            比如,原来炮口90度,向左摆动15度,则炮口应该指向90-(-15)=105度; 
        */
        let angle = this.startAngle - sweep_angle;//炮口的新角度
        // 炮口角度限制在45~135度之间
        if(angle < 45){
            angle = 45;
        }
        if(angle > 135){
            angle = 135;
        }
        cc.log("炮口摆动:" + sweep_angle+ ",修正后的角度:" +angle);
        this.node.angle = angle;
   }
    onTouchEnd(e:cc.Event.EventTouch) {
        this.fire();//鼠标松开,开火
    }
    onTouchCancle(e:cc.Event.EventTouch) {}   
    //开火 发射子弹
    fire() {
        if(this.bulletIcon==null){
            cc.log("请设置bulletIcon图片");
            return;
        }
        //炮口的指向,应是子弹的运行方向
        let angle : number = this.node.angle;
        let radian = angle * Math.PI/180; //角度值 转换成 弧度值
        let direction = cc.v2(Math.cos(radian),Math.sin(radian));//标准化向量

        //动态创建一个Node,添加Sprite组件
        let bullet : cc.Node = new cc.Node(); //创建 子弹 节点
        let sprite : cc.Sprite = bullet.addComponent(cc.Sprite); // 创建 子弹节点的 精灵 组件
        sprite.spriteFrame = this.bulletIcon;//给精灵的精灵帧 赋值 子弹Icon
        bullet.parent = this.node.parent; //指定父节点是 炮塔的父节点->射击系统
        //子弹的角度及初始位置
        bullet.angle = this.node.angle;//子弹的角度 赋值成 炮口的角度
        let r = 110;//子弹与射击基准的距离
        let bullet_x = r * direction.x;
        let bullet_y= r * direction.y;
        bullet.setPosition(cc.v3(bullet_x,bullet_y));//子弹的初始位置

    }
}

 Cocos Creator游戏开发教程 学习笔记_第475张图片

出现这样偏移的问题,仔细想了想,估计是父节点的中心点和子节点的对不上。

Cocos Creator游戏开发教程 学习笔记_第476张图片

我修改了他们的位置,让他们的x,y轴重叠,且原点和父节点 射击系统 重叠。效果如下:

 Cocos Creator游戏开发教程 学习笔记_第477张图片

 还是不在中间。那么感觉需要让炮台的图像向左一些,让y轴在炮口中间,y=0.5。不断调整这两个值,然后保持Position(0,0)。终于,子弹在炮口中间了。

Cocos Creator游戏开发教程 学习笔记_第478张图片

 Cocos Creator游戏开发教程 学习笔记_第479张图片Cocos Creator游戏开发教程 学习笔记_第480张图片

微调一下r=140,简直正中间,完美。

 Cocos Creator游戏开发教程 学习笔记_第481张图片

17.5子弹的飞行

 Cocos Creator游戏开发教程 学习笔记_第482张图片

 Bullet.ts的代码:

const {ccclass, property} = cc._decorator;

@ccclass
export default class Bullet extends cc.Component {
    //飞行的方向(标准化向量)
    direction : cc.Vec2 = null;

    // LIFE-CYCLE CALLBACKS:
    onLoad () {}
    start () {
        this.schedule(this.onTimer,0.016);
    }
    // update (dt) {}
    onTimer() {
        //靶标与射击基准之间的距离400
        if(this.node.y > 400){
            this.dismiss();
            return;
        }
        let speed : number = 15; //步长
        let dx = speed * this.direction.x;
        let dy = speed * this.direction.y;
        this.node.x += dx;
        this.node.y += dy;
        
    }   
    dismiss() {
        this.node.destroy();
    }

}

修改Cannon.ts的代码:把bullet子弹节点改名为bulletNode。更精确,不影响下面的给子弹附加脚本组件的时候声明的let bullet。

Cocos Creator游戏开发教程 学习笔记_第483张图片

给节点bulletNode添加组件Bullet.ts需要手动导入。(记得给Bullet.ts改名

Cocos Creator游戏开发教程 学习笔记_第484张图片

 Cocos Creator游戏开发教程 学习笔记_第485张图片

声明一下bullet的类型为Bullet类型。

Cocos Creator游戏开发教程 学习笔记_第486张图片

 Cannon.ts的完整代码:

import Bullet from "./Bullet";

const {ccclass, property} = cc._decorator;

@ccclass
export default class Cannon extends cc.Component {
    //内部属性
    startPos : cc.Vec2 = null;
    startAngle : number = null;//炮口的角度
    //添加子弹Icon
    @property(cc.SpriteFrame)
    bulletIcon: cc.SpriteFrame = null;
    // LIFE-CYCLE CALLBACKS:
    onLoad () {
        this.node.angle = 90; // 初始值设置为90度
        this.node.on('touchstart',this.onTouchStart,this);
        this.node.on('touchmove',this.onTouchMove,this);
        this.node.on('touchend',this.onTouchEnd,this);
        this.node.on('touchcancle',this.onTouchCancle,this);
    }
    start () {}
    // update (dt) {}
    onTouchStart(e:cc.Event.EventTouch) {
        // startPos :触点开始的位置 (将一个点转换到节点 (局部:父节点) 空间坐标系。)
        this.startPos = this.node.parent.convertToNodeSpaceAR(e.getLocation());
        // startAngle:炮口的初始角度(x轴方向为0度)
        this.startAngle = this.node.angle;
    }
    onTouchMove(e:cc.Event.EventTouch) {
        // 触点的当前位置
        let pos = this.node.parent.convertToNodeSpaceAR(e.getLocation());
        //摆动的角度,a.signAngle(b)即a向量与b向量之间的夹角。
        let sweep_radian = pos.signAngle(this.startPos);//弧度radian值,例如π/4
        let sweep_angle = 180 * sweep_radian / Math.PI; //弧度radian值 转化成 角度angle值
        /*炮口的新指向:
            比如,原来炮口90度,向右摆动15度,则炮口应该指向90-15=75度;
            比如,原来炮口90度,向左摆动15度,则炮口应该指向90-(-15)=105度; 
        */
        let angle = this.startAngle - sweep_angle;//炮口的新角度
        // 炮口角度限制在45~135度之间
        if(angle < 45){
            angle = 45;
        }
        if(angle > 135){
            angle = 135;
        }
        cc.log("炮口摆动:" + sweep_angle+ ",修正后的角度:" +angle);
        this.node.angle = angle;
   }
    onTouchEnd(e:cc.Event.EventTouch) {
        this.fire();//鼠标松开,开火
    }
    onTouchCancle(e:cc.Event.EventTouch) {}   
    //开火 发射子弹
    fire() {
        if(this.bulletIcon==null){
            cc.log("请设置bulletIcon图片");
            return;
        }
        //炮口的指向,应是子弹的运行方向
        let angle : number = this.node.angle;
        let radian = angle * Math.PI/180; //角度值 转换成 弧度值
        let direction = cc.v2(Math.cos(radian),Math.sin(radian));//标准化向量

        //动态创建一个子弹 bulletNode,添加Sprite组件
        let bulletNode : cc.Node = new cc.Node(); //创建 子弹 节点
        let sprite : cc.Sprite = bulletNode.addComponent(cc.Sprite); // 创建 子弹节点的 精灵 组件
        sprite.spriteFrame = this.bulletIcon;//给精灵的精灵帧 赋值 子弹Icon
        bulletNode.parent = this.node.parent; //指定父节点是 炮塔的父节点->射击系统
        //子弹的角度及初始位置
        bulletNode.angle = this.node.angle;//子弹的角度 赋值成 炮口的角度
        let r = 140;//子弹与射击基准的距离
        let bullet_x = r * direction.x;
        let bullet_y= r * direction.y;
        bulletNode.setPosition(cc.v3(bullet_x,bullet_y));//子弹的初始位置


        //给子弹附加一个脚本组件Bullet.ts
        let bullet : Bullet = bulletNode.addComponent(Bullet);
        bullet.direction = direction; //子弹飞行的方向

    }
}

效果如图所示:

Cocos Creator游戏开发教程 学习笔记_第487张图片 Cocos Creator游戏开发教程 学习笔记_第488张图片

射击基准和靶标之间的距离要等于代码中写的是400。如图所示,还不是靶心。子弹还有长度,再调多一点到100,正好到靶心。

Cocos Creator游戏开发教程 学习笔记_第489张图片

17.6手工碰撞计算Cocos Creator游戏开发教程 学习笔记_第490张图片

 Cocos Creator游戏开发教程 学习笔记_第491张图片

 在Bullet.ts中进行检测:

Cocos Creator游戏开发教程 学习笔记_第492张图片

 Cocos Creator游戏开发教程 学习笔记_第493张图片

 Cocos Creator游戏开发教程 学习笔记_第494张图片

 在Cannon.ts中加上:

Cocos Creator游戏开发教程 学习笔记_第495张图片

 Cocos Creator游戏开发教程 学习笔记_第496张图片

但是这样也一点不准确。看来和半径没有关系。还是需要计算子弹的延长线和最终的终点才好。(试图计算,思路:计算靶标圆心和子弹延长线的终点(不会算),这两个点之间的距离小于靶标半径100,判定命中靶标。)调节射击系统和靶子的位置,然后让子弹弹头基本上可以垂直射中靶心。

Cocos Creator游戏开发教程 学习笔记_第497张图片

 Cocos Creator游戏开发教程 学习笔记_第498张图片

 Cocos Creator游戏开发教程 学习笔记_第499张图片Cocos Creator游戏开发教程 学习笔记_第500张图片

 如下代码,表示射在这条红线上是命中。(这就从视觉上比较精确了。)

Cocos Creator游戏开发教程 学习笔记_第501张图片

Cocos Creator游戏开发教程 学习笔记_第502张图片

17.7特效提示Cocos Creator游戏开发教程 学习笔记_第503张图片

 Cocos Creator游戏开发教程 学习笔记_第504张图片

在Cannon.ts中,添加:爆炸效果需要显示的图片,并把这个图片传递给Bullets.ts。

Cocos Creator游戏开发教程 学习笔记_第505张图片

 Cocos Creator游戏开发教程 学习笔记_第506张图片

在Bullet.ts中需要添加: 爆炸图片帧接受Cannon.ts中传递的图片。然后再命中目标之后,显示爆炸效果(图片)和加分效果(文字)。

Cocos Creator游戏开发教程 学习笔记_第507张图片

Cocos Creator游戏开发教程 学习笔记_第508张图片

Cocos Creator游戏开发教程 学习笔记_第509张图片Cocos Creator游戏开发教程 学习笔记_第510张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class Bullet extends cc.Component {
    //飞行的方向(标准化向量)
    direction : cc.Vec2 = null;
    //靶标
    target : cc.Node = null;
    //爆炸特效
    explodeEffect : cc.SpriteFrame = null;
   

    // LIFE-CYCLE CALLBACKS:
    onLoad () {}
    start () {
        if(this.target == null){
            cc.log('未设置靶标target属性!');
            return;
        }

        this.schedule(this.onTimer,0.016);
    }
    // update (dt) {}
    onTimer() {
        //靶标与射击基准之间的距离400
        if(this.node.y > 400){
            //this.dismiss();
            if(this.isHit()){
                this.success();

            }
            else{
                this.failed();
            }
            return;
        }
        let speed : number = 15; //步长
        let dx = speed * this.direction.x;
        let dy = speed * this.direction.y;
        this.node.x += dx;
        this.node.y += dy;
        
    }   
    
    isHit() : boolean {
        let targetPos : cc.Vec2 = this.getWorldLocation(this.target); //靶子的世界坐标
        let selfPos : cc.Vec2 = this.getWorldLocation(this.node);//子弹运行400px之后的世界坐标
    //let distance : number = Math.abs( targetPos.x - selfPos.x); //x方向距离
        cc.log('靶标x='+ targetPos.x + ',子弹x=' + selfPos.x);
        cc.log('靶标y='+ targetPos.y + ',子弹y=' + selfPos.y);
        let distanceD : number = cc.Vec2.distance( targetPos,selfPos);//两点的欧式距离,即两点直线距离。
        cc.log('间距distanceD='+ distanceD);
    // if(distance < 50){//粗略判断:一点也不准确!!!!
        if(distanceD > 607 && distanceD < 612.8){//根据射击数据和间距diatanceD看出来的607和612.8。
            return true;
        }else{
            return false;
        }
    }
    //获取一个节点的世界坐标
    getWorldLocation(node: cc.Node): cc.Vec2 {
        let pos = node.getPosition();
        return node.parent.convertToNodeSpaceAR(pos);
    }
    success() {//此处应该添加特效
        cc.log('命中目标!');
        //this.dismiss();
        this.explode();//爆炸
        this.cheer();//加分
        
    }
    //爆炸特效
    explode() {
        cc.log('爆炸效果...');
        let sp : cc.Sprite = this.node.getComponent(cc.Sprite);//创建新的渲染节点精灵,
        sp.spriteFrame = this.explodeEffect;//把爆炸效果图加入这个精灵的精灵帧,作为图片资源。

        this.node.scale = 0.8;//爆炸效果图初始显示的缩放大小,
        //“闭包”:在回调中无法直接调用this,所以先定义一个 self = this ,以便在回调中调用。
        let self = this;
        cc.tween(this.node)//缓动效果to设置最终值
            .to(0.3,{scale:1.5})//消失时的大小。
            .to(0.2,{opacity:0})//消失时的透明度0,变透明
            .call(function(){self.dismiss();})//爆炸显示完之后,销毁子弹
            .start();
    }
    //加分效果
    cheer(){
        let labelNode : cc.Node = new cc.Node();//声明新的节点
        let label : cc.Label = labelNode.addComponent(cc.Label);//声明文字标签组件
        label.string = "+10分";//给文字标签组件的string赋值
        labelNode.color = new cc.Color(255,0,0);//设置颜色
        labelNode.parent = this.node.parent;//设置该节点的父节点
        labelNode.setPosition(cc.v3(0,550,0));//设置该节点出现的位置
        labelNode.opacity =50;//初始透明度50

        cc.tween(labelNode) //缓动效果文字的缩放和透明度
            .to(0.3,{scale:1})
            .to(0.2,{opacity:0})
            .call(function(){labelNode.destroy();})//爆炸显示完之后,文本也销毁
            .start();
    }
    failed() {
        cc.log('脱靶!');
        this.dismiss();
    }
    dismiss() {
        this.node.destroy();
    }

}
// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import Bullet from "./Bullet";



const {ccclass, property} = cc._decorator;

@ccclass
export default class Cannon extends cc.Component {
    //内部属性
    startPos : cc.Vec2 = null;
    startAngle : number = null;//炮口的角度
    //添加子弹Icon
    @property(cc.SpriteFrame)
    bulletIcon: cc.SpriteFrame = null;
    //爆炸效果图片
    @property(cc.SpriteFrame)
    explodeEffect: cc.SpriteFrame = null;

    // LIFE-CYCLE CALLBACKS:
    onLoad () {
        this.node.angle = 90; // 初始值设置为90度
        this.node.on('touchstart',this.onTouchStart,this);
        this.node.on('touchmove',this.onTouchMove,this);
        this.node.on('touchend',this.onTouchEnd,this);
        this.node.on('touchcancle',this.onTouchCancle,this);
    }
    start () {}
    // update (dt) {}
    onTouchStart(e:cc.Event.EventTouch) {
        // startPos :触点开始的位置 (将一个点转换到节点 (局部:父节点) 空间坐标系。)
        this.startPos = this.node.parent.convertToNodeSpaceAR(e.getLocation());
        // startAngle:炮口的初始角度(x轴方向为0度)
        this.startAngle = this.node.angle;
    }
    onTouchMove(e:cc.Event.EventTouch) {
        // 触点的当前位置
        let pos = this.node.parent.convertToNodeSpaceAR(e.getLocation());
        //摆动的角度,a.signAngle(b)即a向量与b向量之间的夹角。
        let sweep_radian = pos.signAngle(this.startPos);//弧度radian值,例如π/4
        let sweep_angle = 180 * sweep_radian / Math.PI; //弧度radian值 转化成 角度angle值
        /*炮口的新指向:
            比如,原来炮口90度,向右摆动15度,则炮口应该指向90-15=75度;
            比如,原来炮口90度,向左摆动15度,则炮口应该指向90-(-15)=105度; 
        */
        let angle = this.startAngle - sweep_angle;//炮口的新角度
        // 炮口角度限制在45~135度之间
        if(angle < 45){
            angle = 45;
        }
        if(angle > 135){
            angle = 135;
        }
        cc.log("炮口摆动:" + sweep_angle+ ",修正后的角度:" +angle);
        this.node.angle = angle;
   }
    onTouchEnd(e:cc.Event.EventTouch) {
        this.fire();//鼠标松开,开火
    }
    onTouchCancle(e:cc.Event.EventTouch) {}   
    //开火 发射子弹
    fire() {
        if(this.bulletIcon==null){
            cc.log("请设置bulletIcon图片");
            return;
        }
        //炮口的指向,应是子弹的运行方向
        let angle : number = this.node.angle;
        let radian = angle * Math.PI/180; //角度值 转换成 弧度值
        let direction = cc.v2(Math.cos(radian),Math.sin(radian));//标准化向量

        //动态创建一个子弹 bulletNode,添加Sprite组件
        let bulletNode : cc.Node = new cc.Node(); //创建 子弹 节点
        let sprite : cc.Sprite = bulletNode.addComponent(cc.Sprite); // 创建 子弹节点的 精灵 组件
        sprite.spriteFrame = this.bulletIcon;//给精灵的精灵帧 赋值 子弹Icon
        bulletNode.parent = this.node.parent; //指定父节点是 炮塔的父节点->射击系统
        //子弹的角度及初始位置
        bulletNode.angle = this.node.angle;//子弹的角度 赋值成 炮口的角度
        let r = 140;//子弹与射击基准的距离
        let bullet_x = r * direction.x;
        let bullet_y= r * direction.y;
        bulletNode.setPosition(cc.v3(bullet_x,bullet_y));//子弹的初始位置


        //给子弹(方向在炮塔)附加一个脚本组件Bullet.ts,控制子弹飞行的效果:距离、特效
        let bullet : Bullet = bulletNode.addComponent(Bullet);
        bullet.direction = direction; //子弹飞行的方向

        //添加子弹的子节点 target 靶子  和爆炸效果图
        bullet.target = cc.find('Canvas/靶子');
        bullet.explodeEffect = this.explodeEffect; //爆炸效果的图片需要传递

    }
}

17.8靶标的运动控制Cocos Creator游戏开发教程 学习笔记_第511张图片

 

 添加新脚本靶子Target.ts;挂在靶子这个节点下面。

@ccclass
export default class Target  extends cc.Component {

    //运动方向,规定左为正方向
    isLeaf : boolean = true;
    onLoad () {}
    start () {}
    update (dt) {
        let dx : number = 3;//每一帧移动3px
        if(this.isLeaf==true){//如果运动到最左端,就换方向
            dx = 0 - dx;   
        }
        this.node.x += dx;
        //判断移动的方向和最大距离
        if(this.isLeaf && this.node.x < -400){
            this.isLeaf = false;//如果向左移动超过200,则则向右移动
        }
        if( ! this.isLeaf && this.node.x > 400){
            this.isLeaf = true;//如果向右移动超过200,则向左移动
        }

    }
}

17.09弹药量显示Cocos Creator游戏开发教程 学习笔记_第512张图片

 Cocos Creator游戏开发教程 学习笔记_第513张图片

创建一个渲染节点->单色节点,自己选一个颜色,作为弹夹的背景颜色区域。 宽250,高50。

把弹夹的锚点设置在左方。

Cocos Creator游戏开发教程 学习笔记_第514张图片

 然后给弹仓下面附加一个脚本Magazine.ts。并添加图片。 

Cocos Creator游戏开发教程 学习笔记_第515张图片Cocos Creator游戏开发教程 学习笔记_第516张图片

 为了使弹仓显示在左下角。可以给弹仓添加一个组件:

Cocos Creator游戏开发教程 学习笔记_第517张图片Cocos Creator游戏开发教程 学习笔记_第518张图片

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html


const {ccclass, property} = cc._decorator;

// 弹匣

@ccclass
export default class Magazine extends cc.Component {

    // 子弹图片
    @property(cc.SpriteFrame)
    bulletIcon : cc.SpriteFrame = null;

    capacity : number = 10; // 最大弹药capacity容量。
    count : number = 10; // 现有弹药数量

    onLoad () {
        // 子弹的水平间距
        let space: number = this.node.width / this.capacity;

        // 动态创建10个子弹。
        let i : number = 0;
        for(i =0; i< this.capacity ; i++)
        {
            let bulletNode : cc.Node = new cc.Node();
            let bulletSprite  : cc.Sprite = bulletNode.addComponent(cc.Sprite);
            bulletSprite.spriteFrame = this.bulletIcon;
            this.node.addChild( bulletNode );
            //位置:
            bulletNode.x = space * i + 10; // 向右偏移一些
            bulletNode.y = 0;
        }
    }
    start () {}
    // update (dt) {}

      
    //下面的代码暂时还没有用到。 
    // 重置
    reset (){
        this.count = this.capacity;
        this.display();
    }

    // 消耗n个子弹
    consume ( n : number){
        this.count -= n;
        if(this.count < 0) 
            this.count = 0;
        
        this.display();
    }

    // 显示剩余的子弹
    // active的表示剩下的子弹
    display (){
        let nodes : cc.Node[] = this.node.children;

        let i : number = 0;
        for(i=0; i< nodes.length ; i++)
        {
            if(this.count > i)
                nodes[i].active = true;
            else
                nodes[i].active = false;
        }
    }
}

17.10全局对象Cocos Creator游戏开发教程 学习笔记_第519张图片

 方法一:

Cocos Creator游戏开发教程 学习笔记_第520张图片

 //射出一颗子弹爆炸之后,减少一颗子弹的图片显示
            //简单方法:找到弹夹下面的组件Magazine,然后给方法comsume传递一个参数1。
        let magazine : Magazine = cc.find('Canvas/弹夹').getComponent('Magazine');
        magazine.consume(1);

Cocos Creator游戏开发教程 学习笔记_第521张图片

 这样写很直接,但是不优美。因为在其他地方也可能会用到Magazine这个对象。这样就会很多次的调用find和get方法。所以用下面这些方法:集中定义的方法,把需要使用的方法集中定义,然后初始化。

使用全局对象,把经常要访问的对象定义为全局对象,放在一个文件中。

 方法二:

Cocos Creator游戏开发教程 学习笔记_第522张图片Cocos Creator游戏开发教程 学习笔记_第523张图片

在文件夹script中 添加一个新的组件Common.ts设置全局对象。

Cocos Creator游戏开发教程 学习笔记_第524张图片

 新建一个一级节点:其他。(和Canvas平级。)然后在其他下面新建一个节点:游戏初始化,把Common.ts挂载这个节点下面。(当游戏加载的时候,会先加载Canvas,然后加载其他和下面的方法)

Cocos Creator游戏开发教程 学习笔记_第525张图片

有三个步骤:

1 添加 Common.ts

import Magazine from "./Magazine";

const {ccclass, property} = cc._decorator;

@ccclass
export default class Common extends cc.Component {

   // 全局对象 ( 或者叫静态对象、静态引用)
   static magazine : Magazine = null;
   onLoad () {
       Common.magazine =cc.find('Canvas/弹夹').getComponent('Magazine');
   }

}

2 初始化

        (有两种方法。这里说的是其中一种。)

(1) 添加一个节点(其他->游戏初始化)

(2) 挂载Coomon.ts脚本

于是,当游戏加载该节点时,Common.onLoad()被调用

3 全局对象的调用(在Cannon.ts中调用)

Cocos Creator游戏开发教程 学习笔记_第526张图片

17.11结果提示框Cocos Creator游戏开发教程 学习笔记_第527张图片

 Cocos Creator游戏开发教程 学习笔记_第528张图片Cocos Creator游戏开发教程 学习笔记_第529张图片

 在Canvas下面创建一个节点“结果提示框”,设置大小,添加组件Widget。然后在节点下面创建单色节点作为子节点 “遮罩层”把游戏主画面遮住,并设置颜色、大小和透明度,添加组件Widget。

Cocos Creator游戏开发教程 学习笔记_第530张图片Cocos Creator游戏开发教程 学习笔记_第531张图片

 当提示框显示的时候,背后的游戏应该是不能操作的,需要添加拦截。

现在我们先做出效果,然后再加拦截。

把分数框图片添加到结果提示框下面,并调整大小和位置。

在结果提示框下面,创建一个文字节点,命名为 replay。文字内容是“再玩一局”。设置颜色和位置。
Cocos Creator游戏开发教程 学习笔记_第532张图片

 在结果提示框下面,单独加一个节点,作为分数。写入内容10分。调整颜色和位置。

Cocos Creator游戏开发教程 学习笔记_第533张图片

 在文件夹script中 新建ResultDialog.ts脚本,并添加屏蔽。

Cocos Creator游戏开发教程 学习笔记_第534张图片


const {ccclass, property} = cc._decorator;

@ccclass
export default class ResultDialog extends cc.Component {
    //找到replay节点,响应方法dimiss,关掉结果提示框
    onLoad () {
        let replayNode : cc.Node = cc.find('replay',this.node);
        replayNode.on('touchstart',this.dismiss,this);

        //添加屏蔽
        this.node.on('touchstart',this.onTouchDisable,this);
        this.node.on('touchmove',this.onTouchDisable,this);
        this.node.on('touchend',this.onTouchDisable,this);

    }
  
    start () {

    }
    //显示提示框
    show(){
        this.node.active = true;
    }
    //隐藏提示框
    dismiss() {
        this.node.active = false;
    }
    //停止传递当前事件
    onTouchDisable( e : cc.Event.EventTouch ) {
        e.stopPropagation();
    }

    

    // update (dt) {}
}

17.12得分统计Cocos Creator游戏开发教程 学习笔记_第535张图片

 Cocos Creator游戏开发教程 学习笔记_第536张图片每一发子弹有10分,10发子弹满分100分,每次击中则记录加10分。这需要一个全局变量,记录一个玩家在一局中所得的分数。步骤如下:

1 添加一个全局变量score得分。

Common.ts


import Magazine from "./Magazine";
import ResultDialog from "./ResultDialog";

const {ccclass, property} = cc._decorator;

@ccclass
export default class Common extends cc.Component {

   // 全局对象 ( 或者叫静态对象、静态引用)
   static magazine : Magazine = null;

   //得分统计
   static score : number = 0;
   
   //结果提示框
   static resultDialog : ResultDialog = null;

   onLoad () {
       Common.magazine =cc.find('Canvas/弹夹').getComponent('Magazine');
       Common.resultDialog =cc.find('Canvas/结果提示框').getComponent('ResultDialog');

   }

}

2 命中时加分

Bullet.ts

success(){       

        this.explode();

        this.cheer();          

        // 得分

        Common.score += 10;

}

3 结局判断  (结果提示框也要加入全局变量。)

Bullet.ts

    dismiss(){

        this.node.destroy();        

 //如果10发子弹用完,游戏结束,显示 结果提示框。

        if(Common.magazine.count <= 0) {

            Common.resultDialog.show();

        }

}

4 得分显示

ResultDialog.ts

    show(){

        this.node.active = true;

        // 显示最终得分

        let scoreNode : cc.Node = cc.find('分数', this.node);

        let scoreLabel : cc.Label = scoreNode.getComponent(cc.Label);  

        scoreLabel.string = Common.score + '';    

}

17.13重新开始游戏Cocos Creator游戏开发教程 学习笔记_第537张图片

Cocos Creator游戏开发教程 学习笔记_第538张图片

 

 

17.14音效及其他Cocos Creator游戏开发教程 学习笔记_第539张图片

Cocos Creator游戏开发教程 学习笔记_第540张图片

你可能感兴趣的:(cocos开发,cocos2d)