CocosCreator知识库<二>关于TiledMap的系统学习教程(阶段性更新)

CocosCreator知识库<二>关于TiledMap的系统学习教程<26/12/2017>(长期更新,看不懂先大致总体搞一遍,然后回头细看)

 

                    TiledMap官网:(不收费,点击Nothanks免费下载最新版)

                                传送门:http://www.mapeditor.org/

 

推荐教程<零>TiledMap瓦片地图(potato47)

      传送门:http://blog.csdn.net/potato47/article/details/51366481

基础教程<一>基础功能+地形功能

      传送门:http://blog.csdn.net/firseve/article/details/50789526

进阶教程<二>动画效果

      传送门:http://blog.csdn.net/firseve/article/details/50952100

进阶教程<三>TiledMap坐标转换(认识TiledMap的三种地图类型)

      传送门:http://blog.csdn.net/z104207/article/details/46873429

进阶教程<四>详细的45度角坐标计算

      传送门:http://blog.csdn.net/jianglong0156/article/details/52700551

 

 

常用方法汇总:

 

#CC.TiledMap:*****************************************
~properties:
tmxFile//地图文件
mapLoaded//地图加载是调用的函数
~function:
getMapSize()//
setMapSize()//
getTileSize()//
setTileSize()//
getLayer(name)//returns TieldLayer
getObjectGroup(name)//returns TMXObjectGroup
getPropertiesForGID(GID)//returns Object(属性字典)

#CC.TieldLayer    ********************************************
getPositionAt(pos)//returns Vec2(像素坐标) 参数是瓦片坐标
removeTileAt(pos)//瓦片坐标
getTileGIDAt(pos)//returns Number(全局唯一标识,0为空)
getTileAt(pos)//returns _ccsg.Sprite   //removeChild(sprite);
setTileGID(gid,pos)//相当于在pos位置添加GID的图块(原来的图块删除)
getTileSize()//
setTleSize()//
getMapTileSize()

#TMXObjectGroup:   ******************************************
~properties:
~function:
var getObject(var objectName)//返回属性字典
#_ccsg.Sprite://cocos js 里的Sprite,继承自CC.Node,而不是组件
~properties:
x
y
width
height
opacity
...//节点的属性都有
~function:
var setSpriteFrame(var spriteFrameName)
var runAction(var action)   
...//节点的方法都有

 

 

 

 

 

 

<坦克大战项目>TiledMap相关部分填坑:(详情请见博主原博客)

      关于之前的坦克大战,主要是在GameManager里面初始化的(提前将对应的.tmx地图文件拖入场景之中)

在TiledMap中进行编辑完层后,各层对应关系如图:

CocosCreator知识库&lt;二&gt;关于TiledMap的系统学习教程(阶段性更新)_第1张图片CocosCreator知识库&lt;二&gt;关于TiledMap的系统学习教程(阶段性更新)_第2张图片CocosCreator知识库&lt;二&gt;关于TiledMap的系统学习教程(阶段性更新)_第3张图片

在TiledMap编辑器中完成的层级关系简单说明:

CocosCreator知识库&lt;二&gt;关于TiledMap的系统学习教程(阶段性更新)_第4张图片

从资源管理器中拖入编辑好的单个.tmx文件会自动解析并生成对应结构(可对比上方TiledMap中编辑的层级结构,很方便!)

CocosCreator知识库&lt;二&gt;关于TiledMap的系统学习教程(阶段性更新)_第5张图片CocosCreator知识库&lt;二&gt;关于TiledMap的系统学习教程(阶段性更新)_第6张图片

为什么要排列好层级顺序?因为可以产生层级效果:

CocosCreator知识库&lt;二&gt;关于TiledMap的系统学习教程(阶段性更新)_第7张图片然后实际效果如图CocosCreator知识库&lt;二&gt;关于TiledMap的系统学习教程(阶段性更新)_第8张图片

 

接下来我们从坦克大战代码中提取仅仅与TiledMap地图生成创建判断相关的代码块做展示和研究:

