CocosCreator塔防

塔防(TowerDefence)

场景搭建

设置CocosCreator布局为经典布局

规范项目资源目录结构

目录 描述
scene 场景目录
script 脚本目录
texture 纹理目录
anim 动画片段

保存当前场景到scene目录下并命名为game.fire

将游戏资源拖拽到texture目录下

  • 搭建游戏场景
  • 游戏场景中创建路径导航

将地图纹理拖拽到Canvas渲染节点上释放后会在画布节点下生成新的地图节点,修改画布节点的设计分辨率为地图自身的宽高。

创建地图

设置主角hero节点,在其下创建单色渲染精灵节点,并命名为blood血条,调整血条的背景色为红色。设置blood`血条的宽高尺寸为30x3。

在blodd节点下创建子节点,即选择创建节点中的创建渲染下选中Sprite单色节点,同时命名为value。设置value节点中Sprite属性中Type为FIELD,同时设置Fill Range为1。

制作敌人

制作敌人与血条

制作角色与血条.gif

制作路径

使用动画编辑器创建补间动画完成路径的绘制

制作路径.gif
补间动画

使用自定义的组件类从补间动画中获取所有节点的坐标

贝塞尔曲线

贝塞尔曲线是应用于2D图形的数学曲线,该曲线的定义由4个点组成,分别是起始点p0,终止点p3(又称为锚点),以及两个相互分离的中间点控制点p1和p2。

  • p0 起始点
  • p1 中间控制点1
  • p2 中间控制点2
  • p3 终止点
CocosCreator塔防_第1张图片
贝塞尔曲线

创建path.js用户脚本组件,用于将路径动画片段中的贝塞尔曲线转化为坐标点。

$ vim /assets/script/path.js
cc.Class({
    extends: cc.Component,
    properties: {
        debug:true
    },
    onLoad () {
        //获取当前节点上的动画组件
        this.anim = this.node.getComponent(cc.Animation);
        //获取动画片段
        const clips = this.anim.getClips();
        //获取当前片段
        const clip = clips[0];

        //获取贝塞尔曲线路径
        this.pathdata = [];
        const paths = clip.curveData.paths;
        for(let k in paths){
            const frames = paths[k].props.position;
            this.genPathData(frames);
        }

        //根据调试模式绘制节点
        if(this.debug){
            //添加绘图组件
            this.graphics = this.node.addComponent(cc.Graphics);
            this.graphics.fillColor = cc.color(255, 0, 0, 255);
            this.graphic();
        }
    },
    graphic(){
        this.graphics.clear();
        for(let i=0; i

path路径节点添加自定义的用户脚本组件path.js

设置脚本组件

预览观察调试模式下路径

CocosCreator塔防_第2张图片
路径

敌人导航

控制敌人沿着路径移动

$ vim assts/script/enemy.js
/**控制敌人按照路径导航移动 */
const Path = require("./path");
cc.Class({
    extends: cc.Component,
    properties: {
        path:{type:Path, default:null, tooltip:"路径组件"},
    },
    pause(){
        this.walking = false;
    },
    reset(){
        this.walking = true;
    },
    //读取配置文件获取初始化变量
    initConfig(config){
        this.config = config;
        this.speed = config.speed;
        this.index = config.index;//路径索引
    },
    start(){
        this.walking = false;
        //读取配置初始化参数
        this.initConfig({speed:200, min_blood:100, max_blood:1000, index:0});
        //生成路径节点坐标
        this.getPath(this.index);
        //设置敌人验证路径节点移动
        this.walk();
        //行走中的暂停,5秒内走2秒暂停3秒
        this.scheduleOnce(this.pause.bind(this), 3);//3秒后暂停
        this.scheduleOnce(this.reset.bind(this), 5);//移动5秒
    },
    //生成路径节点
    getPath(index){
        //获取目标路径节点的集合
        const pathdata = this.path.getPathData();
        if(index < 0 || index >= pathdata.length){
            return;
        }
        this.pathnode = pathdata[index];
        //cc.log("pathnode", this.pathnode);
    },
    //设置敌人验证路径节点移动
    walk(){
        if(this.pathnode.length < 2){
            return;
        }
        //设置敌人移动到起点位置
        this.node.setPosition(this.pathnode[0].x, this.pathnode[0].y);
        //记录下一步
        this.next = 1;
        //从当前点移动到下一点
        this.walkToNext();
    },
    //从当前点移动到下一步
    walkToNext(){
        //是否走到最后一点
        if(this.next > this.pathnode.length){
            this.walking = false;
            return;
        }
        //获取起点和终点
        const src = this.node.getPosition();
        const dst = this.pathnode[this.next];
        if(dst == undefined){
            return;
        }
        //获取起始点和终止点之间的方向向量
        const dir = dst.sub(src);
        //计算向量长度,取模
        const distance = dir.mag();
        //判断长度是否超出
        if(distance <= 0){
            this.next ++;
            this.walkToNext();//跳入下一步
            return;
        }
        //将速度分解
        this.vx = this.speed * dir.x / distance;
        this.vy = this.speed * dir.y / distance;
        //计算从起点移动到终点所需要耗费的时间长度
        this.walktime = distance / this.speed;

        //定义定时器用于判断行走过程中的累加时间是否大于总消耗时间
        this.timer = 0;

        //设置行走状态
        this.walking = true;
    },
    //敌人移动 dt是每次更新的时间间隔
    update(dt){
        if(!this.walking){
            return;
        }
        //累加时间
        this.timer += dt;
        //重新设置当前节点的坐标
        if(this.timer >= this.walktime){
            dt -= (this.timer - this.walktime);
        }
        this.node.x += this.vx * dt;
        this.node.y += this.vy * dt;
        //判断计时器时间进入下一步
        if(this.timer >= this.walktime){
            this.next ++;
            this.walkToNext();
        }
    }
});
添加脚本组件

你可能感兴趣的:(游戏,游戏开发,react,elasticsearch,webgl)