我们的游戏分为三个场景
游戏启动的时候进入menu场景,当玩家点击对战时进入match场景,匹配成功进入game场景,取消匹配返回menu场景,游戏结束返回menu场景
每一对匹配成功的玩家进入一个独立的房间,所以不同的房间的通信应该互不影响,由于不同场景的通信内容不同,所以不同场景的通信也应该独立
下面就是灵魂画师的创作时间:
我们把这个游戏的匹配过程比作两个好基友开房的过程,从上图我们可以了解到
- 如果有一个人进入了宾馆,那么他最先进入的区域就是hall(大厅)
- 当他非常那啥的时候他就想去前台开个房,那么他就进入了queue(队列),并断开hall的通信
- 当另一个人也非常那啥的时候也去前台排队,当个queue里有两个人的时候,前台小姐就给了他俩一个空闲房间的钥匙,他们就一起进入了一个独立的room,并断开queue的通信
- 以上循环,房间数有限,在房间满的时候不能匹配成功
我们在Global里定义以上socket
menu场景启动时,我们连接hallSocket,开始匹配时,断开hallSocket
进入match场景,连接queueSocket,先进入queue的玩家主场黑棋先手,后进入客场白棋后手(这个逻辑是服务端判断的),匹配成功时,服务端会发送roomId,玩家进入相应的房间,并断开queueSocket的通信
在game场景中,如果游戏结束我们就断掉roomSocket回到menu场景
服务端完整逻辑
server.js
'use strict'
let app = require('express')();
let server = require('http').Server(app);
let io = require('socket.io')(server);
server.listen(4747, function() {
console.log('listening on:4747');
});
let MAX = 30;//最大支持连接房间数
let hall = null;//大厅
let queue = null;//匹配队列
let rooms = [];//游戏房间
function Hall() {
this.people = 0;
this.socket = null;
}
function Room(){
this.people = 0;
this.socket = null;
}
function Queue(){
this.people = 0;
this.socket = null;
}
hall = new Hall();
queue = new Queue();
for(let n = 0;n < MAX;n++){
rooms[n] = new Room();
}
function getFreeRoom(){
for(let n = 0;n < MAX;n++){
if(rooms[n].people === 0){
return n;
}
}
return -1;
}
io.people = 0;
io.on('connection',function(socket){
io.people++;
console.log('someone connected');
socket.on('disconnect',function(){
io.people--;
console.log('someone disconnected');
});
})
hall.socket = io.of('/hall').on('connection', function(socket) {
hall.people++;
console.log('a player connected.There are '+hall.people+' people in hall');
hall.socket.emit('people changed',hall.people);
socket.on('disconnect',function(){
hall.people--;
console.log('a player disconnected.There are '+hall.people+' people in hall');
hall.socket.emit('people changed',hall.people);
});
});
queue.socket = io.of('/queue').on('connection',function(socket){
queue.people++;
console.log('someone connect queue socket.There are '+queue.people+' people in queue');
if(queue.people === 1){
socket.emit('set stand','black');
}else if(queue.people === 2){
socket.emit('set stand','white');
let roomId = getFreeRoom();
console.log(roomId+"roomId");
if(roomId >= 0){
queue.socket.emit('match success',roomId);
console.log('match success.There are '+queue.people+' people in queue');
}else{
console.log('no free room!');
}
}
socket.on('cancel match',function(){
queue.people--;
console.log('someone cancel match.There are '+queue.people+' people in queue');
});
socket.on('disconnect',function(){
queue.people--;
console.log('someone disconnected match.There are '+queue.people+' people in queue');
});
});
for(let i = 0;i < MAX;i++){
rooms[i].socket = io.of('/rooms'+i).on('connection',function(socket){
rooms[i].people++;
console.log('some one connected room'+i+'.There are '+rooms[i].people+' people in the room');
socket.on('update chessboard',function(chessCoor){
socket.broadcast.emit('update chessboard',chessCoor);
});
socket.on('force change turn',function(){
socket.broadcast.emit('force change turn');
});
socket.on('disconnect',function(){
rooms[i].people--;
console.log('someone disconnected room'+i+'.There are '+rooms[i].people+' people in the room');
});
});
}