联网对战游戏开源实例分享之《斗兽棋》

栏目: 后端 · 发布时间: 7年前

内容简介:本次,Matchvs为大家带来的是一款回合制休闲游戏的开源案例 。玩家双方在一个4X4的棋盘上,遵循食物链的规则玩法下进行翻牌与追逐,最终以场上存活的一方为获胜者。

本次,Matchvs为大家带来的是一款回合制休闲游戏的开源案例 。玩家双方在一个4X4的棋盘上,遵循食物链的规则玩法下进行翻牌与追逐,最终以场上存活的一方为获胜者。

体验地址>>

源码地址>>

首先你需要下载Cocos Creator 和Matchvs JavaScript SDK。本次游戏设计的实现步骤主要拆分为用户登录、随机匹配和创建房间、以及同屏游戏三个部分完成。

用户登录

​ 使用Cocos Creator(以下简称CC)创建游戏登录场景

​ 使用CC 拖动控件, 还原设计稿 , 依托CC的良好的工作流,使得这部分的工作可以由游戏策划或者UI设计者来完成,程序开发者只需要在场景中挂载相应的游戏逻辑脚本. 举个例子,在登录按钮挂在一个 uiLogin.js 的脚本完成用户登录功能.

uilogin.fire

联网对战游戏开源实例分享之《斗兽棋》

新建一个uiLogin.js,按 1,2,3 三个步骤挂载到场景中.

  1. 新建js脚本文件

  2. 选中场景任一控件

  3. 添加组件,选中刚新建的脚本,

在脚本的 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();
                    });
                }
            }
        }
    },复制代码

通过监听 joinRoomResponsejoinRoomNotify 匹配结果

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);
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

从零开始学微信公众号运营推广

从零开始学微信公众号运营推广

叶龙 / 清华大学出版社 / 2017-6-1 / 39.80

本书是丛书的第2本,具体内容如下。 第1章 运营者入门——选择、注册和认证 第2章 变现和赚钱——如何从0到100万 第3章 决定打开率——标题的取名和优化 第4章 决定美观度——图片的选取和优化 第5章 决定停留率——正文的编辑和优化 第6章 决定欣赏率——版式的编辑和优化 第7章 数据的分析——用户内容的精准营销 书中从微信运营入门开始,以商业变......一起来看看 《从零开始学微信公众号运营推广》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具