標籤:指令碼 顯示 func 邏輯 點擊 mes get 目標 else
先來說下要實現的功能
- 根據一定規則產生關卡
- 實現消除等邏輯
- 遊戲結束檢測
- 本機快取遊戲進度
準備工作
建好工程,使用編輯器搭建遊戲情境。我搭建的情境如:
簡單說明下:
- New Sprite是情境中的背景圖片
- StarRoot是一個空節點,後面建立的星星方塊都會加到這個節點上
- ActionRoot是一些做動作、動畫節點的父節點,像comb特效就在這個節點上
- UIRoot,就是使用者介面上的根節點,像遊戲的最高分、當前分數、當前第幾關等等,都放在這個節點上
- ResultRoot是結算介面的根節點。顯示灰色是因為沒有啟用這個節點
- SoundCTL也是一個空節點,主要作用是在節點上掛載一個指令碼處理遊戲的聲音
製作星星預製
方法參考官方文檔
很簡單,根節點下只有一個精靈節點。顯示藍色就表示是一個預製。主要說一下star上的指令碼組件starCtr.js
因為不止一種星星,所以需要改變New Sprite的紋理。星星有下面幾個屬性:
properties: { _starType: 0, _gx: 0, _gy: 0, starSprite: cc.Sprite, starSpriteFrames: { default: [], type: cc.SpriteFrame, },},
starSprite對應New Sprite的Sprite組件;starSpriteFrames儲存了所有星星的紋理;_starType表示星星的類別,它決定了starSprite顯示starSpriteFrames中的哪個紋理;_gx、_gy用來儲存星星方塊在10x10地圖中的格子座標。
initStar (type, gx, gy) { this._starType = type; this.starSprite.spriteFrame = this.starSpriteFrames[this._starType]; this.updateGrid(gx, gy);},updateGrid (gx, gy) { this._gx = gx; this._gy = gy;},
initStar星星的初始化函數,updateGrid用來更新星星的座標位置
在預製裡還做了一個操作,就是處理使用者的點擊操作,所以在指令碼的start函數裡監聽觸摸。start是組件指令碼生命週期的回呼函數,會在組件第一次啟用前,也就是第一次執行update之前觸發。
start () { this.node.on(cc.Node.EventType.TOUCH_START, function (event) { //TODO:觸摸處理 }, this);},
具體的觸摸處理後面說。最後看下屬性偵測器裡的指令碼組件:
產生關卡資料
- 建置規則:每個格子隨機產生星星。(這裡選取一個簡單的邏輯規則,自己可以根據實際情況修改星星產生的邏輯)
- 用一個二維數組儲存10×10的地圖資料
下面介紹兩個對象,分別建立兩個指令碼gamedata.js、Utils.js
gamedata處理遊戲的資料,像遊戲的得分、當前第幾關、地圖資料等等都儲存在裡面。
// gamedata.jsvar level = 0; //記錄當前關卡var targetScore = 0; //當前關卡目標分數var currScore = 0; //當前得分var bestScore = 0; //曆史最高得分var starMatrix = null; //地圖資料,二維數組var starSprite = []; //一維數組,儲存星星的Nodemodule.exports = { level: level, targetScore: targetScore, currScore: currScore, bestScore: bestScore, starMatrix: starMatrix, starSprite: starSprite,};
Utils主要是處理一些公用的邏輯,像關卡建置規則的邏輯就放這裡了。
// Utils.jsvar Config = require("psconfig");var randomColorByArray = function (array) { var i = Math.floor(Math.random() * array.length); return array[i];}//隨機產生星星關卡邏輯function initMatrixDataPortraitRandom () { var matrixData = new Array(Config.matrixRow); for(var row = 0; row < Config.matrixRow; row++) { matrixData[row] = new Array(Config.matrixCol); for(var col = 0; col < Config.matrixCol; col++) { matrixData[row][col] = randomColorByArray(Config.totalColors); } } return matrixData;};module.exports = { initMatrixDataPortraitRandom: initMatrixDataPortraitRandom,};
指令碼Utils.js載入了另一個指令碼psconfig.js,它主要存放遊戲的一些配置,代碼如下:
//psconfig.jsvar cellSize = 73; //星星紋理的邊長var matrixRow = 10; //地圖的行數(高)var matrixCol = 10; //地圖的列數(寬)var totalColors = [0,1,2,3,4]; //表示五種星星module.exports = { cellSize: cellSize, matrixRow: matrixRow, matrixCol: matrixCol, totalColors: totalColors,};
到這裡,關卡資料已經產生,下面就是根據產生的資料繪製星星地圖。
繪製星星
一開始提到,建立的所有星星都會放在StarRoot的節點上。情境中StarRoot是一個空節點,有一個指令碼組件matrixCtr,看:
單個格子邊長73,格子間有2個像素的縫隙,所以StarRoot是邊長748的正方形,把它的錨點設定在左下角,為了方便格子座標和像素位置座標之間的轉換。
在Utils指令碼上添加兩個函數用於座標之間的轉換。
//Utils.jsfunction grid2Pos (gx, gy) { var px = Config.cellSize * 0.5 + (Config.cellSize + 2) * gy; var py = Config.cellSize * 0.5 + (Config.cellSize + 2) * gx; return cc.v2(px, py);};function pos2Grid (px, py) { var gx = (py - Config.cellSize * 0.5) / (Config.cellSize + 2); var gy = (px - Config.cellSize * 0.5) / (Config.cellSize + 2); return cc.v2(Math.round(gx), Math.round(gy));};
最後別忘了匯出,在module.exports中添加變數:
module.exports = { grid2Pos: grid2Pos, pos2Grid: pos2Grid, initMatrixDataPortraitRandom: initMatrixDataPortraitRandom,};
下面說一下指令碼matrixCtr.js
中可以看到,指令碼中有兩個預製類型的屬性star、particle,其中star就是開始製作的星星預製。particle主要是播放粒子,是星星消除時的特效。
properties: { starPrefab: cc.Prefab, starParticle: cc.Prefab, _starPool: null, uiCtr: cc.Node, actCtr: cc.Node, combCtr: cc.Node, soundCtr: cc.Node,},
因為遊戲中要頻繁建立和銷毀星星,而這些操作是非常耗費效能的,所以這裡使用了對象池。關於它的介紹和使用方法參考官方文檔。
//matrixCtr.jsvar Utils = require("Utils");var Config = require("psconfig");var GameData = require("gamedata");onLoad () { //初始化對象池 this._starPool = new cc.NodePool(); for(var i = 0; i < Config.matrixCol*Config.matrixRow; ++i) { var star = cc.instantiate(this.starPrefab); this._starPool.put(star); }}onDestroy () { this._starPool.clear();},createStar (type, gx, gy) { var star = null; if (this._starPool.size() > 0) { star = this._starPool.get(); } else { star = cc.instantiate(this.starPrefab); } star.setPosition(Utils.grid2Pos(gx, gy)); this.node.addChild(star); var starCtr = star.getComponent("starCtr"); starCtr.initStar(type, gx, gy); return star},
注意,這裡省略了cc.Class等一些通用代碼,有了createStar函數,我們就可以根據前面產生的資料來繪製星星了。
// matrixCtr.jsinitMatrix () { for(var row = 0; row < GameData.starMatrix.length; row++) { var cols = GameData.starMatrix[row]; for(var col = 0; col < cols.length; col++) { var type = cols[col]; var index = Utils.indexValue(row, col); if (type >= 0) { var node = this.createStar(type, row, col); GameData.starSprite[index] = node; } else { GameData.starSprite[index] = null; } } }},
initMatrix函數中使用了Utils指令碼中的indexValue函數。這是因為儲存星星資料的是二維數組,儲存星星Node的是一維數組,它是兩者索引的轉換。當然,儲存星星Node也可以使用二維數組。
//Utils.jsfunction indexValue (row, col) { return row * Config.matrixCol + col;};function resolveIndex (index) { var col = index % Config.matrixCol; var row = (index - col) / Config.matrixCol; return cc.v2(row, col);};
別忘了在module.exports中匯出變數,這裡就省略了,最後上一張。
寫在最後歡迎訂閱,擷取更多內容,掌握最新動向
如有疑問,歡迎添加討論(驗證:雞毛信)
幾個約定
- 不提供源碼下載
- 文章會至少包含90%的源碼,對60%的源碼有說明
- 如轉載文章,請務必註明
Cocos Creator開發遊戲消滅星星——星星產生