无限tilemap实现基于ccc

无限tilemap实现基于ccc


源码版本是2.09r5
我这边 主要是实际需要 实现 先 cok一样的无限大地图, 方法很简单
comp.testArray – (这个是我自己项目需要的一个列表 里面 放了 我需要显示的tile节点)
关键在于边界的处理 比如你的地图是 30x30 那么 超过 30或者 低于 0 怎么显示 很简单,比如 (0,31)就是把(0,0)移动到0,31的位置就行了,所以我们地图设计 师需要 收尾可以无缝结合的, comp.testArray 这个列表的选择可以比屏幕大一些,具体需要什么 自己结合游戏逻辑
if(comp.testArray){
for (const key in comp.testArray) {
let col = key%10000;
let row = Math.floor(key/10000);
let index = row*cols + col;
//let index = colOffset + col;
let flippedX = false, flippedY = false;

            let tiledTile = tiledTiles[index];
            if (tiledTile) {
                gid = tiledTile.gid;
            }
            else {
                gid = comp._tiles[index];
            }
            
            grid = grids[(gid & FLIPPED_MASK) >>> 0];
            let isok = true;
            if (!grid) {
                isok = false;
                return;
            }
            if(isok){
                switch (layerOrientation) {
                    case Orientation.ORTHO:
                        left = col * maptw;
                        bottom = (rows - row - 1) * mapth;
                        break;
                    case Orientation.ISO:
                        let tcol = col;
                        let trow = row;
                        // 这里是我的一个设定 row存放的时候 *10000其实 你用字符串就行了
                        if(comp.testArray){
                            let pos = comp.testArray[col + row * 10000];
                            //这里就是实际的tile位置 你们 可以对比下源码 改动很小
                            if(pos){
                                tcol = pos.x;
                                trow = pos.y;
                            }
                        } 
                         
                        left = maptw / 2 * ( cols + tcol - trow - 1);
                        bottom = mapth / 2 * ( rows * 2 - tcol - trow - 2);
                        break;
                    case Orientation.HEX:
                        let diffX2 = (axis === StaggerAxis.STAGGERAXIS_Y && row % 2 === 1) ? (maptw / 2 * odd_even) : 0;
                        left = col * (maptw - diffX1) + diffX2 + tileOffset.x;
                        let diffY2 = (axis === StaggerAxis.STAGGERAXIS_X && col % 2 === 1) ? (mapth/2 * -odd_even) : 0;
                        bottom = (rows - row - 1) * (mapth -diffY1) + diffY2 - tileOffset.y;
                        break;
                }

                if (tiledTile) {
                    let tiledNode = tiledTile.node;

                    // use tiled tile properties

                    // color
                    color2 = color;
                    let newOpacity = (tiledNode.opacity * opacity) / 255;
                    color = tiledNode.color.setA(newOpacity)._val;

                    // transform
                    a2 = a; b2 = b; c2 = c; d2 = d; tx2 = tx; ty2 = ty;
                    tiledNode._updateLocalMatrix();
                    mat4.copy(_mat4_temp, tiledNode._matrix);
                    vec3.set(_vec3_temp, -left, -bottom, 0);
                    mat4.translate(_mat4_temp, _mat4_temp, _vec3_temp);
                    mat4.multiply(_mat4_temp, node._worldMatrix, _mat4_temp);
                    a = _mat4_temp.m00; b = _mat4_temp.m01; c = _mat4_temp.m04; d = _mat4_temp.m05;
                    tx = _mat4_temp.m12; ty = _mat4_temp.m13;
                }

                right = left + tilew;
                top = bottom + tileh;

                // TMX_ORIENTATION_ISO trim
                //这段是 源代码 对 剪裁的优化 因为我已经自己剪裁了 所以就不需要了
                /*
                if (enabledCulling && layerOrientation === Orientation.ISO) {
                    gb = cullingMapy + bottom*cullingD;
                    if (gb > winh+cullingH) {
                        col += Math.floor((gb-winh)*2/cullingH) - 1;
                        isok = false;
                        return;
                    }
                    gr = cullingMapx + right*cullingA;
                    if (gr < -cullingW) {
                        col += Math.floor((-gr)*2/cullingW) - 1;
                        isok = false;
                        return;
                    }
                    gl = cullingMapx + left*cullingA;
                    gt = cullingMapy + top*cullingD;
                    if (gl > winw || gt < 0) {
                        col = maxCol;
                        isok = false;
                        return;
                    }
                }
                */
                if(isok){
                // Rotation and Flip
                if (gid > TileFlag.DIAGONAL) {
                    flippedX = (gid & TileFlag.HORIZONTAL) >>> 0;
                    flippedY = (gid & TileFlag.VERTICAL) >>> 0;
                }

                renderData.vertexCount += 4;
                renderData.indiceCount += 6;
                renderData.dataLength = renderData.vertexCount;

                // tl
                data[dataOffset].x = left * a + top * c + tx;
                data[dataOffset].y = left * b + top * d + ty;
                data[dataOffset].u = flippedX ? grid.r : grid.l;
                data[dataOffset].v = flippedY ? grid.b : grid.t;
                data[dataOffset].color = color;
                dataOffset++;

                // bl
                data[dataOffset].x = left * a + bottom * c + tx;
                data[dataOffset].y = left * b + bottom * d + ty;
                data[dataOffset].u = flippedX ? grid.r : grid.l;
                data[dataOffset].v = flippedY ? grid.t : grid.b;
                data[dataOffset].color = color;
                dataOffset++;

                // tr
                data[dataOffset].x = right * a + top * c + tx;
                data[dataOffset].y = right * b + top * d + ty;
                data[dataOffset].u = flippedX ? grid.l : grid.r;
                data[dataOffset].v = flippedY ? grid.b : grid.t;
                data[dataOffset].color = color;
                dataOffset++;

                // br
                data[dataOffset].x = right * a + bottom * c + tx;
                data[dataOffset].y = right * b + bottom * d + ty;
                data[dataOffset].u = flippedX ? grid.l : grid.r;
                data[dataOffset].v = flippedY ? grid.t : grid.b;
                data[dataOffset].color = color;
                dataOffset++;

                    if (tiledTile) {
                        color = color2;
                        a = a2; b = b2; c = c2; d = d2; tx = tx2; ty = ty2;
                    }
                }

            }
        }
    }

