slg 细分篇 --------- 无限地图原理

先上几张图


我的文档水平现在也就这样了…:sweat:

那这里 牵涉到了 1个问题
tile的位置,和具体需要哪些tie来填充你的屏幕

那我们先来看看官方截屏算法

_updateViewPort(x, y, width, height) {
if (this._viewPort.width === width &&
this._viewPort.height === height &&
this._viewPort.x === x &&
this._viewPort.y === y) {
return;
}
this._viewPort.x = x;
this._viewPort.y = y;
this._viewPort.width = width;
this._viewPort.height = height;

    // if map's type is iso, reserve bottom line is 2 to avoid show empty grid because of iso grid arithmetic
    let reserveLine = 1;
    if (this._layerOrientation === cc.TiledMap.Orientation.ISO) {
        reserveLine = 2;
    }
    let vpx = this._viewPort.x - this._offset.x + this._leftDownToCenterX;
    let vpy = this._viewPort.y - this._offset.y + this._leftDownToCenterY;
    let leftDownX = vpx - this._leftOffset;
    let leftDownY = vpy - this._downOffset;
    let rightTopX = vpx + width + this._rightOffset;
    let rightTopY = vpy + height + this._topOffset;
    let leftDown = this._cullingRect.leftDown;
    let rightTop = this._cullingRect.rightTop;
    if (leftDownX < 0) leftDownX = 0;
    if (leftDownY < 0) leftDownY = 0;
    // calc left down
    this._positionToRowCol(leftDownX, leftDownY, _tempRowCol);
    // make range large
    _tempRowCol.row -= reserveLine;
    _tempRowCol.col -= reserveLine;
    // insure left down row col greater than 0
    _tempRowCol.row = _tempRowCol.row > 0 ? _tempRowCol.row : 0;
    _tempRowCol.col = _tempRowCol.col > 0 ? _tempRowCol.col : 0;
    if (_tempRowCol.row !== leftDown.row || _tempRowCol.col !== leftDown.col) {
        leftDown.row = _tempRowCol.row;
        leftDown.col = _tempRowCol.col;
        this._cullingDirty = true;
    }
    // show nothing
    if (rightTopX < 0 || rightTopY < 0) {
        _tempRowCol.row = -1;
        _tempRowCol.col = -1;
    } else {
        // calc right top
        this._positionToRowCol(rightTopX, rightTopY, _tempRowCol);
        // make range large
        _tempRowCol.row++;
        _tempRowCol.col++;
    }
    // avoid range out of max rect
    if (_tempRowCol.row > this._rightTop.row) _tempRowCol.row = this._rightTop.row;
    if (_tempRowCol.col > this._rightTop.col) _tempRowCol.col = this._rightTop.col;
    if (_tempRowCol.row !== rightTop.row || _tempRowCol.col !== rightTop.col) {
        rightTop.row = _tempRowCol.row;
        rightTop.col = _tempRowCol.col;
        this._cullingDirty = true;
    }
},

我的算法

    let camera = this.mapCamera;
    //临时
    //centerP = centerP.add(cc.v2(0, 667));
    let width = cc.game.canvas.width / cc.view._scaleX;
    let height = cc.game.canvas.height / cc.view._scaleY;
    let screenRect = new cc.Rect(0, 0, width, height);
    let screenArray = [];
    screenArray.push(cc.v2(0, 0));
    screenArray.push(cc.v2(0, height));
    screenArray.push(cc.v2(width, height));
    screenArray.push(cc.v2(width, 0));
    let worldArray = [];
    screenArray.forEach((sp) => {
        let p = camera.MyScreenToWorld(sp);
        worldArray.push(p.add(cc.v2(-width / 2, -height / 2)));
    })
    let xMin = null;
    let yMin = null;
    let xMax = null;
    let yMax = null;
    worldArray.forEach((p) => {
        if (xMin === null || p.x < xMin) {
            xMin = p.x;
        }
        if (yMin === null || p.y < yMin) {
            yMin = p.y;
        }
        if (xMax === null || p.x > xMax) {
            xMax = p.x;
        }
        if (yMax === null || p.y > yMax) {
            yMax = p.y;
        }
    });
    let mapConfig = this.getMapConfigData();
    let startP = cc.v2(xMin, yMax)
        .add(cc.v2(mapConfig.size.width / 2, mapConfig.size.height / 2))
        .add(cc.v2(-mapConfig.mapTileSize.width / 2, mapConfig.mapTileSize.height / 2));
    let endP = cc.v2(xMax, yMin)
        .add(cc.v2(mapConfig.size.width / 2, mapConfig.size.height / 2))
        .add(cc.v2(mapConfig.mapTileSize.width / 2, -mapConfig.mapTileSize.height / 2));
    let x = startP.x;
    let y = startP.y;
    let maxRow = mapConfig.layerSize.height;
    let maxCol = mapConfig.layerSize.width;
    let array = [];
    let r = 0;
    while (x != null && y != null) {
        if (x > endP.x) {
            y = y - mapConfig.mapTileSize.height / 2;
            if (y < endP.y) {
                break;
            } else {
                r++;
                x = startP.x + r % 2 * mapConfig.mapTileSize.width / 2;
            }
        } else {
            x = x + mapConfig.mapTileSize.width;
        }
        let p = cc.v2(x, y);
        let tileP = this.convertPosToTile(p);
        let tilex = tileP.x % maxCol;
        let tiley = tileP.y % maxRow;
        if (tilex < 0) {
            tilex += maxCol;
        }
        if (tiley < 0) {
            tiley += maxRow;
        }
        let tileData = {
            tilePos: cc.v2(tilex, tiley),
            realTilePos: tileP,
        }
        array.push(tileData);
    }
    for (let i = 0; i < mapConfig.tileLayers.length; i++) {
        let tileLayer = mapConfig.tileLayers[i];
        tileLayer.needTileArray = array;
    }

原理都是一样

灵魂作图

这样 你可以得到一个列表(列表里是每个tile的位置), 另外就是每个tile的位置计算问题了

计算 公式…

回归分部

具体源码 都有 你自己去demo 看看 就好

2赞

最后一句话才是重点:joy:

先插个眼:kissing_heart: