顺序地移除2D阵列中的位置';s的行和列,从中心开始

本文关键字:开始 2D 阵列 顺序 位置 | 更新日期: 2023-09-27 18:30:04

我的Bejewelded克隆中出现了另一个问题。我想让星星宝石像在《宝石3》中那样,意味着它们会从星星宝石(中心)向外摧毁宝石。因此,假设这颗恒星宝石在10x10 2D阵列中位于(4,4);它将首先摧毁位置(3,4)、(5,4),(4,3)和(4,5),然后,例如,10帧之后,摧毁(2,4)(6,4)和(4,2),以及(4,6),依此类推

现在,我有了StarDestruction()方法,将星形宝石的位置存储到几个Board范围变量中,并在List<Gem>中销毁位置,如下所示:

Board.starPosX = i;
Board.starPosY = j;
for (int x = 0; x < gems.GetLength(0); x++)
{
    moveTimer = 0;
    int k = x;
    int m = x;
    int q = x;
    int n = x;
    if (i - k < 0) k = 0;
    if (i + m > gems.GetLength(0) - 1) m = 0;
    if (j - q < 0) q = 0;
    if (j + n > gems.GetLength(1) - 1) n = 0;
    gemQ.Add(gems[i - k, j]);
    gemQ.Add(gems[i + m, j]);
    gemQ.Add(gems[i, j - q]);
    gemQ.Add(gems[i, j + n]);
}

其中CCD_ 3是CCD_。

这就是我目前在Update():中销毁宝石的方式

foreach (Gem g in gemQ)
{
    if (timer2 % 12 == 0)
        g.KillGem(gems[starPosX, starPosY]);
}

其中CCD_ 6是用于销毁宝石的定时器。

我有一个更简单的代码来处理原始的gem销毁,但它的工作方式似乎与这个版本没有任何不同。这是一个更简单的代码:

for (int x = 0; x < gems.GetLength(0); x++)
{
    if (x != i)
    {
        gems[x, j].KillGem(gems[i, j]);
    }
    if (x != j)
    {
        gems[i, x].KillGem(gems[i, j]);
    }
}

有什么想法吗?

顺序地移除2D阵列中的位置';s的行和列,从中心开始

根据我们在评论中的对话,完成我的回复编辑。

我现在明白了:

你希望星星宝石摧毁与星星宝石在同一列和同一行的所有其他宝石。你想一次销毁四颗宝石,每四颗之间有一个延迟。爆炸应该从恒星宝石向外移动,即首先摧毁最近的宝石。

你的前臂像这样使用时间:

Timer % 12 == 0

当时,一颗宝石也是如此,通常所有宝石都是如此。你也不想在破坏之间拖延,否则破坏不会被渲染,或者游戏会明显滞后。

第二个问题是,即使你把宝石的破坏间隔开,你也可能会发现破坏是螺旋式的,而不是一次四次。

考虑到这几点,你需要这样做:

// The initial destroy gem code
var gemsToDestroy = new List<Gem>();
for (int x = 0; x < gems.GetLength(0); x++)
{
    if (x != i)
    {
        gemsToDestroy.add(gems[x, j]);
    }
    if (x != j)
    {
        gemsToDestroy.add(gems[i, x]);
    }
}
// You can change your for loop above to achieve this directly, but this is the idea
// We are putting them in order of closest first.
gemsToDestroy = gemsToDestroy.OrderBy(o => o.DistanceFromStar).ToList();
// Your periodic UPDATE code - This is pseudo code but should convey the general idea
// I've been very lazy with my use of LINQ here, you should refactor this solution to 
// to remove as many iterations of the list as possible.
if (gemsToDestroy.Any() && timer.Ready)
{
    var closestDistance = gemsToDestroy[0].DistanceFromStar;
    foreach (var gem in gemsToDestroy.Where(gem => gem.DistanceFromStar == closestDistance))
    {
        gem.Destroy();
    }
    // Again you can do this without LINQ, point is I've removed the now destroyed gems from the list
    gemsToDestroy = gemsToDestroy.Where(gem => gem.DistanceFromStar != closestDistance).ToList();
    timer.Reset(); // So that we wait X time before destroying the next set
}

当gemsToDestroy列表中有物品时,不要忘记阻止玩家输入,并且在销毁时停止游戏计时器,这样玩家就不会因为玩得好而受到惩罚。