2012年12月3日 星期一

(遊戲試做) - 消方塊遊戲

沒試過做這種類型的遊戲,但身邊有人想做那就來想一下遊戲運作機制是如何。

流程應該是如下

1.產生全場景的隨機方塊
2.根據玩家所移動的方塊去運算是否消除自身及週遭的方塊
3.產生新的方塊
4.運算新的方塊及因消除而移位的方塊是否消除自身及週遭的方塊
5.重覆2-4

※注:本雛形不含圖形及輸入處理,純粹只是運作機制的試做。
C#雛形


將方塊建成class

class GameBox {
    public int posX; //X軸位置
    public int posY; //Y軸位置
    public int boxType; //方塊型別

    public GameBox (int positionX, int positionY, int setType) {
        this.posX = positionX;
        this.posY = positionY;
        this.boxType = setType;
    }
}

GameBox[][] gameBoxs = new GameBox[9][9]; //本例以9*9為例
ArrayList changedBoxs = new ArrayList(); //用來記錄有更動過的方塊
ArrayList eliminateBoxs = new ArrayList(); // 記錄待消滅的方塊

//新建9*9方塊矩陣
void BuildPuzzle () {
    for(int x = 0; x < 9; x++)
    {
        for(int y = 0; y < 9; y++)
        {
            gameBoxs[x][y] = new GameBox(x, y, Random.Range(0, 7)); //方塊型別為隨機0-7
        }
    }
}

//將有更動過的方塊記錄,並且檢查是否能消除,不能消除則歸位。
//輸入端傳入移動的兩點位置
void ChangeBoxPosition (Vector2 fromPosition, Vector2 toPosition) {
    GameBox tempBox = new GameBox();
    if(!changedBoxs.Contains(gameBoxs[fromPosition.x][fromPosition.y]))
    {
        changedBoxs.Add(gameBoxs[fromPosition.x][fromPosition.y]);
    }
    gameBoxs[fromPosition.x][fromPosition.y].posX = toPosition.X;
    gameBoxs[fromPosition.x][fromPosition.y].posY = toPosition.Y;
    tempBox = gameBoxs[fromPosition.x][fromPosition.y];
    gameBoxs[fromPosition.x][fromPosition.y] = gameBoxs[toPosition.x][toPosition.y];

    if(!changedBoxs.Contains(gameBoxs[toPosition.x][toPosition.y]))
    {
        changedBoxs.Add(gameBoxs[toPosition.x][toPosition.y]);
    }
    gameBoxs[toPosition.x][toPosition.y].posX = fromPosition.x;
    gameBoxs[toPosition.x][toPosition.y].posY = fromPosition.y;
    gameBoxs[toPosition.x][toPosition.y] = tempBox;

    if(CanEliminateBox())
    {
        EliminateBox();
    }
    else //無法消除方塊,將方塊位置恢復。
    {
        tempBox = gameBoxs[fromPosition.x][fromPosition.y];
        gameBoxs[fromPosition.x][fromPosition.y] = gameBoxs[toPosition.x][toPosition.y];
        gameBoxs[fromPosition.x][fromPosition.y].posX = fromPosition.X;
        gameBoxs[fromPosition.x][fromPosition.y].posY = fromPosition.Y;

        gameBoxs[toPosition.x][toPosition.y] = tempBox;

        gameBoxs[toPosition.x][toPosition.y].posX = toPosition.x;
        gameBoxs[toPosition.x][toPosition.y].posY = toPosition.y;

    }
}

//檢查是否有可消除的方塊,除用於消除方塊外也用於是否還原更動方塊的位置
bool CanEliminateBox () {
    bool canEliminate = false;
    foreach(GameBox box in changedBoxs)
    {
        int left = IsSameTypeBoxLeft(box);
        int right = IsSameTypeBoxRight(box);
        if(left + right > 2)
        {
            for(int x = box.posX - left; x < box.posX + right; x++)
            {
                if(!eliminateBoxs.Contains(gameBoxs[x][box.posY]))
                {
                    eliminateBoxs.Add(gameBoxs[x][box.posY]);
                }
            }
            canEliminate = true;
        }
        int up = IsSameTypeBoxUp(box);
        int down = IsSameTypeBoxDown(box);
        if(up + down > 2)
        {
            for(int y = box.posY - up; y < box.posY + down; y++)
            {
                if(!eliminateBoxs.Contains(gameBoxs[box.posX][y]))
                {
                    eliminateBoxs.Add(gameBoxs[box.posX][y]);
                }
            }
            canEliminate = true;
        }
    }
    changedBoxs.Clear();
    return canEliminate;
}

int IsSameTypeBoxLeft (GameBox startBox) {
    if(startBox.posX > 0 && gameBoxs[startBox.posX - 1][startBox.posY].boxType == startBox.boxType)
    {
        return IsSameTypeBoxLeft(gameBoxs[startBox.posX - 1][startBox.posY]) + 1;
    }
    else
    {
        return 0;
    }
}

int IsSameTypeBoxRight (GameBox startBox) {
    if(startBox.posX < 8 && gameBoxs[startBox.posX + 1][startBox.posY].boxType == startBox.boxType)
    {
        return IsSameTypeBoxRight(gameBoxs[startBox.posX + 1][startBox.posY]) + 1;
    }
    else
    {
        return 0;
    }
}

int IsSameTypeBoxUp (GameBox startBox) {
    if(startBox.posY > 0 && gameBoxs[startBox.posX][startBox.posY - 1].boxType == startBox.boxType)
    {
        return IsSameTypeBoxUp(gameBoxs[startBox.posX][startBox.posY - 1]) + 1;
    }
    else
    {
        return 0;
    }
}

int IsSameTypeBoxDown (GameBox startBox) {
    if(startBox.posY < 8 && gameBoxs[startBox.posX][startBox.posY + 1].boxType == startBox.boxType)
    {
        return IsSameTypeBoxDown(gameBoxs[startBox.posX][startBox.posY + 1]) + 1;
    }
    else
    {
        return 0;
    }
}

//消除可消除的方塊,並且讓方塊往下掉且在上方產生新方塊,最後再檢查是否有可消除的方塊。
void EliminateBox () {
    foreach(GameBox eliminate in eliminateBoxs)
    {
        for(int y = eliminate.posY - 1; y >= 0; y--)
        {
            gameBoxs[eliminate.posX][y + 1] = gameBoxs[eliminate.posX][y];
            gameBoxs[eliminate.posX][y + 1].posY += 1;
            if(!changedBoxs.Contains(gameBoxs[eliminate.posX][y + 1]))
            {
                changedBoxs.Add(gameBoxs[eliminate.posX][y + 1]);
            }
        }
        gameBoxs[eliminate.posX][0] = new GameBox(eliminate.posX, 0, Random.Range(0, 7));
        if(!changedBoxs.Contains(gameBoxs[eliminate.posX][0]))
        {
            changedBoxs.Add(gameBoxs[eliminate.posX][0]);
        }
    }
    eliminateBoxs.Clear();
    if(CanEliminateBox())
    {
        EliminateBox();
    }
}

沒有留言:

張貼留言