文件结构:
package.json:
{
"name": "websocket",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"node-websocket-server": "^1.1.4",
"ws": "^6.1.0"
}
}
//配置一些变量表达游戏状态
var LINE_SEGMENT = 0;
var CHAT_MESSAGE = 1;
var GAME_LOGIC = 2;
var WAITING_TO_START = 0;
var GAME_START = 1;
var GAME_OVER = 2;
var GAME_RESTART = 3;
var playerTurn = 0;
//配置游戏中使用的关键词
var wordsList = ["apple","pear","angry","happy","boat","desk"];
var currentGameState = WAITING_TO_START;
var gameOverTimeout;
//创建websocket连接
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ port: 8181 });
//定义广播函数
wss.broadcast = function broadcast(message) {
wss.clients.forEach(function each(client) {
client.send(message);
});
};
//建立连接时向客户端发送一条msg
wss.on('connection', function (ws) {
var msg = "Welcome to join the party! Total connection: " + wss.clients.size;
//定义发送数据的类型,并广播
var data = {};
data.dataType = CHAT_MESSAGE;
data.name = "Server";
data.message = msg;
wss.broadcast(JSON.stringify(data));
//定义控制游戏逻辑的数据类型,并广播
var gameLogicData = {};
gameLogicData.dataType = GAME_LOGIC;
gameLogicData.gameState = WAITING_TO_START;
wss.broadcast(JSON.stringify(gameLogicData));
//开始游戏的条件
if(currentGameState == WAITING_TO_START && wss.clients.size >=2){
startGame();
}
//广播接收到的客户端发来的消息,并广播
ws.on('message', function (message) {
var obj = eval('(' + message + ')');
wss.broadcast(JSON.stringify(obj));
//如果判断收到的消息是聊天消息
if(obj.dataType == CHAT_MESSAGE){
//如果接收到的消息是正确答案,广播并改变当前游戏状态
if(currentGameState == GAME_START && obj.message == currentAnswer){
var gameLogicData = {};
gameLogicData.dataType = GAME_LOGIC;
gameLogicData.gameState = GAME_OVER;
gameLogicData.winner = obj.name;
gameLogicData.answer = currentAnswer;
wss.broadcast(JSON.stringify(gameLogicData));
currentGameState = WAITING_TO_START;
clearTimeout(gameOverTimeout);
}
}else if(obj.dataType == GAME_LOGIC && obj.gameState == GAME_RESTART){
startGame();
}
});
});
//开始游戏函数,初始化答案,控制开始的用户是谁
function startGame(){
playerTurn = (playerTurn +1) % wss.clients.size;
var answerIndex = Math.floor(Math.random()* wordsList.length);
currentAnswer = wordsList[answerIndex];
var gameLogicData1 = {};
gameLogicData1.dataType = GAME_LOGIC;
gameLogicData1.gameState = GAME_START;
gameLogicData1.isPlayerTurn = false;
wss.broadcast(JSON.stringify(gameLogicData1));
var index = 0;
wss.clients.forEach(function each(client) {
if(index == playerTurn){
var gameLogicData2 = {};
gameLogicData2.dataType = GAME_LOGIC;
gameLogicData2.gameState = GAME_START;
gameLogicData2.answer = currentAnswer;
gameLogicData2.isPlayerTurn = true;
wss.broadcast(JSON.stringify(gameLogicData2));
}
index ++;
});
gameOverTimeout = setTimeout(function(){
var gameLogicData = {};
gameLogicData.dataType = GAME_LOGIC;
gameLogicData.gameState = GAME_OVER;
gameLogicData.winner = 'no-one';
gameLogicData.answer = currentAnswer;
wss.broadcast(JSON.stringify(gameLogicData));
currentGameState = WAITING_TO_START;
},60*1000);
currentGameState = GAME_START;
}
console.log("Websocket server is running");
创建一个websocket连接到服务器
WebSocket Echo Demo
你画我猜
控制画板的绘图功能,同步多个用户之间的绘图
var websocketGame = {
isDrawing:false,
startX:0,
startY:0,
LINE_SEGMENT : 0,
CHAT_MESSAGE : 1,
GAME_LOGIC:2,
WAITING_TO_START:0,
GAME_START:1,
GAME_OVER:2,
GAME_RESTART:3,
isTurnToDraw:false
}
var canvas = document.getElementById("drawing-pad");
var ctx = canvas.getContext('2d');
function drawLine(ctx,x1,y1,x2,y2,thickness){
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.lineWidth = thickness;
ctx.strokeStyle = "#444";
ctx.stroke();
}
$(document).ready(function(){
$('#drawing-pad').mousedown(function(e){
var canvasPosition = $(this).offset();
var mouseX = (e.pageX - canvasPosition.left) || 0;
var mouseY = (e.pageY - canvasPosition.top) || 0;
websocketGame.startX = mouseX;
websocketGame.startY = mouseY;
websocketGame.isDrawing = true;
});
$('#drawing-pad').mousemove(function(e){
if(websocketGame.isDrawing){
var canvasPosition = $(this).offset();
var mouseX = (e.pageX - canvasPosition.left) || 0;
var mouseY = (e.pageY - canvasPosition.top) || 0;
}
if(!(mouseX == websocketGame.startX && mouseY == websocketGame.startY)){
drawLine(ctx,websocketGame.startX,websocketGame.startY,mouseX,mouseY,1);
var data = {};
data.dataType = websocketGame.LINE_SEGMENT;
data.startX = websocketGame.startX;
data.startY = websocketGame.startY;
data.endX = mouseX;
data.endY = mouseY;
ws.send(JSON.stringify(data));
websocketGame.startX = mouseX;
websocketGame.startY = mouseY;
}
});
$('#drawing-pad').mouseup(function(e){
websocketGame.isDrawing = false;
});
})
body{
background:#ccd6e1;
font-family:arial,serif;
}
#game{
width:450px;
margin:0 auto;
}
#game h1{
text-align: center;
margin-bottom:10px;
font-size:20px;
}
#drawing-pad{
position:relative;
border:solid 1px black;
background: white;
}
.vertical-center{
position:relative;
}
ul li{
list-style:none;
}
#chat-history{
height:100px;
overflow:auto;
border:solid 1px #ccc;
font-size:14px;
}