iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0

第三篇:棋類遊戲-立體四子棋

大綱

  • 遊戲內容
  • 創建角色
  • 控制箭頭
  • 放置棋子
  • 顯示結果
  • 尋找連線

成果預覽

這是一個雙人對戰遊戲
可以利用左右鍵控制箭頭下棋
每次下棋只能選擇欄
選後會落下至作最上方
只要四個連線即為贏得遊戲

點擊上圖可以進入遊戲頁面

創建角色

這次會有三個角色

  • 棋盤本人
  • 棋子狀態
  • 箭頭
    棋盤
let checkerboard = sprites.create(img`
    ........................
    ........................
    .8..8..8..8..8..8..8..8.
    .8.88.88.88.88.88.88.88.
    .8..8..8..8..8..8..8..8.
    .8.88.88.88.88.88.88.88.
    .8..8..8..8..8..8..8..8.
    .8.88.88.88.88.88.88.88.
    .8..8..8..8..8..8..8..8.
    .8.88.88.88.88.88.88.88.
    .8..8..8..8..8..8..8..8.
    .8.88.88.88.88.88.88.88.
    .8..8..8..8..8..8..8..8.
    .8.88.88.88.88.88.88.88.
    888888888888888888888888
    8......................8
`, SpriteKind.Player)
checkerboard.setScale(5, ScaleAnchor.Middle)

然後是棋子
因為棋子的部份我們要用圖片的方式顯示
為了可以跟棋盤重疊
所以我們設定都要跟棋盤一樣

let bord = sprites.create(img`
    16*24
`, SpriteKind.Player)
bord.setScale(5, ScaleAnchor.Middle)

箭頭的部分很簡單就直接宣告就行

let arrow = sprites.create(img`
    . . . . . . .
    . . . 2 . . .
    . . . 2 . . .
    . . . 2 . . .
    . . . 2 . . .
    . 2 2 2 2 2 .
    . . 2 2 2 . .
    . . . 2 . . .
    . . . . . . .
`, SpriteKind.Player)

然後我將箭頭放置在棋盤的第一欄上方

arrow.setPosition(37, 20)

控制箭頭

我們總共有七欄 要讓箭頭左右移動
ㄟ! 這聽起來很像上次同化遊戲的選顏色
沒錯!
所以我們就拿上次的程式碼來改就好

let now_number = 0
controller.right.onEvent(ControllerButtonEvent.Pressed, function () {
    now_number = (now_number + 1) % 7
})
controller.left.onEvent(ControllerButtonEvent.Pressed, function () {
    if (now_number == 0) {
        now_number = 7;
    }
    now_number -= 1;
})

然後是要讓箭頭移動
我們可以想成 他從我初次設定的地方(37, 20)
數字多少就移動多少像素(15)
然後再放進去就好

let now_number = 0
controller.right.onEvent(ControllerButtonEvent.Pressed, function () {
    now_number = (now_number + 1) % 7
    arrow.setPosition(37 + (now_number * 15), 20)
})
controller.left.onEvent(ControllerButtonEvent.Pressed, function () {
    if (now_number == 0) {
        now_number = 7;
    }
    now_number -= 1;
    arrow.setPosition(37 + (now_number * 15), 20)
})

放置棋子

我們要做一個儲存棋盤的地方
方便我們之後要用

let Data = [
[" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "]
]

有棋盤了 接下來就是下棋了
因為我們的規則是放到指定行會往下掉
掉到頂端
所以我們思考的方式就是我們要從下面搜尋
找到最下面的" "

function play(location:number) {
    for (let i = 5; i > -1; i--) {
        if (Data[i][location] == " ") {
            ...
        }
    }
}

然後我要把最下面的那格換成其他記號 我這邊以O X

let tuen = "O"
let row:number
function put(location:number) {
    for (let i = 5; i > -1; i--) {
        if (Data[i][location] == " ") {
            Data[i][location] = turn
            row = i
            break
        }
    }
}

這邊先順便拿個row 之後會用到
到此為止 下棋的部分就算告一落了

顯示結果

下完棋後要顯示出來
這邊我用的方法是讓背景自己改變
改變角色圖片上一次也用過

function show_board() {
    let bord_img = image.create(24, 16) // 製造一個空畫板
    for (let R = 0; R < 6; R++) {
        for (let C = 0; C < 7; C++) {// 依序讀取資料
            if (Data[R][C] != " ") {//如果那格有資料
                let color
                if (Data[R][C] == "O") {
                    color = 2
                } else {
                    color = 5
                }
                //將棋子畫上去
                bord_img.setPixel(C * 3 + 3, R * 2+2, color)
                bord_img.setPixel(C * 3 + 2, R * 2+2, color)
                bord_img.setPixel(C * 3 + 2, R * 2+3, color)
            }
        }
    }
    bord.setImage(bord_img) // 改變圖片
}

我怎麼知道他連線了

最後就是判斷連線了
我們的想法就是以我這次下棋的地方為中心
然後往外找是否連線
以橫向來看

function check_end(location: number, row: number) {
    // 檢查橫向
    // 左向
    let count = 0
    for (let i = 0; i < 4 && (location + i < 7); i++) {
        if (Data[row][location + i] != turn) {
            break
        }
        count += 1
    }
    console.log(count)
    // 右向
    for (let i = 0; i < 4 && (location - i > -1); i++) {
        if (Data[row][location - i] != turn) {
            break
        }
        count += 1
    }
    if (count > 4) {
        return true
    }
    ...

橫向就是左向加右向
剩下的直 斜 向因為篇幅 所以我沒放進來
請自行到我的遊戲頁面看程式碼


基礎架構以完畢 最後就是依序呼叫

controller.A.onEvent(ControllerButtonEvent.Pressed, function () {
    put(now_number)
    show_board()
    let is_end = check_end(now_number, row))
    if (is_end){
        game.showLongText(`${turn}win`, DialogLayout.Bottom)
        game.over(false) 
    }
    if(turn == "O"){
        turn = "X"
    }else{
        turn = "O"
    }
})

下期預告

各種棋篇-黑白棋


上一篇
Arcade再進化 - 虛擬鍵盤的妙用(3)
下一篇
Arcade再進化-射擊遊戲(3)
系列文
玩game學打code。街機程式設計再進化。微軟Arcade30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言