这个是实现的源码 位置在 tmx-layer-assembler.js这个文件
http://www.mikework.cn:8080/tilemap/
实际效果
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Unity Tilemap无限地图是一种可以在游戏场景中无限扩展的地图系统。它使用Unity的Tilemap功能来实现地图的绘制和渲染。 通常地图在游戏中是有固定大小的,但是有时我们需要一个可以无限扩展的地图,比如RPG游戏中的开放世界。Unity Tilemap无限地图就是为这种情况设计的。 实现无限地图的关键在于动态加载和卸载地图块。首先,我们需要定义一个地图块的大小,并在初始加载时生成一块可见的地图。随着玩家的移动,当玩家接近地图边缘时,我们会动态加载相邻的地图块。当玩家离开一块地图块时,我们会将其卸载,以节省资源。 为了实现无缝地图的切换,我们可以在地图块的边缘使用平滑过渡,使得相邻的地图块之间没有明显的分界线。这需要在地图块的绘制中使用一些技巧,比如重复边缘纹理和使用自动渲染器。 另外,为了提高性能和节省资源,我们可以使用一些优化技术。比如,只激活当前可见范围内的地图块,禁用其他不可见的地图块。还可以使用对象池来重用地图块,避免频繁的创建和销毁。 总之,Unity Tilemap无限地图是一种可以在游戏中实现无限扩展的地图系统。通过动态加载和卸载地图块,平滑过渡以及一些优化技术,我们可以实现无缝的游戏世界。这为开发者提供了更大的自由度,并且能够创建更加开放和富有探索性的游戏体验。 ### 回答2: Unity的Tilemap组件可以用来创建无限地图。通过Tilemap的瓦片系统,我们可以轻松地布置和编辑地图的瓷砖。 要创建无限地图,我们可以使用Tilemap的动态加载和卸载瓷砖的功能。通过这个功能,我们可以在摄像机视野之外加载地图的瓦片,而当它们超出视野范围时,可以自动卸载不再需要的瓷砖。这种方式能够保持地图一直呈现在摄像机视野内,从而实现无限地图的效果。 具体实现上,我们可以创建一个地图生成器的脚本来动态加载和卸载地图瓷砖。该脚本可以根据玩家的位置和行动来动态加载附近的瓷砖,并卸载离开视野范围的瓷砖。这样一来,无论玩家移动到哪里,都可以看到无限延伸的地图。 为了优化加载和卸载的性能,我们还可以实现一个对象池来管理地图瓷砖的加载和卸载。对象池可以预先加载一定数量的瓷砖,并在需要时直接从池中取出,而不是每次都去实例化和销毁瓷砖。 总而言之,Unity的Tilemap组件可以帮助我们创建无限地图。通过使用动态加载和卸载瓷砖的功能,以及合理的优化策略,我们可以实现一个看似无限延伸的地图,并为玩家提供更加丰富和无限的游戏体验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值