达达麻将游戏流程
达达麻将版图
登陆到游戏服务器
1:客户端GameNetMgr.js, connectGameServer连接到游戏服务器,并发送”login”命令;
var sd = {
token:data.token,
roomid:data.roomid,
time:data.time,
sign:data.sign,
};
2:服务器socket_service.js 监听到login事件:
//启动服务
exports.start = function(conf,mgr){
config = conf;
var httpServer = require('http').createServer(app);
io = require('socket.io')(httpServer);
httpServer.listen(config.CLIENT_PORT);
//监听是否有客户端连接进来,如果有客户连接进来就会调用这个函数
//为这个客户创建一个socket通道
io.sockets.on('connection',function(socket){
//监听一个事件,然后data,客户端发送过来的数据
//数据使用的是json协议的编码,来进行数据交换;底层发送json文本;
socket.on('login',function(data){
//转成json格式数据
data = JSON.parse(data);
if(socket.userId != null){
//已经登陆过的就忽略
return;
}
var token = data.token;
var roomId = data.roomid;
var time = data.time;
var sign = data.sign;
console.log(roomId);
console.log(token);
console.log(time);
console.log(sign);
//检查参数合法性
if(token == null || roomId == null || sign == null || time == null){
console.log(1);
socket.emit('login_result',{errcode:1,errmsg:"invalid parameters"});
return;
}
//检查参数是否被篡改
var md5 = crypto.md5(roomId + token + time + config.ROOM_PRI_KEY);
if(md5 != sign){
console.log(2);
//emit发送一个事件
socket.emit('login_result',{errcode:2,errmsg:"login failed. invalid sign!"});
return;
}
//检查token是否有效
if(tokenMgr.isTokenValid(token)==false){
console.log(3);
socket.emit('login_result',{errcode:3,errmsg:"token out of time."});
return;
}
//检查房间合法性
var userId = tokenMgr.getUserID(token);
var roomId = roomMgr.getUserRoom(userId);
userMgr.bind(userId,socket);
socket.userId = userId;
//返回房间信息
var roomInfo = roomMgr.getRoom(roomId);
var seatIndex = roomMgr.getUserSeat(userId);
roomInfo.seats[seatIndex].ip = socket.handshake.address;
var userData = null;
var seats = [];
for(var i = 0; i < roomInfo.seats.length; ++i){
var rs = roomInfo.seats[i];
var online = false;
if(rs.userId > 0){
online = userMgr.isOnline(rs.userId);
}
seats.push({
userid:rs.userId,
ip:rs.ip,
score:rs.score,
name:rs.name,
online:online,
ready:rs.ready,
seatindex:i
});
if(userId == rs.userId){
userData = seats[i];
}
}
//通知前端
var ret = {
errcode:0,
errmsg:"ok",
data:{
roomid:roomInfo.id,
conf:roomInfo.conf,
numofgames:roomInfo.numOfGames,
seats:seats
}
};
socket.emit('login_result',ret);
//通知其它客户端
userMgr.broacastInRoom('new_user_comes_push',userData,userId);
socket.gameMgr = roomInfo.gameMgr;
//玩家上线,强制设置为TRUE
socket.gameMgr.setReady(userId);
socket.emit('login_finished');
if(roomInfo.dr != null){
var dr = roomInfo.dr;
var ramaingTime = (dr.endTime - Date.now()) / 1000;
var data = {
time:ramaingTime,
states:dr.states
}
userMgr.sendMsg(userId,'dissolve_notice_push',data);
}
});
(1)检查参数的合法性,根据token获取uid, 建立uid 与socket的联系;
userMgr.bind(userId,socket);
socket.userId = userId;
(2)获取房间信息,(进入房间的时候保存了座位号(roomid, seatIndex));
var roomId = roomMgr.getUserRoom(userId);
(3)配置好当前的座位的ip地址
var roomInfo = roomMgr.getRoom(roomId);
(4)遍历roomInfo里面所有的座位,将作为信息的数据全部打包好;
if(userId == rs.userId){
userData = seats[i];
}
(5)login_result事件发送给链接进来的客户端;
//通知前端
var ret = {
errcode:0,
errmsg:"ok",
data:{
roomid:roomInfo.id,
conf:roomInfo.conf,
numofgames:roomInfo.numOfGames,
seats:seats
}
};
socket.emit('login_result',ret);
数据保存到全局的GameNetMgr里面
(6)把这个用户进来的消息,广播给其他的用户,其他的用户看到这个进来了;
//通知其它客户端
userMgr.broacastInRoom('new_user_comes_push',userData,userId);
(7)通知玩家上线了,如果4个人凑齐了,开始新一局;
socket.gameMgr = roomInfo.gameMgr;
//玩家上线,强制设置为TRUE
socket.gameMgr.setReady(userId);
麻将场景客户端
1: mjgame场景挂载了MJGame.js与MahjongMgr.js 两个脚本;
注:新框架新添加了Alert.js脚本,是3个。
2: MJGame.js onLoad:添加了其它功能的一些组件;
onLoad: function () {
cc.vv.utils.setFitSreenMode();
this.addComponent("NoticeTip");
this.addComponent("GameOver");
this.addComponent("DingQue");
this.addComponent("PengGangs");
this.addComponent("MJRoom");
this.addComponent("TimePointer");
this.addComponent("GameResult");
this.addComponent("Chat");
this.addComponent("Folds");
this.addComponent("ReplayCtrl");
this.addComponent("PopupMgr");
this.addComponent("HuanSanZhang");
this.addComponent("ReConnect");
this.addComponent("Voice");
this.addComponent("UserInfoShow");
this.addComponent("Status");
this.initView();
this.initEventHandlers();
this.gameRoot.active = false;
this.prepareRoot.active = true;
this.initWanfaLabel();
this.onGameBeign();
cc.vv.audioMgr.playBGM("bgFight.mp3");
cc.vv.utils.addEscEvent(this.node);
},
3: initView: 初始化场景, 隐藏不需要的;
initView:function(){
//搜索需要的子节点
var gameChild = this.node.getChildByName("game");
this._mjcount = gameChild.getChildByName('mjcount').getComponent(cc.Label);
this._mjcount.string = "剩余" + cc.vv.gameNetMgr.numOfMJ + "张";
this._gamecount = gameChild.getChildByName('gamecount').getComponent(cc.Label);
this._gamecount.string = "" + cc.vv.gameNetMgr.numOfGames + "/" + cc.vv.gameNetMgr.maxNumOfGames + "局";
var myselfChild = gameChild.getChildByName("myself");
var myholds = myselfChild.getChildByName("holds");
this._chupaidrag = gameChild.getChildByName(&#