DelayNoMore/frontend/assets/scripts/TileCollisionManagerSingleton.js

671 lines
27 KiB
JavaScript

"use strict";
window.ALL_DISCRETE_DIRECTIONS_CLOCKWISE = [{
dx: 0,
dy: 1
}, {
dx: 2,
dy: 1
}, {
dx: 2,
dy: 0
}, {
dx: 2,
dy: -1
}, {
dx: 0,
dy: -1
}, {
dx: -2,
dy: -1
}, {
dx: -2,
dy: 0
}, {
dx: -2,
dy: 1
}];
function TileCollisionManager() { }
TileCollisionManager.prototype._continuousFromCentreOfDiscreteTile = function (tiledMapNode, tiledMapIns, layerIns, discretePosX, discretePosY) {
var mapOrientation = tiledMapIns.getMapOrientation();
var mapTileRectilinearSize = tiledMapIns.getTileSize();
var mapAnchorOffset = cc.v2(0, 0);
var tileSize = {
width: 0,
height: 0
};
var layerOffset = cc.v2(0, 0);
switch (mapOrientation) {
case cc.TiledMap.Orientation.ORTHO:
return null;
case cc.TiledMap.Orientation.ISO:
var tileSizeUnifiedLength = Math.sqrt(mapTileRectilinearSize.width * mapTileRectilinearSize.width / 4 + mapTileRectilinearSize.height * mapTileRectilinearSize.height / 4);
tileSize = {
width: tileSizeUnifiedLength,
height: tileSizeUnifiedLength
};
var cosineThetaRadian = mapTileRectilinearSize.width / 2 / tileSizeUnifiedLength;
var sineThetaRadian = mapTileRectilinearSize.height / 2 / tileSizeUnifiedLength;
mapAnchorOffset = cc.v2(
tiledMapNode.getContentSize().width * (0.5 - tiledMapNode.getAnchorPoint().x),
tiledMapNode.getContentSize().height * (1 - tiledMapNode.getAnchorPoint().y)
);
layerOffset = cc.v2(0, 0);
var transMat = [
[cosineThetaRadian, -cosineThetaRadian],
[-sineThetaRadian, -sineThetaRadian]
];
var tmpContinuousX = (parseFloat(discretePosX) + 0.5) * tileSizeUnifiedLength;
var tmpContinuousY = (parseFloat(discretePosY) + 0.5) * tileSizeUnifiedLength;
var dContinuousXWrtMapNode = transMat[0][0] * tmpContinuousX + transMat[0][1] * tmpContinuousY;
var dContinuousYWrtMapNode = transMat[1][0] * tmpContinuousX + transMat[1][1] * tmpContinuousY;
return cc.v2(dContinuousXWrtMapNode, dContinuousYWrtMapNode).add(mapAnchorOffset);
default:
return null;
}
};
TileCollisionManager.prototype._continuousToDiscrete = function (tiledMapNode, tiledMapIns, continuousNewPosLocalToMap, continuousOldPosLocalToMap) {
/*
* References
* - http://cocos2d-x.org/docs/api-ref/creator/v1.5/classes/TiledMap.html
* - http://cocos2d-x.org/docs/api-ref/creator/v1.5/classes/TiledLayer.html
* - http://docs.mapeditor.org/en/stable/reference/tmx-map-format/?highlight=orientation#map
*/
var mapOrientation = tiledMapIns.getMapOrientation();
var mapTileRectilinearSize = tiledMapIns.getTileSize();
var mapAnchorOffset = {
x: 0,
y: 0
};
var tileSize = {
width: 0,
height: 0
};
var layerOffset = {
x: 0,
y: 0
};
var convertedContinuousOldXInTileCoordinates = null;
var convertedContinuousOldYInTileCoordinates = null;
var convertedContinuousNewXInTileCoordinates = null;
var convertedContinuousNewYInTileCoordinates = null;
var oldWholeMultipleX = 0;
var oldWholeMultipleY = 0;
var newWholeMultipleX = 0;
var newWholeMultipleY = 0;
var discretePosX = 0;
var discretePosY = 0;
var exactBorderX = 0;
var exactBorderY = 0; // These tmp variables are NOT NECESSARILY useful.
var oldTmpX = 0;
var oldTmpY = 0;
var newTmpX = 0;
var newTmpY = 0;
switch (mapOrientation) {
case cc.TiledMap.Orientation.ORTHO:
mapAnchorOffset = {
x: -(tiledMapNode.getContentSize().width * tiledMapNode.getAnchorPoint().x),
y: tiledMapNode.getContentSize().height * (1 - tiledMapNode.getAnchorPoint().y)
};
layerOffset = {
x: 0,
y: 0
};
tileSize = mapTileRectilinearSize;
convertedContinuousOldXInTileCoordinates = continuousOldPosLocalToMap.x - layerOffset.x - mapAnchorOffset.x;
convertedContinuousOldYInTileCoordinates = mapAnchorOffset.y - (continuousOldPosLocalToMap.y - layerOffset.y);
convertedContinuousNewXInTileCoordinates = continuousNewPosLocalToMap.x - layerOffset.x - mapAnchorOffset.x;
convertedContinuousNewYInTileCoordinates = mapAnchorOffset.y - (continuousNewPosLocalToMap.y - layerOffset.y);
break;
case cc.TiledMap.Orientation.ISO:
var tileSizeUnifiedLength = Math.sqrt(mapTileRectilinearSize.width * mapTileRectilinearSize.width / 4 + mapTileRectilinearSize.height * mapTileRectilinearSize.height / 4);
tileSize = {
width: tileSizeUnifiedLength,
height: tileSizeUnifiedLength
};
var cosineThetaRadian = mapTileRectilinearSize.width / 2 / tileSizeUnifiedLength;
var sineThetaRadian = mapTileRectilinearSize.height / 2 / tileSizeUnifiedLength;
mapAnchorOffset = {
x: tiledMapNode.getContentSize().width * (0.5 - tiledMapNode.getAnchorPoint().x),
y: tiledMapNode.getContentSize().height * (1 - tiledMapNode.getAnchorPoint().y)
};
layerOffset = {
x: 0,
y: 0
};
oldTmpX = continuousOldPosLocalToMap.x - layerOffset.x - mapAnchorOffset.x;
oldTmpY = continuousOldPosLocalToMap.y - layerOffset.y - mapAnchorOffset.y;
newTmpX = continuousNewPosLocalToMap.x - layerOffset.x - mapAnchorOffset.x;
newTmpY = continuousNewPosLocalToMap.y - layerOffset.y - mapAnchorOffset.y;
var transMat = [[1 / (2 * cosineThetaRadian), -1 / (2 * sineThetaRadian)], [-1 / (2 * cosineThetaRadian), -1 / (2 * sineThetaRadian)]];
convertedContinuousOldXInTileCoordinates = transMat[0][0] * oldTmpX + transMat[0][1] * oldTmpY;
convertedContinuousOldYInTileCoordinates = transMat[1][0] * oldTmpX + transMat[1][1] * oldTmpY;
convertedContinuousNewXInTileCoordinates = transMat[0][0] * newTmpX + transMat[0][1] * newTmpY;
convertedContinuousNewYInTileCoordinates = transMat[1][0] * newTmpX + transMat[1][1] * newTmpY;
break;
default:
break;
}
if (null == convertedContinuousOldXInTileCoordinates || null == convertedContinuousOldYInTileCoordinates || null == convertedContinuousNewXInTileCoordinates || null == convertedContinuousNewYInTileCoordinates) {
return null;
}
oldWholeMultipleX = Math.floor(convertedContinuousOldXInTileCoordinates / tileSize.width);
oldWholeMultipleY = Math.floor(convertedContinuousOldYInTileCoordinates / tileSize.height);
newWholeMultipleX = Math.floor(convertedContinuousNewXInTileCoordinates / tileSize.width);
newWholeMultipleY = Math.floor(convertedContinuousNewYInTileCoordinates / tileSize.height); // Mind that the calculation of `exactBorderY` is different for `convertedContinuousOldYInTileCoordinates <> convertedContinuousNewYInTileCoordinates`.
if (convertedContinuousOldYInTileCoordinates < convertedContinuousNewYInTileCoordinates) {
exactBorderY = newWholeMultipleY * tileSize.height;
if (convertedContinuousNewYInTileCoordinates > exactBorderY && convertedContinuousOldYInTileCoordinates <= exactBorderY) {
// Will try to cross the border if (newWholeMultipleY != oldWholeMultipleY).
discretePosY = newWholeMultipleY;
} else {
discretePosY = oldWholeMultipleY;
}
} else if (convertedContinuousOldYInTileCoordinates > convertedContinuousNewYInTileCoordinates) {
exactBorderY = oldWholeMultipleY * tileSize.height;
if (convertedContinuousNewYInTileCoordinates < exactBorderY && convertedContinuousOldYInTileCoordinates >= exactBorderY) {
// Will try to cross the border if (newWholeMultipleY != oldWholeMultipleY).
discretePosY = newWholeMultipleY;
} else {
discretePosY = oldWholeMultipleY;
}
} else {
discretePosY = oldWholeMultipleY;
} // Mind that the calculation of `exactBorderX` is different for `convertedContinuousOldXInTileCoordinates <> convertedContinuousNewXInTileCoordinates`.
if (convertedContinuousOldXInTileCoordinates < convertedContinuousNewXInTileCoordinates) {
exactBorderX = newWholeMultipleX * tileSize.width;
if (convertedContinuousNewXInTileCoordinates > exactBorderX && convertedContinuousOldXInTileCoordinates <= exactBorderX) {
// Will cross the border if (newWholeMultipleX != oldWholeMultipleX).
discretePosX = newWholeMultipleX;
} else {
discretePosX = oldWholeMultipleX;
}
} else if (convertedContinuousOldXInTileCoordinates > convertedContinuousNewXInTileCoordinates) {
exactBorderX = oldWholeMultipleX * tileSize.width;
if (convertedContinuousNewXInTileCoordinates < exactBorderX && convertedContinuousOldXInTileCoordinates >= exactBorderX) {
// Will cross the border if (newWholeMultipleX != oldWholeMultipleX).
discretePosX = newWholeMultipleX;
} else {
discretePosX = oldWholeMultipleX;
}
} else {
discretePosX = oldWholeMultipleX;
}
return {
x: discretePosX,
y: discretePosY
};
};
TileCollisionManager.prototype.continuousMapNodeVecToContinuousObjLayerVec = function (withTiledMapNode, continuousMapNodeVec) {
var tiledMapIns = withTiledMapNode.getComponent(cc.TiledMap);
var mapOrientation = tiledMapIns.getMapOrientation();
var mapTileRectilinearSize = tiledMapIns.getTileSize();
switch (mapOrientation) {
case cc.TiledMap.Orientation.ORTHO:
// TODO
return null;
case cc.TiledMap.Orientation.ISO:
var tileSizeUnifiedLength = Math.sqrt(mapTileRectilinearSize.width * mapTileRectilinearSize.width * 0.25 + mapTileRectilinearSize.height * mapTileRectilinearSize.height * 0.25);
var isometricObjectLayerPointOffsetScaleFactor = (tileSizeUnifiedLength / mapTileRectilinearSize.height);
var inverseIsometricObjectLayerPointOffsetScaleFactor = 1 / isometricObjectLayerPointOffsetScaleFactor;
var cosineThetaRadian = (mapTileRectilinearSize.width * 0.5) / tileSizeUnifiedLength;
var sineThetaRadian = (mapTileRectilinearSize.height * 0.5) / tileSizeUnifiedLength;
var inverseTransMat = [
[inverseIsometricObjectLayerPointOffsetScaleFactor * 0.5 * (1 / cosineThetaRadian), - inverseIsometricObjectLayerPointOffsetScaleFactor * 0.5 * (1 / sineThetaRadian)],
[- inverseIsometricObjectLayerPointOffsetScaleFactor * 0.5 * (1 / cosineThetaRadian), - inverseIsometricObjectLayerPointOffsetScaleFactor * 0.5 * (1 / sineThetaRadian)]
];
var convertedVecX = inverseTransMat[0][0] * continuousMapNodeVec.x + inverseTransMat[0][1] * continuousMapNodeVec.y;
var convertedVecY = inverseTransMat[1][0] * continuousMapNodeVec.x + inverseTransMat[1][1] * continuousMapNodeVec.y;
return cc.v2(convertedVecX, convertedVecY);
default:
return null;
}
}
TileCollisionManager.prototype.continuousObjLayerVecToContinuousMapNodeVec = function (withTiledMapNode, continuousObjLayerVec) {
var tiledMapIns = withTiledMapNode.getComponent(cc.TiledMap);
var mapOrientation = tiledMapIns.getMapOrientation();
var mapTileRectilinearSize = tiledMapIns.getTileSize();
switch (mapOrientation) {
case cc.TiledMap.Orientation.ORTHO:
// TODO
return null;
case cc.TiledMap.Orientation.ISO:
var tileSizeUnifiedLength = Math.sqrt(mapTileRectilinearSize.width * mapTileRectilinearSize.width * 0.25 + mapTileRectilinearSize.height * mapTileRectilinearSize.height * 0.25);
var isometricObjectLayerPointOffsetScaleFactor = (tileSizeUnifiedLength / mapTileRectilinearSize.height);
var cosineThetaRadian = (mapTileRectilinearSize.width * 0.5) / tileSizeUnifiedLength;
var sineThetaRadian = (mapTileRectilinearSize.height * 0.5) / tileSizeUnifiedLength;
var transMat = [
[isometricObjectLayerPointOffsetScaleFactor * cosineThetaRadian, - isometricObjectLayerPointOffsetScaleFactor * cosineThetaRadian],
[- isometricObjectLayerPointOffsetScaleFactor * sineThetaRadian, - isometricObjectLayerPointOffsetScaleFactor * sineThetaRadian]
];
var convertedVecX = transMat[0][0] * continuousObjLayerVec.x + transMat[0][1] * continuousObjLayerVec.y;
var convertedVecY = transMat[1][0] * continuousObjLayerVec.x + transMat[1][1] * continuousObjLayerVec.y;
return cc.v2(convertedVecX, convertedVecY);
default:
return null;
}
}
TileCollisionManager.prototype.continuousObjLayerOffsetToContinuousMapNodePos = function (withTiledMapNode, continuousObjLayerOffset) {
var tiledMapIns = withTiledMapNode.getComponent(cc.TiledMap);
var mapOrientation = tiledMapIns.getMapOrientation();
switch (mapOrientation) {
case cc.TiledMap.Orientation.ORTHO:
// TODO
return null;
case cc.TiledMap.Orientation.ISO:
const calibratedVec = continuousObjLayerOffset; // TODO: Respect the real offsets!
// The immediately following statement takes a magic assumption that the anchor of `withTiledMapNode` is (0.5, 0.5) which is NOT NECESSARILY true.
const layerOffset = cc.v2(0, +(withTiledMapNode.getContentSize().height * 0.5));
return layerOffset.add(this.continuousObjLayerVecToContinuousMapNodeVec(withTiledMapNode, calibratedVec));
default:
return null;
}
}
TileCollisionManager.prototype.continuousMapNodePosToContinuousObjLayerOffset = function (withTiledMapNode, continuousMapNodePos) {
var tiledMapIns = withTiledMapNode.getComponent(cc.TiledMap);
var mapOrientation = tiledMapIns.getMapOrientation();
var mapTileRectilinearSize = tiledMapIns.getTileSize();
switch (mapOrientation) {
case cc.TiledMap.Orientation.ORTHO:
// TODO
return null;
case cc.TiledMap.Orientation.ISO:
// The immediately following statement takes a magic assumption that the anchor of `withTiledMapNode` is (0.5, 0.5) which is NOT NECESSARILY true.
var layerOffset = cc.v2(0, +(withTiledMapNode.getContentSize().height * 0.5));
var calibratedVec = continuousMapNodePos.sub(layerOffset); // TODO: Respect the real offsets!
return this.continuousMapNodeVecToContinuousObjLayerVec(withTiledMapNode, calibratedVec);
default:
return null;
}
}
/**
* Note that `TileCollisionManager.extractBoundaryObjects` returns everything with coordinates local to `withTiledMapNode`!
*/
window.battleEntityTypeNameToGlobalGid = {};
TileCollisionManager.prototype.extractBoundaryObjects = function (withTiledMapNode) {
let toRet = {
barriers: [],
frameAnimations: [],
grandBoundaries: [],
};
const tiledMapIns = withTiledMapNode.getComponent(cc.TiledMap); // This is a magic name.
const mapTileSize = tiledMapIns.getTileSize();
const mapOrientation = tiledMapIns.getMapOrientation();
/*
* Copies from https://github.com/cocos-creator/engine/blob/master/cocos2d/tilemap/CCTiledMap.js as a hack to parse advanced <tile> info
* of a TSX file. [BEGINS]
*/
const file = tiledMapIns._tmxFile;
const texValues = file.textures;
const texKeys = file.textureNames;
const textures = {};
for (let texIdx = 0; texIdx < texValues.length; ++texIdx) {
textures[texKeys[texIdx]] = texValues[texIdx];
}
const tsxFileNames = file.tsxFileNames;
const tsxFiles = file.tsxFiles;
let tsxMap = {};
for (let tsxFilenameIdx = 0; tsxFilenameIdx < tsxFileNames.length; ++tsxFilenameIdx) {
if (0 >= tsxFileNames[tsxFilenameIdx].length) continue;
tsxMap[tsxFileNames[tsxFilenameIdx]] = tsxFiles[tsxFilenameIdx].text;
}
const mapInfo = new cc.TMXMapInfo(file.tmxXmlStr, tsxMap, textures);
const tileSets = mapInfo.getTilesets();
/*
* Copies from https://github.com/cocos-creator/engine/blob/master/cocos2d/tilemap/CCTiledMap.js as a hack to parse advanced <tile> info
* of a TSX file. [ENDS]
*/
let gidBoundariesMap = {};
const tilesElListUnderTilesets = {};
for (let tsxFilenameIdx = 0; tsxFilenameIdx < tsxFileNames.length; ++tsxFilenameIdx) {
const tsxOrientation = tileSets[tsxFilenameIdx].orientation;
if (cc.TiledMap.Orientation.ORTHO == tsxOrientation) {
cc.error("Error at tileset %s: We don't proceed with tilesets in ORTHO orientation by now.", tsxFileNames[tsxFilenameIdx]);
continue;
};
const tsxXMLStr = tsxMap[tsxFileNames[tsxFilenameIdx]];
const selTileset = mapInfo._parser._parseXML(tsxXMLStr).documentElement;
const firstGid = (parseInt(selTileset.getAttribute('firstgid')) || tileSets[tsxFilenameIdx].firstGid || 0);
const currentTiles = selTileset.getElementsByTagName('tile');
if (!currentTiles) continue;
tilesElListUnderTilesets[tsxFileNames[tsxFilenameIdx]] = currentTiles;
for (let tileIdx = 0; tileIdx < currentTiles.length; ++tileIdx) {
const currentTile = currentTiles[tileIdx];
const parentGid = parseInt(firstGid) + parseInt(currentTile.getAttribute('id') || 0);
let childrenOfCurrentTile = null;
if (cc.sys.isNative) {
childrenOfCurrentTile = currentTile.getElementsByTagName("objectgroup");
} else {
childrenOfCurrentTile = currentTile.children;
}
for (let childIdx = 0; childIdx < childrenOfCurrentTile.length; ++childIdx) {
const ch = childrenOfCurrentTile[childIdx];
if ('objectgroup' != ch.nodeName) continue;
var currentObjectGroupUnderTile = mapInfo._parseObjectGroup(ch);
gidBoundariesMap[parentGid] = {
barriers: [],
};
for (let oidx = 0; oidx < currentObjectGroupUnderTile._objects.length; ++oidx) {
const oo = currentObjectGroupUnderTile._objects[oidx];
const polylinePoints = oo.polylinePoints;
if (null == polylinePoints) continue;
const boundaryType = oo.boundary_type;
switch (boundaryType) {
case "LowScoreTreasure":
case "HighScoreTreasure":
case "GuardTower":
const spriteFrameInfoForGid = getOrCreateSpriteFrameForGid(parentGid, mapInfo, tilesElListUnderTilesets);
if (null != spriteFrameInfoForGid) {
window.battleEntityTypeNameToGlobalGid[boundaryType] = parentGid;
}
break;
case "barrier":
let brToPushTmp = [];
for (let bidx = 0; bidx < polylinePoints.length; ++bidx) {
brToPushTmp.push(cc.v2(oo.x, oo.y).add(polylinePoints[bidx]));
}
brToPushTmp.boundaryType = boundaryType;
gidBoundariesMap[parentGid].barriers.push(brToPushTmp);
break;
default:
break;
}
}
}
}
}
// Reference http://docs.cocos.com/creator/api/en/classes/TiledMap.html.
let allObjectGroups = tiledMapIns.getObjectGroups();
for (var i = 0; i < allObjectGroups.length; ++i) {
// Reference http://docs.cocos.com/creator/api/en/classes/TiledObjectGroup.html.
var objectGroup = allObjectGroups[i];
if ("frame_anim" != objectGroup.getProperty("type")) continue;
var allObjects = objectGroup.getObjects();
for (var j = 0; j < allObjects.length; ++j) {
var object = allObjects[j];
var gid = object.gid;
if (!gid || gid <= 0) {
continue;
}
var animationClipInfoForGid = getOrCreateAnimationClipForGid(gid, mapInfo, tilesElListUnderTilesets);
if (!animationClipInfoForGid) continue;
toRet.frameAnimations.push({
posInMapNode: this.continuousObjLayerOffsetToContinuousMapNodePos(withTiledMapNode, object.offset),
origSize: animationClipInfoForGid.origSize,
sizeInMapNode: cc.size(object.width, object.height),
animationClip: animationClipInfoForGid.animationClip
});
}
}
for (let i = 0; i < allObjectGroups.length; ++i) {
var objectGroup = allObjectGroups[i];
if ("barrier_and_shelter" != objectGroup.getProperty("type")) continue;
var allObjects = objectGroup.getObjects();
for (let j = 0; j < allObjects.length; ++j) {
let object = allObjects[j];
let gid = object.gid;
if (0 < gid) {
continue;
}
const polylinePoints = object.polylinePoints;
if (null == polylinePoints) {
continue
}
for (let k = 0; k < polylinePoints.length; ++k) {
/* Since CocosCreatorv2.1.3, the Y-coord of object polylines DIRECTLY DRAWN ON tmx with ISOMETRIC ORIENTATION is inverted. -- YFLu, 2019-11-01. */
polylinePoints[k].y = -polylinePoints[k].y;
}
const boundaryType = object.boundary_type;
switch (boundaryType) {
case "barrier":
let toPushBarriers = [];
for (let k = 0; k < polylinePoints.length; ++k) {
const tmp = object.offset.add(polylinePoints[k]);
toPushBarriers.push(this.continuousObjLayerOffsetToContinuousMapNodePos(withTiledMapNode, tmp));
}
if (null != object.debug_mark) {
console.log("Transformed ", polylinePoints, ", to ", toPushBarriers);
}
toPushBarriers.boundaryType = boundaryType;
toRet.barriers.push(toPushBarriers);
break;
default:
break;
}
}
}
const allLayers = tiledMapIns.getLayers();
let layerDOMTrees = [];
const mapDomTree = mapInfo._parser._parseXML(tiledMapIns.tmxAsset.tmxXmlStr).documentElement;
const mapDOMAllChildren = (mapDomTree.children);
for (let mdtIdx = 0; mdtIdx < mapDOMAllChildren.length; ++mdtIdx) {
const tmpCh = mapDOMAllChildren[mdtIdx];
if (mapInfo._shouldIgnoreNode(tmpCh)) {
continue;
}
if (tmpCh.nodeName != 'layer') {
continue;
}
layerDOMTrees.push(tmpCh);
}
for (let j = 0; j < allLayers.length; ++j) {
// TODO: Respect layer offset!
const currentTileLayer = allLayers[j];
const currentTileset = currentTileLayer.getTileSet();
if (!currentTileset) {
continue;
}
const currentLayerSize = currentTileLayer.getLayerSize();
const currentLayerTileSize = currentTileset._tileSize;
const firstGidInCurrentTileset = currentTileset.firstGid;
for (let discreteXInLayer = 0; discreteXInLayer < currentLayerSize.width; ++discreteXInLayer) {
for (let discreteYInLayer = 0; discreteYInLayer < currentLayerSize.height; ++discreteYInLayer) {
const currentGid = currentTileLayer.getTileGIDAt(discreteXInLayer, discreteYInLayer);
if (0 >= currentGid) continue;
const gidBoundaries = gidBoundariesMap[currentGid];
if (!gidBoundaries) continue;
switch (mapOrientation) {
case cc.TiledMap.Orientation.ORTHO:
// TODO
return toRet;
case cc.TiledMap.Orientation.ISO:
const centreOfAnchorTileInMapNode = this._continuousFromCentreOfDiscreteTile(withTiledMapNode, tiledMapIns, currentTileLayer, discreteXInLayer, discreteYInLayer);
const topLeftOfWholeTsxTileInMapNode = centreOfAnchorTileInMapNode.add(cc.v2(-0.5 * mapTileSize.width, currentLayerTileSize.height - 0.5 * mapTileSize.height));
for (let bidx = 0; bidx < gidBoundaries.barriers.length; ++bidx) {
const theBarrier = gidBoundaries.barriers[bidx]; // An array of cc.v2 points.
let brToPushTmp = [];
for (let tbidx = 0; tbidx < theBarrier.length; ++tbidx) {
brToPushTmp.push(topLeftOfWholeTsxTileInMapNode.add(cc.v2(theBarrier[tbidx].x, -theBarrier[tbidx].y /* Mind the reverse y-axis here. */)));
}
toRet.barriers.push(brToPushTmp);
}
continue;
default:
return toRet;
}
}
}
}
return toRet;
}
TileCollisionManager.prototype.isOutOfMapNode = function (tiledMapNode, continuousPosLocalToMap) {
var tiledMapIns = tiledMapNode.getComponent(cc.TiledMap); // This is a magic name.
var mapOrientation = tiledMapIns.getMapOrientation();
var mapTileRectilinearSize = tiledMapIns.getTileSize();
var mapContentSize = cc.size(tiledMapIns.getTileSize().width * tiledMapIns.getMapSize().width, tiledMapIns.getTileSize().height * tiledMapIns.getMapSize().height);
switch (mapOrientation) {
case cc.TiledMap.Orientation.ORTHO:
// TODO
return true;
case cc.TiledMap.Orientation.ISO:
var continuousObjLayerOffset = this.continuousMapNodePosToContinuousObjLayerOffset(tiledMapNode, continuousPosLocalToMap);
return 0 > continuousObjLayerOffset.x || 0 > continuousObjLayerOffset.y || mapContentSize.width < continuousObjLayerOffset.x || mapContentSize.height < continuousObjLayerOffset.y;
default:
return true;
}
return true;
};
TileCollisionManager.prototype.initMapNodeByTiledBoundaries = function(mapScriptIns, mapNode, extractedBoundaryObjs) {
// TODO: TO DEPRECATE!
const tiledMapIns = mapNode.getComponent(cc.TiledMap);
if (extractedBoundaryObjs.grandBoundaries) {
window.grandBoundary = [];
for (let boundaryObj of extractedBoundaryObjs.grandBoundaries) {
for (let p of boundaryObj) {
if (CC_DEBUG) {
const labelNode = new cc.Node();
labelNode.setPosition(p);
const label = labelNode.addComponent(cc.Label);
label.string = "GB_(" + p.x.toFixed(2) + ", " + p.y.toFixed(2) + ")";
safelyAddChild(mapNode, labelNode);
setLocalZOrder(labelNode, 999);
}
window.grandBoundary.push(p);
}
break;
}
}
mapScriptIns.dictOfTiledFrameAnimationList = {};
for (let frameAnim of extractedBoundaryObjs.frameAnimations) {
if (!frameAnim.type) {
cc.warn("should bind a type to the frameAnim object layer");
continue
}
const tiledMapIns = mapScriptIns.node.getComponent(cc.TiledMap);
let frameAnimInType = mapScriptIns.dictOfTiledFrameAnimationList[frameAnim.type];
if (!frameAnimInType) {
mapScriptIns.dictOfTiledFrameAnimationList[frameAnim.type] = [];
frameAnimInType = mapScriptIns.dictOfTiledFrameAnimationList[frameAnim.type];
}
const animNode = cc.instantiate(mapScriptIns.tiledAnimPrefab);
const anim = animNode.getComponent(cc.Animation);
animNode.setPosition(frameAnim.posInMapNode);
animNode.width = frameAnim.sizeInMapNode.width;
animNode.height = frameAnim.sizeInMapNode.height;
animNode.setScale(frameAnim.sizeInMapNode.width / frameAnim.origSize.width, frameAnim.sizeInMapNode.height / frameAnim.origSize.height);
animNode.opacity = 0;
animNode.setAnchorPoint(cc.v2(0.5, 0)); // A special requirement for "image-type Tiled object" by "CocosCreator v2.0.1".
safelyAddChild(mapScriptIns.node, animNode);
setLocalZOrder(animNode, 5);
anim.addClip(frameAnim.animationClip, "default");
anim.play("default");
frameAnimInType.push(animNode);
}
mapScriptIns.barrierColliders = [];
for (let boundaryObj of extractedBoundaryObjs.barriers) {
const newBarrier = cc.instantiate(mapScriptIns.polygonBoundaryBarrierPrefab);
const newBoundaryOffsetInMapNode = cc.v2(boundaryObj[0].x, boundaryObj[0].y);
newBarrier.setPosition(newBoundaryOffsetInMapNode);
newBarrier.setAnchorPoint(cc.v2(0, 0));
const newBarrierColliderIns = newBarrier.getComponent(cc.PolygonCollider);
newBarrierColliderIns.points = [];
for (let p of boundaryObj) {
newBarrierColliderIns.points.push(p.sub(newBoundaryOffsetInMapNode));
}
mapScriptIns.barrierColliders.push(newBarrierColliderIns);
mapScriptIns.node.addChild(newBarrier);
}
const allLayers = tiledMapIns.getLayers();
for (let layer of allLayers) {
const layerType = layer.getProperty("type");
switch (layerType) {
case "barrier_and_shelter":
setLocalZOrder(layer.node, 3);
break;
default:
break;
}
}
const allObjectGroups = tiledMapIns.getObjectGroups();
for (let objectGroup of allObjectGroups) {
const objectGroupType = objectGroup.getProperty("type");
switch (objectGroupType) {
case "barrier_and_shelter":
setLocalZOrder(objectGroup.node, 3);
break;
default:
break;
}
}
}
window.tileCollisionManager = new TileCollisionManager();