0

我正在创建一个游戏,我用它们的 id 的二维数组来表示盒子。

var grid =  [[X,X,X,X,X,X,X,X,X,X],
             [X,X,4,4,4,4,X,X,X,X],
             [X,3,3,3,3,X,X,X,X,X],
             [X,X,X,2,2,2,2,X,X,X],
             [X,1,1,1,1,5,5,5,5,5]];

盒子堆叠在一起,X 代表一个空白点。

如果其中一个框被删除,我希望上面的任何框(可以适合)向下移动。所以它们总是整齐地堆放着。

因此,如果我要删除 ID 为 1 的框,我会得到一个像这样的新网格:

var grid =  [[X,X,X,X,X,X,X,X,X,X],
             [X,X,4,4,4,4,X,X,X,X],
             [X,3,3,3,3,X,X,X,X,X],
             [X,X,X,2,2,2,2,X,X,X],
             [X,X,X,X,X,5,5,5,5,5]];

然后我希望 Box: 3 像这样滑入它的位置:

var grid =  [[X,X,X,X,X,X,X,X,X,X],
             [X,X,4,4,4,4,X,X,X,X],
             [X,X,X,X,X,X,X,X,X,X],
             [X,X,X,2,2,2,2,X,X,X],
             [X,3,3,3,3,5,5,5,5,5]];

最后 Box: 4 应该向下移动到 3 所在的位置:

var grid =  [[X,X,X,X,X,X,X,X,X,X],
             [X,X,X,X,X,X,X,X,X,X],
             [X,X,4,4,4,4,X,X,X,X],
             [X,X,X,2,2,2,2,X,X,X],
             [X,3,3,3,3,5,5,5,5,5]];

有没有一种简单的方法可以做到这一点?我正在考虑一个回调,当一个盒子被破坏时检查网格,但我想出的主要是 IF 语句。那里有优雅的东西吗?

盒子类本身也有起始位置和长度:

  box = {id:     3,
         start:  1,
         length: 4};
4

3 回答 3

1

这实际上不是一件容易的事。我创建了一个小小提琴,可以实现您想要实现的目标(我认为)。
我扩展了box prototype一些功能。我的解决方案依赖于变量gridand blocks,但如果您愿意,您可以进一步抽象它。
功能testFunctionalityprintGridToElement只是为了测试目的。

我的新盒子原型:

function Box(i, s, l) {
    this.id = i;
    this.start = s;
    this.length = l;
    this.row;
    blocks.push(this);
}
Box.prototype.insertIntoGrid = function (row) {
    this.row = row;
    if (!grid[row]) grid[row] = [];
    for (var i = 0; i < this.length; i++) {
        grid[row][this.start + i] = this.id;
    }
};
Box.prototype.destroy = function () {
    blocks.splice(blocks.indexOf(this), 1);
    this.removeFromGrid();
    this.checkRemainingBlocksForMoveDown();
};
Box.prototype.checkRemainingBlocksForMoveDown = function () {
    for (var i = 0; i < blocks.length; i++) {
        var btmd = blocks[i].checkForMoveDown();
        if (btmd) {
            btmd[0].move(btmd[1]);
            btmd[0].checkRemainingBlocksForMoveDown();
        }
    }
}
Box.prototype.move = function (row) {
    this.removeFromGrid();
    this.insertIntoGrid(row);
};
Box.prototype.removeFromGrid = function () {
    for (var i = 0; i < this.length; i++) {
        grid[this.row][this.start + i] = 0;
    }
};
Box.prototype.checkForMoveDown = function () {
    for (var i = 0; i < this.row; i++) {
        var move = true;
        for (var j = 0; j < this.length; j++) {
            if (grid[i][this.start + j] != 0) {
                move = false;
                break;
            }
        }
        if (move) {
            return [this, i];
        }
    }
};

以及它的用法:

var b1 = new Box(1, 1, 4);
b1.insertIntoGrid(0);
var b2 = new Box(2, 3, 4);
b2.insertIntoGrid(1);
var b3 = new Box(3, 1, 4);
b3.insertIntoGrid(2);
var b4 = new Box(4, 2, 4);
b4.insertIntoGrid(3);
var b5 = new Box(5, 5, 5);
b5.insertIntoGrid(0);
b1.destroy();
b2.destroy();
b3.destroy();

注意:我设计了网格,0 是最低行

于 2014-11-14T13:18:57.593 回答
1

我迟到了,但我来了。

您可能应该交换行和列。那就是让它像:

var rows = [];
column = [x,x,x,x,x,x,x,x];
rows.push(column);

代替:

var columns = [];
var row = [x,x,x,x,x,x,x,x];
columns.push(row);

这样一来,drop 只是对列的数组操作。然后,您可以执行诸如spliceout a block、splicein a block、unshiftshift等等之类的操作。

在动画之前执行数组操作,但不是在从网格中获取列和行信息之前。

您甚至可以通过数组方法命名执行此操作的方法。shift下降底部块,splice(start, stop, [optional]new block)。像那样。

@Markai 确实交换了答案中的列和行,但我想我会增加一些清晰度。

于 2015-02-06T22:33:26.393 回答
0

这就是我想出的(不工作,但要点)

fallCheck = function(deletedPosition, deletedLength) {
  var fallable = grid.reduce(
    function(array, row) {

    var unique = row.filter(function(item, i, ar) { return ar.indexOf(item) === i;});

    var id = unique.find( function(boxId) {
      var box = boxes.iterate("id", boxId, Phaser.Group.RETURN_CHILD);  //Finds the instance within a Phaser Group
      return (box.start >= deletedPosition) && (box.start + box.length) <= (deletedPosition + deletedLength);
    });

    if (id != -1) array.push(id);
  }, []);

  if (fallable.length > 0) { fall(fallable[0]); }  //fall simply moves the box to the lowest position on the grid

};
于 2014-11-15T11:30:03.880 回答