CocosCreator之KUOKUO分享-俄羅斯方塊

摘要

俄羅斯方塊小遊戲,TypeScript 語言,適合學習,已開源!

正文

使用版本

CocosCreator 版本 2.2.2

遊戲演示


一個月前就想做了,結果先鴿了半個月,16 天前完成 demo,後來又加入了方塊數據編輯場景。再後面幾天做了一些修改,加了一些註釋,今天才做了出來,大家千萬不要學我,要克服懶惰 O(∩_∩)O~

關係圖

首先我們看下腳本的關係圖:


寫些枚舉

枚舉的好處不再多說,我們先理一理俄羅斯方塊這個遊戲都需要些什麼枚舉。第一個是遊戲中方塊渲染,在 12 * 7 的格子中,每個格子應該有八種狀態,或者說是不渲染與七種顏色;第二個是觸摸事件,我們手指上下左右操作對應的事件名稱;第三個就是各種音效對應的枚舉;最後一個,是我爲了方便使用 cc.find 找到節點的路徑寫的枚舉。

enum.ts

/** 不渲染與7個顏色 */
export enum ItemColor {
    NULL = 0,
    Color1,
    Color2,
    Color3,
    Color4,
    Color5,
    Color6,
    Color7,
}

/** 觸摸事件-上下左右滑動 */
export enum TouchEvent {
    UP = 'touch-up',
    DOWN = 'touch-down',
    LEFT = 'touch-left',
    RIGHT = 'touch-right'
}

/** 音效事件 */
export enum MusicEvent {
    BGM = 'bgm',
    ACTION = 'action',
    GAME_OVER = 'over',
    /** 方塊消除 */
    ELIMINATE = 'eliminate'
}

/** 節點路徑 */
export enum NodeUrl {
    Canvas = 'Canvas',
    Music = 'Music'
}

render渲染模塊

遊戲主場景是 12 * 7 方格,這個渲染模塊就是通過一個 12 * 7 的數據數組對應,進行渲染。首先,將 12 * 7 個方格里面鋪滿帶圖片的節點(預製體 item 就是帶有精靈組件的一個節點,config 中存着一些常量):

init () {
    const height = config.row * config.blockHeight
    const width = config.col * config.blockWidth
    // 初始化所有節點
    for (let i = 0; i < config.row; i++) {
        this.itemArray[i] = []
        for (let j = 0; j < config.col; j++) {
            const x = -width / 2 + config.blockWidth / 2 + j * config.blockWidth
            const y = height / 2 - config.blockHeight / 2 - i * config.blockHeight
            const item = this.createItem(x, y)
            this.itemArray[i][j] = item
        }
    }
}

createItem (x: number, y: number): cc.Node {
    let item = cc.instantiate(this.item)
    this.node.addChild(item)
    item.setPosition(x, y)
    item.setContentSize(config.itemWidth, config.itemHeight)
    return item
}

render.ts 中的渲染函數,根據傳入數據進行圖片替換,不渲染時數組越界爲 undefined,取消掉紋理:

/** 根據傳入二維數組進行渲染 */
render (dataArray: ItemColor[][]) {
    for (let i = 0; i < config.row; i++) {
        for (let j = 0; j < config.col; j++) {
            const color = dataArray[i][j]
            // 拖入圖片的下標是 0-6,顏色枚舉對應 1-7
            this.itemArray[i][j].getComponent(cc.Sprite).spriteFrame = this.itemSpriteFrames[color - 1]
        }
    }
}

這樣渲染模塊的 render 函數只接受一個二維數組數據,主邏輯那邊只操作數據,最後調用下 render 即可!看下 render.ts 整體:

import { config } from "./config"
import { ItemColor } from "./enum"

const {ccclass, property} = cc._decorator

@ccclass
export default class Render extends cc.Component {

    @property(cc.Prefab)
    item: cc.Prefab = undefined

    @property([cc.SpriteFrame])
    itemSpriteFrames: cc.SpriteFrame[] = []

    /** 遊戲層上應該鋪滿節點,然後根據數據渲染 */
    itemArray: cc.Node[][] = []

    onLoad () {
        this.init()
    }

    init () {
        const height = config.row * config.blockHeight
        const width = config.col * config.blockWidth
        // 初始化所有節點
        for (let i = 0; i < config.row; i++) {
            this.itemArray[i] = []
            for (let j = 0; j < config.col; j++) {
                const x = -width / 2 + config.blockWidth / 2 + j * config.blockWidth
                const y = height / 2 - config.blockHeight / 2 - i * config.blockHeight
                const item = this.createItem(x, y)
                this.itemArray[i][j] = item
            }
        }
    }

    /** 根據傳入二維數組進行渲染 */
    render (dataArray: ItemColor[][]) {
        for (let i = 0; i < config.row; i++) {
            for (let j = 0; j < config.col; j++) {
                const color = dataArray[i][j]
                // 拖入圖片 0-6,顏色枚舉 1-7
                this.itemArray[i][j].getComponent(cc.Sprite).spriteFrame = this.itemSpriteFrames[color - 1]
            }
        }
    }

    createItem (x: number, y: number): cc.Node {
        let item = cc.instantiate(this.item)
        this.node.addChild(item)
        item.setPosition(x, y)
        item.setContentSize(config.itemWidth, config.itemHeight)
        return item
    }
}

邏輯數據處理

方塊的數據我是這樣規定的:

綠色那裏代表(0,0)位置,這樣有相對位置,方便處理數據,我就這樣定義了當前方塊的數據結構:

/** 當前形狀 */
currentShape: CurrentShapeData = {
    center: cc.v2(0, 0),
    index: 0,
    color: ItemColor.NULL
}

身爲程序員(懶人),必然得方便自己搞個編輯數據的場景(舉例:7形狀的數據就是上面圖片表格對應的一個數組)

我們在 main 主腳本維護一個二維數組數據:

/** 二維數組 */
dataArray: ItemColor[][] = []

這樣比如我們新添加一個形狀到遊戲裏,只要先獲取這個數組[cc.v2(-1, -1), cc.v2(-1, 0), cc.v2(0, 0), cc.v2(1, 0)],然後遍歷一次添加到 dataArray 最後走一次 render,方塊就出來了:

/** 根據當前中心點和形狀類型加入數據 */
setCurrentData (currentShape: CurrentShapeData) {
    const { center, color, index } = currentShape
    const shape = `shape${color}`
    const shapeData: cc.Vec2[][] = config[shape]
    shapeData[index].forEach(ele => {
        const row = center.x + ele.x
        const col = center.y + ele.y
        this.dataArray[row][col] = color
    })
    // 刷新視圖
    this.render()
}

好了,剩下的邏輯大家去 GitHub 上下載一波看一看吧,註釋還是蠻多的!

結語

源碼已經開源,喜歡的記得給點個 Star!

開源地址:https://github.com/KuoKuo666/CocosCreator-Tetris

O(∩_∩)O~~

微信公衆號

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