GameManager中与TiledMap相关的部分:(导入数据并解析地图,通过坐标转换,然后完成碰撞墙壁侦测)[重点:内部碰撞方法中对基地爆炸碰撞检测的部分,涉及核心知识]

 

var Game = cc.Class({  
    extends: cc.Component,  
  
    properties: {  
        //地图  
        curMap: cc.TiledMap,  
    },  
  
    // use this for initialization  
    onLoad: function () {  
        //获取地图 TiledMap 组件  
        this._tiledMap = this.curMap.getComponent('cc.TiledMap');  
    },  
  
    start: function (err) {  
        if (err) {  
            return;  
        }  
  
        //引入地图数据  
        this._tiledMapData = require("TiledMapData");  
  
        //获取地图尺寸  
        this._curMapTileSize = this._tiledMap.getTileSize();  
        this._curMapSize = cc.v2(this._tiledMap.node.width, this._tiledMap.node.height);  
  
        // 地图墙层  
        this.mapLayer0 = this._tiledMap.getLayer("layer_0");  
  
        //获取组件  
        this.tankNode = cc.find("/Canvas/Map/tank");  
    },  
  
    //碰撞检测(与TiledMap相关,准备注释)  
    collisionTest: function (rect, bullet) {  
        //判断是否碰到地图边界  
        if (rect.xMin <= -this._curMapSize.x / 2 || rect.xMax >= this._curMapSize.x / 2 ||  
            rect.yMin <= -this._curMapSize.y / 2 || rect.yMax >= this._curMapSize.y / 2) {  
  
            return true;  
        }  
        //判断是否撞墙  
        //将坐标转换为地图坐标系  
        var MinY = this._curMapSize.y / 2 - rect.yMin;  
        var MaxY = this._curMapSize.y / 2 - rect.yMax;  
        var MinX = this._curMapSize.x / 2 + rect.xMin;  
        var MaxX = this._curMapSize.x / 2 + rect.xMax;  
  
        //获取四个角的顶点  
        var LeftDown = cc.v2(MinX, MinY);  
        var RightDown = cc.v2(MaxX, MinY);  
        var LeftUp = cc.v2(MinX, MaxY);  
        var RightUp = cc.v2(MaxX, MaxY);  
  
        //获取四条边的中心点  
        var MidDown = cc.v2(MinX + (MaxX - MinX) / 2, MinY);  
        var MidUp = cc.v2(MinX + (MaxX - MinX) / 2, MaxY);  
        var MidLeft = cc.v2(MinX, MinY + (MaxY - MinY) / 2);  
        var MidRight = cc.v2(MaxX, MinY + (MaxY - MinY) / 2);  
  
        //检测碰撞  
        return this._collisionTest([LeftDown, RightDown, LeftUp, RightUp,  
                MidDown, MidUp, MidLeft, MidRight  
            ],  
            bullet);  
    //内部碰撞检测方法
    _collisionTest: function (points, bullet) {
        var point = points.shift()
        var gid = this.mapLayer0.getTileGIDAt(cc.v2(parseInt(point.x / this._curMapTileSize.width), parseInt(point.y / this._curMapTileSize.height)));
        if (this._tiledMapData.gidToTileType[gid] != this._tiledMapData.tileType.tileNone &&
            this._tiledMapData.gidToTileType[gid] != this._tiledMapData.tileType.tileGrass) {
            if (bullet && this._tiledMapData.gidToTileType[gid] == this._tiledMapData.tileType.tileKing) { //基地
                this.scheduleOnce(function () {
                    this.gameOver.active = true;
                }, 1.5);
                this.scheduleOnce(function () {
                    cc.director.loadScene("StartScene");
                    this.socket.emit("gameover");
                }, 3);

                this.mapLayer0.setTileGID(25, 12, 24);
                this.mapLayer0.setTileGID(26, 13, 24);
                this.mapLayer0.setTileGID(31, 12, 25);
                this.mapLayer0.setTileGID(32, 13, 25);
            }
            if (bullet && this._tiledMapData.gidToTileType[gid] == this._tiledMapData.tileType.tileWall) { //墙
                this.mapLayer0.removeTileAt(cc.v2(parseInt(point.x / this._curMapTileSize.width), parseInt(point.y / this._curMapTileSize.height)));
            }
            return true;
        }
        if (points.length > 0) {
            return this._collisionTest(points, bullet);
        } else {
            return false;
        }
    },
    },  

 

 

 

 

 

 

 

Bullet脚本中与TiledMap相关的部分:(主要是用到了GameManager里面侦测墙壁的方法,并且传入了子弹的boundingbox包围盒做参数)

cc.Class({
    extends: cc.Component,

    onLoad: function () {
        //获取组件
        this._cityCtrl = cc.find("/GameManager").getComponent("GameManager");
        this.bulletNode = cc.find("/Canvas/Map/bullet");
    },

    stepUpdate: function (dt, stepTime) {

        if (!this.stopMove) {
            //返回父节坐标系下的轴向对齐的包围盒
            var boundingBox = this.node.getBoundingBox();
            //该方法用来快速创建一个新的矩形  var a = new cc.Rect(0 , 0, 10, 0);
            var rect = cc.rect(boundingBox.xMin + this.offset.x * this.speed * dt * 1.5,
                boundingBox.yMin + this.offset.y * this.speed * dt * 1.7,
                boundingBox.size.width,
                boundingBox.size.height);
            if (this._cityCtrl.collisionTest(rect) //检测与地图的碰撞
                || //上下侦测满足其一则执行
                this.collisionTank(rect) //检测与坦克的碰撞
            ) {
                this.tankMoveStop(); //如果发生碰撞立即停止坦克行动
            } else {
                //如果没有发生碰撞,继续按照原有的偏移量和速度进行移动

                this.node.x += this.offset.x * this.speed * dt;
                this.node.y += this.offset.y * this.speed * dt;
            }
        }
    },
});

 

TiledMapData脚本:(用来枚举TiledMap地图数据类型相关信息)

 

var _tileType = cc.Enum({
    tileNone: 0,
    tileGrass: 1,
    tileSteel: 2,
    tileWall: 3,
    tileRiver: 4,
    tileKing: 5
});
//gid从1开始
var _gidToTileType = [
    _tileType.tileNone, //从1开始,这个不算

    _tileType.tileNone, _tileType.tileNone, _tileType.tileGrass, _tileType.tileGrass, _tileType.tileSteel, _tileType.tileSteel,
    _tileType.tileNone, _tileType.tileNone, _tileType.tileGrass, _tileType.tileGrass, _tileType.tileSteel, _tileType.tileSteel,

    _tileType.tileWall, _tileType.tileWall, _tileType.tileRiver, _tileType.tileRiver, _tileType.tileKing, _tileType.tileKing,
    _tileType.tileWall, _tileType.tileWall, _tileType.tileRiver, _tileType.tileRiver, _tileType.tileKing, _tileType.tileKing,

    _tileType.tileFalseKing, _tileType.tileFalseKing, _tileType.tileNone, _tileType.tileNone, _tileType.tileNone, _tileType.tileNone,
    _tileType.tileFalseKing, _tileType.tileFalseKing, _tileType.tileNone, _tileType.tileNone, _tileType.tileNone, _tileType.tileNone
];

module.exports = {
    tileType: _tileType,
    gidToTileType: _gidToTileType
};

下图为解析上面TiledMapData脚本:(这个部分结合上面脚本中内部碰撞侦测方法理解比较好)

 

CocosCreator知识库&lt;二&gt;关于TiledMap的系统学习教程(阶段性更新)_第9张图片
 

 

要点补充,对于已经编辑好的地图进行素材更换:

CocosCreator知识库&lt;二&gt;关于TiledMap的系统学习教程(阶段性更新)_第10张图片CocosCreator知识库&lt;二&gt;关于TiledMap的系统学习教程(阶段性更新)_第11张图片CocosCreator知识库&lt;二&gt;关于TiledMap的系统学习教程(阶段性更新)_第12张图片

下列这些必须完全一致,排列顺序也一样:

CocosCreator知识库&lt;二&gt;关于TiledMap的系统学习教程(阶段性更新)_第13张图片

以上!

 

你可能感兴趣的:(CocosCreator,CocosCreator知识库)