问一个TiledMap相关的问题:
我在编辑地图的时候,想做一个障碍物,但是障碍物有一部分是空白的。
而TiledMap中自带了图块碰撞编辑器,我用该编辑器编辑了可碰撞的区域后,目前不清楚怎么获取到该图块的碰撞区域。
所以我想知道一下如何在代码中获取到对应的可碰撞区域?
麻烦知道的童鞋告知一下,感激不尽。
示意图如下:
引擎没有实现 对引擎进行一下扩展可以获取到
新建一个 js 脚本 复制下面的代码
function strToColor (value) {
if (!value) {
return cc.color(0, 0, 0, 255);
}
value = (value.indexOf('#') !== -1) ? value.substring(1) : value;
if (value.length === 8) {
let a = parseInt(value.substr(0, 2), 16) || 255;
let r = parseInt(value.substr(2, 2), 16) || 0;
let g = parseInt(value.substr(4, 2), 16) || 0;
let b = parseInt(value.substr(6, 2), 16) || 0;
return cc.color(r, g, b, a);
} else {
let r = parseInt(value.substr(0, 2), 16) || 0;
let g = parseInt(value.substr(2, 2), 16) || 0;
let b = parseInt(value.substr(4, 2), 16) || 0;
return cc.color(r, g, b, 255);
}
}
// 扩展导出 m_type (对象类型)
function getPropertyList (node, map) {
let res = [];
let properties = node.getElementsByTagName("properties");
for (let i = 0; i < properties.length; ++i) {
let property = properties[i].getElementsByTagName("property");
for (let j = 0; j < property.length; ++j) {
res.push(property[j]);
}
}
map = map || {};
for (let i = 0; i < res.length; i++) {
let element = res[i];
let name = element.getAttribute('name');
let type = element.getAttribute('type') || 'string';
let value = element.getAttribute('value');
if (type === 'int') {
value = parseInt(value);
}
else if (type === 'float') {
value = parseFloat(value);
}
else if (type === 'bool') {
value = value === 'true';
}
else if (type === 'color') {
value = strToColor(value);
}
map[name] = value;
}
return map;
}
cc.TiledMap.prototype._tileObjectGroups = [];
if(!CC_EDITOR){
cc.js.getset(cc.TiledMap.prototype,"tileObjectGroups",function(){ return this._tileObjectGroups;});
}
// let _buildWithMapInfo = cc.TiledMap.prototype._buildWithMapInfo;
cc.TiledMap.prototype._buildWithMapInfo = function(mapInfo) {
this._mapInfo = mapInfo;
this._mapSize = mapInfo.getMapSize();
this._tileSize = mapInfo.getTileSize();
this._mapOrientation = mapInfo.orientation;
this._properties = mapInfo.properties;
this._tileProperties = mapInfo.getTileProperties();
this._imageLayers = mapInfo.getImageLayers();
this._animations = mapInfo.getTileAnimations();
this._tileObjectGroups = mapInfo._tileObjectGroups;
this._tilesets = mapInfo.getTilesets();
let tilesets = this._tilesets;
this._textures.length = 0;
let totalTextures = [];
for (let i = 0, l = tilesets.length; i < l; ++i) {
let tilesetInfo = tilesets[i];
if (!tilesetInfo || !tilesetInfo.sourceImage) continue;
this._textures[i] = tilesetInfo.sourceImage;
totalTextures.push(tilesetInfo.sourceImage);
}
for (let i = 0; i < this._imageLayers.length; i++) {
let imageLayer = this._imageLayers[i];
if (!imageLayer || !imageLayer.sourceImage) continue;
totalTextures.push(imageLayer.sourceImage);
}
cc.TiledMap.loadAllTextures (totalTextures, function () {
this._buildLayerAndGroup();
}.bind(this));
}
cc.TMXMapInfo.prototype._tileObjectGroups = {};
let _initWithXML = cc.TMXMapInfo.prototype.initWithXML;
cc.TMXMapInfo.prototype.initWithXML = function (tmxString, tsxMap, textures, textureSizes, imageLayerTextures) {
this._tilesets.length = 0;
this._layers.length = 0;
this._imageLayers.length = 0;
this._tsxMap = tsxMap;
this._textures = textures;
this._imageLayerTextures = imageLayerTextures;
this._textureSizes = textureSizes;
this._objectGroups.length = 0;
this._allChildren.length = 0;
this.properties.length = 0;
this._tileProperties = {};
this._tileAnimations = {};
this._tileObjectGroups = {};
// tmp vars
this.currentString = "";
this.storingCharacters = false;
this.layerAttrs = cc.TMXLayerInfo.ATTRIB_NONE;
this.parentElement = cc.TiledMap.NONE;
return this.parseXMLString(tmxString);
}
cc.TMXMapInfo.prototype.parseXMLString = function(xmlStr, tilesetFirstGid) {
let mapXML = this._parser._parseXML(xmlStr);
let i;
// PARSE <map>
let map = mapXML.documentElement;
let orientationStr = map.getAttribute('orientation');
let staggerAxisStr = map.getAttribute('staggeraxis');
let staggerIndexStr = map.getAttribute('staggerindex');
let hexSideLengthStr = map.getAttribute('hexsidelength');
let renderorderStr = map.getAttribute('renderorder');
let version = map.getAttribute('version') || '1.0.0';
if (map.nodeName === "map") {
let versionArr = version.split('.');
let supportVersion = this._supportVersion;
for (let i = 0; i < supportVersion.length; i++) {
let v = parseInt(versionArr[i]) || 0;
let sv = supportVersion[i];
if (sv < v) {
cc.logID(7216, version);
break;
}
}
if (orientationStr === "orthogonal")
this.orientation = cc.TiledMap.Orientation.ORTHO;
else if (orientationStr === "isometric")
this.orientation = cc.TiledMap.Orientation.ISO;
else if (orientationStr === "hexagonal")
this.orientation = cc.TiledMap.Orientation.HEX;
else if (orientationStr !== null)
cc.logID(7217, orientationStr);
if (renderorderStr === 'right-up') {
this.renderOrder = cc.TiledMap.RenderOrder.RightUp;
} else if (renderorderStr === 'left-up') {
this.renderOrder = cc.TiledMap.RenderOrder.LeftUp;
} else if (renderorderStr === 'left-down') {
this.renderOrder = cc.TiledMap.RenderOrder.LeftDown;
} else {
this.renderOrder = cc.TiledMap.RenderOrder.RightDown;
}
if (staggerAxisStr === 'x') {
this.setStaggerAxis(cc.TiledMap.StaggerAxis.STAGGERAXIS_X);
}
else if (staggerAxisStr === 'y') {
this.setStaggerAxis(cc.TiledMap.StaggerAxis.STAGGERAXIS_Y);
}
if (staggerIndexStr === 'odd') {
this.setStaggerIndex(cc.TiledMap.StaggerIndex.STAGGERINDEX_ODD);
}
else if (staggerIndexStr === 'even') {
this.setStaggerIndex(cc.TiledMap.StaggerIndex.STAGGERINDEX_EVEN);
}
if (hexSideLengthStr) {
this.setHexSideLength(parseFloat(hexSideLengthStr));
}
let mapSize = cc.size(0, 0);
mapSize.width = parseFloat(map.getAttribute('width'));
mapSize.height = parseFloat(map.getAttribute('height'));
this.setMapSize(mapSize);
mapSize = cc.size(0, 0);
mapSize.width = parseFloat(map.getAttribute('tilewidth'));
mapSize.height = parseFloat(map.getAttribute('tileheight'));
this.setTileSize(mapSize);
// The parent element is the map
this.properties = getPropertyList(map);
}
// PARSE <tileset>
let tilesets = map.getElementsByTagName('tileset');
if (map.nodeName !== "map") {
tilesets = [];
tilesets.push(map);
}
for (i = 0; i < tilesets.length; i++) {
let selTileset = tilesets[i];
// If this is an external tileset then start parsing that
let tsxName = selTileset.getAttribute('source');
if (tsxName) {
let currentFirstGID = parseInt(selTileset.getAttribute('firstgid'));
let tsxXmlString = this._tsxMap[tsxName];
if (tsxXmlString) {
this.parseXMLString(tsxXmlString, currentFirstGID);
}
} else {
let images = selTileset.getElementsByTagName('image');
let multiTextures = images.length > 1;
let image = images[0];
let firstImageName = image.getAttribute('source');
firstImageName = firstImageName.replace(/\\/g, '\/');
let tiles = selTileset.getElementsByTagName('tile');
let tileCount = tiles && tiles.length || 1;
let tile = null;
let tilesetName = selTileset.getAttribute('name') || "";
let tilesetSpacing = parseInt(selTileset.getAttribute('spacing')) || 0;
let tilesetMargin = parseInt(selTileset.getAttribute('margin')) || 0;
let fgid = parseInt(tilesetFirstGid);
if (!fgid) {
fgid = parseInt(selTileset.getAttribute('firstgid')) || 0;
}
let tilesetSize = cc.size(0, 0);
tilesetSize.width = parseFloat(selTileset.getAttribute('tilewidth'));
tilesetSize.height = parseFloat(selTileset.getAttribute('tileheight'));
// parse tile offset
let offset = selTileset.getElementsByTagName('tileoffset')[0];
let tileOffset = cc.v2(0, 0);
if (offset) {
tileOffset.x = parseFloat(offset.getAttribute('x'));
tileOffset.y = parseFloat(offset.getAttribute('y'));
}
let tileset = null;
for (let tileIdx = 0; tileIdx < tileCount; tileIdx++) {
if (!tileset || multiTextures) {
tileset = new cc.TMXTilesetInfo();
tileset.name = tilesetName;
tileset.firstGid = fgid;
tileset.spacing = tilesetSpacing;
tileset.margin = tilesetMargin;
tileset._tileSize = tilesetSize;
tileset.tileOffset = tileOffset;
tileset.sourceImage = this._textures[firstImageName];
tileset.imageSize = this._textureSizes[firstImageName] || tileset.imageSize;
if (!tileset.sourceImage) {
cc.errorID(7221, firstImageName);
}
this.setTilesets(tileset);
}
tile = tiles && tiles[tileIdx];
if (!tile) continue;
this.parentGID = parseInt(fgid) + parseInt(tile.getAttribute('id') || 0);
let tileImages = tile.getElementsByTagName('image');
if (tileImages && tileImages.length > 0) {
image = tileImages[0];
let imageName = image.getAttribute('source');
imageName = imageName.replace(/\\/g, '\/');
tileset.sourceImage = this._textures[imageName];
if (!tileset.sourceImage) {
cc.errorID(7221, imageName);
}
let tileSize = cc.size(0, 0);
tileSize.width = parseFloat(image.getAttribute('width'));
tileSize.height = parseFloat(image.getAttribute('height'));
tileset._tileSize = tileSize;
tileset.firstGid = this.parentGID;
}
this._tileProperties[this.parentGID] = getPropertyList(tile);
let animations = tile.getElementsByTagName('animation');
if (animations && animations.length > 0) {
let animation = animations[0];
let framesData = animation.getElementsByTagName('frame');
let animationProp = {frames:[], dt:0, frameIdx:0};
this._tileAnimations[this.parentGID] = animationProp;
let frames = animationProp.frames;
for (let frameIdx = 0; frameIdx < framesData.length; frameIdx++) {
let frame = framesData[frameIdx];
let tileid = parseInt(fgid) + parseInt(frame.getAttribute('tileid'));
let duration = parseFloat(frame.getAttribute('duration'));
frames.push({tileid : tileid, duration : duration / 1000, grid: null});
}
}
let objectgroupXML = tile.getElementsByTagName('objectgroup');
if(objectgroupXML && objectgroupXML.length > 0){
let objectGroup = this._parseObjectGroup(objectgroupXML[0]);
this._tileObjectGroups[this.parentGID] = objectGroup;
}
}
}
}
// PARSE <layer> & <objectgroup> in order
let childNodes = map.childNodes;
for (i = 0; i < childNodes.length; i++) {
let childNode = childNodes[i];
if (this._shouldIgnoreNode(childNode)) {
continue;
}
if (childNode.nodeName === 'imagelayer') {
let imageLayer = this._parseImageLayer(childNode);
if (imageLayer) {
this.setImageLayers(imageLayer);
}
}
if (childNode.nodeName === 'layer') {
let layer = this._parseLayer(childNode);
this.setLayers(layer);
}
if (childNode.nodeName === 'objectgroup') {
let objectGroup = this._parseObjectGroup(childNode);
this.setObjectGroups(objectGroup);
}
}
return map;
}
cc.TMXMapInfo.prototype._parseObjectGroup = function(selGroup) {
let objectGroup = new cc.TMXObjectGroupInfo();
objectGroup.name = selGroup.getAttribute('name') || '';
objectGroup.offset = cc.v2(parseFloat(selGroup.getAttribute('offsetx')), parseFloat(selGroup.getAttribute('offsety')));
let opacity = selGroup.getAttribute('opacity') || 1;
if (opacity)
objectGroup._opacity = parseInt(255 * parseFloat(opacity));
else
objectGroup._opacity = 255;
let visible = selGroup.getAttribute('visible');
if (visible && parseInt(visible) === 0)
objectGroup.visible = false;
let color = selGroup.getAttribute('color');
if (color)
objectGroup._color.fromHEX(color);
let draworder = selGroup.getAttribute('draworder');
if (draworder)
objectGroup._draworder = draworder;
// set the properties to the group
objectGroup.setProperties(getPropertyList(selGroup));
let objects = selGroup.getElementsByTagName('object');
if (objects) {
for (let j = 0; j < objects.length; j++) {
let selObj = objects[j];
// The value for "type" was blank or not a valid class name
// Create an instance of TMXObjectInfo to store the object and its properties
let objectProp = {};
// Set the id of the object
objectProp['id'] = selObj.getAttribute('id') || j;
// Set the name of the object to the value for "name"
objectProp["name"] = selObj.getAttribute('name') || "";
// Assign all the attributes as key/name pairs in the properties dictionary
objectProp["width"] = parseFloat(selObj.getAttribute('width')) || 0;
objectProp["height"] = parseFloat(selObj.getAttribute('height')) || 0;
objectProp["x"] = parseFloat(selObj.getAttribute('x')) || 0;
objectProp["y"] = parseFloat(selObj.getAttribute('y')) || 0;
objectProp["rotation"] = parseFloat(selObj.getAttribute('rotation')) || 0;
objectProp["m_type"] = selObj.getAttribute('type') || "";
getPropertyList(selObj, objectProp);
// visible
let visibleAttr = selObj.getAttribute('visible');
objectProp['visible'] = !(visibleAttr && parseInt(visibleAttr) === 0);
// text
let texts = selObj.getElementsByTagName('text');
if (texts && texts.length > 0) {
let text = texts[0];
objectProp['type'] = cc.TiledMap.TMXObjectType.TEXT;
objectProp['wrap'] = text.getAttribute('wrap') == '1';
objectProp['color'] = strToColor(text.getAttribute('color'));
objectProp['halign'] = strToHAlign(text.getAttribute('halign'));
objectProp['valign'] = strToVAlign(text.getAttribute('valign'));
objectProp['pixelsize'] = parseInt(text.getAttribute('pixelsize')) || 16;
objectProp['text'] = text.childNodes[0].nodeValue;
}
// image
let gid = selObj.getAttribute('gid');
if (gid) {
objectProp['gid'] = parseInt(gid);
objectProp['type'] = cc.TiledMap.TMXObjectType.IMAGE;
}
// ellipse
let ellipse = selObj.getElementsByTagName('ellipse');
if (ellipse && ellipse.length > 0) {
objectProp['type'] = cc.TiledMap.TMXObjectType.ELLIPSE;
}
//polygon
let polygonProps = selObj.getElementsByTagName("polygon");
if (polygonProps && polygonProps.length > 0) {
objectProp['type'] = cc.TiledMap.TMXObjectType.POLYGON;
let selPgPointStr = polygonProps[0].getAttribute('points');
if (selPgPointStr)
objectProp["points"] = this._parsePointsString(selPgPointStr);
}
//polyline
let polylineProps = selObj.getElementsByTagName("polyline");
if (polylineProps && polylineProps.length > 0) {
objectProp['type'] = cc.TiledMap.TMXObjectType.POLYLINE;
let selPlPointStr = polylineProps[0].getAttribute('points');
if(this == undefined || this == null){
console.log(`App-> `,this);
}
if (selPlPointStr)
objectProp["polylinePoints"] = this._parsePointsString(selPlPointStr);
}
if (!objectProp['type']) {
objectProp['type'] = cc.TiledMap.TMXObjectType.RECT;
}
// Add the object to the objectGroup
objectGroup._objects.push(objectProp);
}
if (draworder !== 'index') {
objectGroup._objects.sort(function (a, b) {
return a.y - b.y;
});
}
}
return objectGroup;
}
使用: tiledMap.tileObjectGroups[gid] 获取碰撞数据
然后这个扩展 也添加了 获取 对象类型的变量
let objectGroup = tiledMap.getObjectGroup('对象图层')
let point = objectGroup.getObject('出生点');
point.m_type === '标记'

2赞
mark一下
3.8依然没有此功能@jare
2024.4.30
4年了还是没有
