聯網對戰遊戲開源例項分享之《鬥獸棋》
本次,Matchvs為大家帶來的是一款回合制休閒遊戲的開源案例 。玩家雙方在一個4X4的棋盤上,遵循食物鏈的規則玩法下進行翻牌與追逐,最終以場上存活的一方為獲勝者。
ofollow,noindex">體驗地址>>
首先你需要下載Cocos Creator 和Matchvs JavaScript SDK。本次遊戲設計的實現步驟主要拆分為使用者登入、隨機匹配和建立房間、以及同屏遊戲三個部分完成。
使用者登入
使用Cocos Creator(以下簡稱CC)建立遊戲登入場景
使用CC 拖動控制元件, 還原設計稿 , 依託CC的良好的工作流,使得這部分的工作可以由遊戲策劃或者UI設計者來完成,程式開發者只需要在場景中掛載相應的遊戲邏輯指令碼. 舉個例子,在登入按鈕掛在一個 uiLogin.js
的指令碼完成使用者登入功能.
uilogin.fire
新建一個uiLogin.js,按 1,2,3 三個步驟掛載到場景中.
-
新建js指令碼檔案
-
選中場景任一控制元件
-
新增元件,選中剛新建的指令碼,
在指令碼的 on'Load
函式中給按鈕新增點選監聽,觸發登入操作
onLoad() { this.nodeDict["start"].on("click", Game.GameManager.matchVsInit, Game.GameManager); }複製程式碼
實現 this.startGame
函式. 登入之前需要初始化 Matchvs SDK
:
uiLogin.js
uiLogin.js --- var uiPanel = require("uiPanel"); cc.Class({ extends: uiPanel, properties: {}, onLoad() { this._super(); }, start() { if (window.wx) { this.nodeDict["start"].active = false; wx.getSystemInfo({ success: function(data) { Game.GameManager.getUserInfoBtn = wx.createUserInfoButton({ type: 'text', text: '開始多人遊戲', style: { left: data.screenWidth * 0.2, top: data.screenHeight * 0.73, width: data.screenWidth * 0.65, height: data.screenHeight * 0.07, lineHeight: data.screenHeight * 0.07, backgroundColor: '#fe714a', color: '#ffffff', textAlign: 'center', fontSize: data.screenHeight * 0.025, borderRadius: 8 } }); Game.GameManager.getUserInfoBtn.onTap(function(res) { if (Game.GameManager.isClickCd) { return; } Game.GameManager.isClickCd = true; setTimeout(function() { Game.GameManager.isClickCd = false; }, 1000); Game.GameManager.nickName = res.userInfo.nickName; Game.GameManager.avatarUrl = res.userInfo.avatarUrl; Game.GameManager.matchVsInit(); Game.GameManager.getUserInfoBtn.hide(); }); } }); } else { this.nodeDict["start"].on("click", Game.GameManager.matchVsInit, Game.GameManager); } }, onEnable() { if (Game.GameManager.getUserInfoBtn) { Game.GameManager.getUserInfoBtn.show(); } }, onDisable() { if (Game.GameManager.getUserInfoBtn) { Game.GameManager.getUserInfoBtn.hide(); } } }); 複製程式碼
初始化需要的幾個引數在Matchvs官網註冊即可得到.
//Glb.js //-------- channel: 'MatchVS', platform: 'alpha', gameId: 201554, gameVersion: 1, appKey: 'd4e29d00bd3a48e2acf4f6e7a5ffe270', secret: 'f0f7bd601d9f43db840091ac08a17002',複製程式碼
開始遊戲,跳轉場景uiGamePanel:
startGame: function() { console.log('-----startGame-----') if(this.isLoadGame) return; this.isLoadGame = true; this.readyCnt = 0; cc.director.loadScene('game', function() { clientEvent.dispatch(clientEvent.eventType.clearChess); uiFunc.openUI("uiGamePanel", function(panel) { panel.getComponent("uiGamePanel").timeLabelInit(); this.sendReadyMsg(); }.bind(this)); }.bind(this)); }, 複製程式碼
隨機匹配和建立房間
使用CC建立大廳場景(uiLobbyPanel.fire)給使用者選擇匹配方式,建立匹配場景(uiMatching1v1.fire) 給使用者反饋比配進度,與登入功能的實現步驟類似:寫一個 uiMatching1v1.js
指令碼掛在到場景中的控制元件上.
uiMatching1v1.js ---- randomRoom: function() { Game.GameManager.blockInput(); GLB.matchType = GLB.RANDOM_MATCH; // 修改匹配方式為隨機匹配 console.log('開始隨機匹配'); if (GLB.gameType === GLB.COOPERATION) { if (GLB.MAX_PLAYER_COUNT > 1) { if (cc.Canvas.instance.designResolution.height > cc.Canvas.instance.designResolution.width) { uiFunc.openUI("uiMatchingVer", function(obj) { var matching = obj.getComponent("uiMatching"); matching.joinRandomRoom(); }); } else { uiFunc.openUI("uiMatching", function(obj) { var matching = obj.getComponent("uiMatching"); matching.joinRandomRoom(); }); } } else { cc.director.loadScene('game'); } } else if (GLB.gameType === GLB.COMPETITION) { if (GLB.MAX_PLAYER_COUNT === 2) { if (cc.Canvas.instance.designResolution.height > cc.Canvas.instance.designResolution.width) { uiFunc.openUI("uiMatching1v1Ver", function(obj) { var matching = obj.getComponent("uiMatching1v1Ver"); matching.joinRandomRoom(); }); } else { uiFunc.openUI("uiMatching1v1", function(obj) { var matching = obj.getComponent("uiMatching1v1"); matching.joinRandomRoom(); }); } } else if (GLB.MAX_PLAYER_COUNT === 4) { if (cc.Canvas.instance.designResolution.height > cc.Canvas.instance.designResolution.width) { uiFunc.openUI("uiMatching2v2Ver", function(obj) { var matching = obj.getComponent("uiMatching2v2Ver"); matching.joinRandomRoom(); }); } else { uiFunc.openUI("uiMatching2v2Ver", function(obj) { var matching = obj.getComponent("uiMatching2v2Ver"); matching.joinRandomRoom(); }); } } } },複製程式碼
通過監聽 joinRoomResponse
和 joinRoomNotify
匹配結果
uiMatchvsing1v1.js --- joinRandomRoom: function() { var result = null; if (GLB.matchType === GLB.RANDOM_MATCH) { result = mvs.engine.joinRandomRoom(GLB.MAX_PLAYER_COUNT, ''); if (result !== 0) { console.log('進入房間失敗,錯誤碼:' + result); } } else if (GLB.matchType === GLB.PROPERTY_MATCH) { var matchinfo = new mvs.MatchInfo(); matchinfo.maxPlayer = GLB.MAX_PLAYER_COUNT; matchinfo.mode = 0; matchinfo.canWatch = 0; matchinfo.tags = GLB.tagsInfo; result = mvs.engine.joinRoomWithProperties(matchinfo, "joinRoomWithProperties"); if (result !== 0) { console.log('進入房間失敗,錯誤碼:' + result); } } },複製程式碼
監聽進房間操作的伺服器回覆和房間玩家進出情況的訊息:
joinRoomResponse: function(data) { if (data.status !== 200) { console.log('進入房間失敗,非同步回撥錯誤碼: ' + data.status); } else { console.log('進入房間成功'); console.log('房間號: ' + data.roomInfo.roomID); } GLB.roomId = data.roomInfo.roomID; var userIds = [GLB.userInfo.id] console.log('房間使用者: ' + userIds); var playerIcon = null; for (var j = 0; j < data.roomUserInfoList.length; j++) { playerIcon = this.playerIcons[j].getComponent('playerIcon'); if (playerIcon && !playerIcon.userInfo) { playerIcon.setData(data.roomUserInfoList[j]); if (GLB.userInfo.id !== data.roomUserInfoList[j].userId) { userIds.push(data.roomUserInfoList[j].userId); } } } for (var i = 0; i < this.playerIcons.length; i++) { playerIcon = this.playerIcons[i].getComponent('playerIcon'); if (playerIcon && !playerIcon.userInfo) { playerIcon.setData(GLB.userInfo); } } GLB.playerUserIds = userIds; if (userIds.length >= GLB.MAX_PLAYER_COUNT) { var result = mvs.engine.joinOver(""); console.log("發出關閉房間的通知"); if (result !== 0) { console.log("關閉房間失敗,錯誤碼:", result); } GLB.playerUserIds = userIds; } }, joinRoomNotify: function(data) { console.log("joinRoomNotify, roomUserInfo:" + JSON.stringify(data.roomUserInfo)); var playerIcon = null; for (var j = 0; j < this.playerIcons.length; j++) { playerIcon = this.playerIcons[j].getComponent('playerIcon'); if (playerIcon && !playerIcon.userInfo) { playerIcon.setData(data.roomUserInfo); break; } }複製程式碼
遊戲同步 釋出上線
還是按照上給你面的套路,新建場景(uiGamePanel.fire),掛在指令碼(uiGamePanel.js).攻擊的動作使用Matchvs 的 sendEventEx
發出,如回合開始播放動畫:
roundStart () { console.log('------roundStart------') this.timeLabelInit(); clearInterval(this.interval); this.playerFlag = GLB.PLAYER_FLAG.RED; // this.getTurn(this.playerFlag); user.init(); this.headColorInit(); clientEvent.dispatch(clientEvent.eventType.getMap); this.playReadyGo(); this.setTimeNumFont(); this.setHeadIcon(); },複製程式碼
另一方的客戶端收到後處理遊戲中的各種事件訊息;開發完成後, 再通過CC的一鍵釋出微信小遊戲功能上線微信。
clientEvent.on(clientEvent.eventType.updateTime, this.updateTime, this); clientEvent.on(clientEvent.eventType.countTime, this.countTime, this); clientEvent.on(clientEvent.eventType.changeFlag, this.changeFlag, this); clientEvent.on(clientEvent.eventType.roundStart, this.roundStart, this); clientEvent.on(clientEvent.eventType.gameOver, this.gameOver, this); clientEvent.on(clientEvent.eventType.stopTimeWarnAnim, this.stopTimeWarnAnim, this); 複製程式碼