《Cocos Creator遊戲實戰》棋類遊戲中的棋子擺放邏輯

棋類遊戲中的棋子擺放邏輯

創建節點

代碼編寫


其實要點就一句話:我們看到的不應是棋盤,而是座標。

現在通過下面的五子棋(或圍棋)實例來看下如何理解這句話。

 

運行效果如下:

 

Cocos Creator版本:2.2.2

後臺回覆"",獲取該項目完整文件。

 

創建節點

1. bg爲Sprite類型節點,作爲場景背景。

2. board bg也是Sprite類型節點,作爲棋盤背景。

3. board雖然爲空節點,但是非常關鍵,因爲棋子都是添加到這個節點上的。它的大小應等於棋盤上可落子區域大小:

爲方便開發,我們可以將該節點的錨點設置爲(0, 0),那麼對棋子來說左下角就是座標原點了。

4. dot預製也會添加到board節點上。棋盤上有多少個點,就會有多少個預製。每個預製都會進行觸摸監聽,玩家點擊到哪個dot,那麼我們就在相應的dot位置上放一個棋子。

5. piece預製用來當做棋子。

 

代碼編寫

首先我們新建一個Board.js腳本,添加屬性並編寫onLoad方法內容:

// Board.js
properties: {
    piecePrefab: cc.Prefab,                  // 棋子預製
    touchDotPrefab: cc.Prefab                // 觸摸點預製
},

// LIFE-CYCLE CALLBACKS:

onLoad () {
    cc.debug.setDisplayStats(false);

    const hLines = 15;                       // 水平線數量
    const vLines = 15;                       // 垂直線數量
    this.blockWidth = (this.node.width / (vLines-1)).toFixed(2);     // 每塊區域的寬度
    this.blockHeight = (this.node.height / (hLines-1)).toFixed(2);   // 每塊區域的高度

    this.boardPosArray = [];                 // 棋盤上所有點的座標
    this.getBoardPos(hLines, vLines);       

    this.currentPlayer = 'BLACK';            // 當前着步方

    this.initTouchDots();                    // 添加所有觸摸點
},

1. hLines和vLines常量用來保存棋盤上的水平線和垂直線數量,五子棋(圍棋)的棋盤是一個正方形,所以橫豎線數量相等,都爲15。

2. 既然已經知道了可落子區域的總大小和橫豎線數量,那麼我們就可以求出每塊小區域的大小了。

3. boardPosArray數組用來存儲棋盤上各個點的座標。而獲取各個點的座標就在getBoardPos方法中:

// Board.js
getBoardPos(hLines, vLines) {          
    for (let i=0; i<hLines; i++) {
        for (let j=0; j<vLines; j++) {
            let x = j*this.blockWidth;
            let y = i*this.blockHeight;
            this.boardPosArray.push([x, y, '0']);
        }
    }
},

boardPosArray數組的每個元素包含一個x座標,一個y座標以及用來判斷當前位置是否存在棋子的標識,初始化時都是'0'。

4. currentPlayer變量用來存儲當前的着步方。

5. initTouches用來添加觸摸點,方法編寫如下:

// Board.js
initTouchDots() {
    for (let i=0; i<this.boardPosArray.length; i++) {
        let touchDot = cc.instantiate(this.touchDotPrefab);
        touchDot.opacity = 0;
        this.node.addChild(touchDot);
        touchDot.getComponent('TouchDot').initBoard(this);
        touchDot.setPosition(this.boardPosArray[i][0], this.boardPosArray[i][1])
    }
},

觸摸點是不能被看到的,所以透明度需要設爲0。筆者這裏給大家看下沒有設置爲透明時的樣子:

 

該預製上掛着的TouchDot.js腳本編寫如下:

// TouchDot.js
cc.Class({
    extends: cc.Component,

    properties: {
    },

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        this.node.on('touchstart', this.onTouchStart, this);
    },

    initBoard(board) {
        this.board = board;
    },

    onTouchStart() {
        this.board.putPiece(this.node.x, this.node.y);
    }
});

initBoard方法用於獲取Board.js腳本實例。在onTouchStart方法中我們調用Board.js中的putPiece方法直接將棋子放置到該觸摸點的位置。

 

putPiece方法編寫如下:

// Board.js
putPiece(x, y) {
    // 放置棋子,並更新着步方xx
    let is_ok = this.check(x.toFixed(2), y.toFixed(2));               
    if (!is_ok)
        return;

    let piece = cc.instantiate(this.piecePrefab);
    this.node.addChild(piece);
    piece.getComponent('Piece').setPic(this.currentPlayer);
    piece.width = this.blockWidth*0.9;
    piece.height = this.blockHeight*0.9;
    piece.setPosition(x, y)

    if (this.currentPlayer == 'BLACK') {
        this.currentPlayer = 'WHITE';
    }
    else {
        this.currentPlayer = 'BLACK';
    }
},

在該方法中,我們首先要調用check方法判斷當前位置是否已經有棋子了,如果沒有那麼就在該位置上放一個棋子,放置完畢則更改着步方。

 

check方法編寫如下:

// Board.js
check(x, y) {
    // 查看當前位置是否可以着步
    for (let i=0; i<this.boardPosArray.length; i++) {
        if (x==this.boardPosArray[i][0] && y==this.boardPosArray[i][1]){
            if (this.boardPosArray[i][2]=='0') {
                // 可以放置,並更新數組
                this.boardPosArray[i][2] = '1';
                return true;
            }
            else {
                // 已有棋子,不可放置
                return false;
            }
        }
    }
}

其實就是循環boardPosArray數組,判斷該位置上是'0'還是'1',如果是前者,那麼表明可以放置。

注:筆者這裏的判斷只是給大家進行簡單進行演示,並不一定符合下棋規則。比如圍棋中的某個空位落子後會直接沒"氣"(也就是說該空位已經被圍死了),那麼也不能在這個空位上落子對吧。

 

棋子預製上掛着的Piece.js腳本編寫如下:

// Piece.js
cc.Class({
    extends: cc.Component,

    properties: {
        blackPic: cc.SpriteFrame,
        whitePic: cc.SpriteFrame
    },

    // LIFE-CYCLE CALLBACKS:

    onLoad () {},

    setPic(currentPlayer) {
        if (currentPlayer=='BLACK') {
            this.node.getComponent(cc.Sprite).spriteFrame = this.blackPic;
        }
        else if (currentPlayer=='WHITE') {
            this.node.getComponent(cc.Sprite).spriteFrame = this.whitePic;
        }
    }
});

blackPic和whitePic就是黑白棋子圖片,而setPic方法會根據當前的着步方來設置相應的棋子圖片。

 

好,那本節教程就到這,希望大家有所收穫~

P.S. 雖然筆者這裏用的是五子棋(或圍棋)這個例子,但是開發邏輯同樣適用於其他棋類,比如象棋。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章