代码之家  ›  专栏  ›  技术社区  ›  TheTechy

从多维数组为HTML5平铺图生成冲突对象

  •  0
  • TheTechy  · 技术社区  · 6 年前

    我正在创建一个HTML5平台游戏,使用对象进行碰撞检测,并使用2d平铺贴图渲染级别。这一切都在起作用。

    Level map rendered

    我想使用相同的2d数组动态构建对象数组,以允许玩家根据需要构建地图,同时也便于首先创建地图。当硬编码对象数组时,一切都正常,所以我知道碰撞检测和游戏引擎正常工作。

    虽然我可以为每个单独的数组元素创建对象,但我希望根据数组中匹配元素的数量构建具有宽度的对象(每个元素为25x25),即如果3个数组元素为1,1,1,则对象的宽度将为75。也许一些代码可以帮助解释:

    以下平铺阵列

    var arr1 = [
        [0,0,0,1,1,1,1,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,2,2,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [3,3,3,0,0,0,0,0,0,0]
    ];
    

    应生成以下对象数组:

    [
        {x: 75, y: 0, width: 100, height: 25, value: 1},
        {x: 75, y: 50, width: 50, height: 25, value: 2},
        {x: 0, y: 100, width: 75, height: 25, value: 3}
    ]
    

    但它却产生了以下结果:

    [
        {x: 75, y: 0, width: 25, height: 25, value: 1},
        {x: 100, y: 0, width: 25, height: 25, value: 1},
        {x: 125, y: 0, width: 25, height: 25, value: 1}
    ]
    

    我的逻辑显然是错误的,但我一生都无法理解。

    示例代码如下:

    非常感谢您的帮助:

    var tmpObj = {};
    var objArr = [];
    var arr1 = [
        [0,0,0,1,1,1,1,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,2,2,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [3,3,3,0,0,0,0,0,0,0]
    ];
    
    for (let i=0; i<arr1.length; i++) {
        for (let j=0; j<arr1[i].length; j++) {
            if (arr1[i][j] > 0 && arr1[i][j] < 6) { // platform blocks only 1 - 5
                if (tmpObj.x === undefined) {
                    tmpObj = {
                        x: j * 25,
                        y: i * 25,
                        width: 25,
                        height: 25,
                        value: arr1[i][j]
                    }
                } else if (arr1[i][j] == arr1[i][j-1] && arr1[i][j] == tmpObj.v) {
                    tmpObj.w += 25;
                } else if (arr1[i][j] !== tmpObj.v) { // new tile type
                    objArr.push(tmpObj);
                    tmpObj = {
                        x: j * 25,
                        y: i * 25,
                        width: 25,
                        height: 25,
                        value: arr1[i][j]
                    }
                } else {
                    objArr.push(tmpObj);
                    tmpObj = {};
                }
            }
        }
    }
    console.log(objArr);
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Blindman67    6 年前

    看看您正在尝试做什么,您的实现太复杂了。而不是寻找bug(为此,我会使用devTools并逐行遍历代码以找到问题所在)我使用while循环重写了该函数,以查找连接的瓷砖的宽度。

    我随意使用对象属性名称,但我相信您可以根据需要更改它。

    const objArr = [];
    const arr1 = [
        [0,0,0,1,1,1,1,0,1,0],
        [2,0,0,0,0,0,0,0,0,3],
        [0,0,0,4,4,0,4,4,4,4],
        [0,0,0,0,0,0,0,0,0,0],
        [3,3,3,5,5,4,0,0,0,0]
    ];
    const tileSize = 25;
    
    for (let i = 0; i < arr1.length; i++) {
        const row = arr1[i]
        for (let j = 0; j < row.length; j++) {
            if (row[j] > 0 && row[j] < 6) {
                let count = j + 1;
                while (count < row.length && row[count] === row[j]) { count += 1 }
                objArr.push({
                    x: j * tileSize,
                    y: i * tileSize,
                    w: tileSize * (count - j),
                    h: tileSize,
                    tile: row[j]
                });
                j = count - 1;
            }
        }
    }
    
    // show results
    objArr.forEach(log);
    
    
    
    
    
    
    
    
    
    // unrelated to answer. (I hate the console SO has for snippets.)
    function log(data){
        show.appendChild(
            Object.assign(
                document.createElement("div"), {
                    textContent : 
                         Object.keys(data).reduce((str, key) => {
                              return str + (" " + key+ ": " + data[key]).padEnd(8,".");
                              }, ""
                         )
                   }
             )
       );
    }                     
    <code id="show"></code>