canvas+websocket+vue做一個你畫我猜小遊戲
阿新 • • 發佈:2018-12-12
做這個主要是學習使用一下canvas和websocket,專案地址。
你畫我猜大家應該都玩過,一個人畫,其他人猜。現在剛剛實現了最基本的功能,以後還會慢慢修改的。
完成進度
- 登入,登入後username儲存到了sessionStorage中。
- 座位,登入後可以選擇座位,並通過ws告訴所有人你的座位。
- 傳送內容,登入後可以通過ws將輸入內容釋出給所有人。
- 聊天記錄,可以接收所有人的聊天打字內容。
- 畫圖,目前只能通過點選“我要畫”按鈕進行畫圖。
- 接收畫圖,預設情況或點選“我要猜”按鈕可以檢視他人畫圖。
- 開始遊戲
- 輪流進行畫圖與看圖猜詞
- 猜詞詞表
- 傳送內容為正確詞時特殊顯示
- 記分
- 多房間遊戲
- 移動端
專案架構
專案截圖
專案
先安裝node的ws模組,然後使用node做一個簡單的後端,作用就是接受websocket連線,將收到的一個使用者發過來的資料傳送給所有使用者。
// 匯入WebSocket模組:
const WebSocket = require('ws');
// 引用Server類:
const WebSocketServer = WebSocket.Server;
// 例項化:
const wss = new WebSocketServer({
port: 3000
});
wss.on('connection', function (ws) {
console. log(`[SERVER] connection()`);
ws.on('message', function (message) {
console.log(`[SERVER] Received: ${message}`);
wss.clients.forEach((client) => {
client.send(message)
})
})
});
後端寫好了,前端先進行ws連線,然後將ws和msg傳給後面的模組。
this.ws = new WebSocket('ws://localhost:3000/' );
this.ws.onmessage = (message)=>{
console.log(message)
this.msg = message.data.split(',')
}
前端分為畫和猜兩個模組,畫的模組關鍵程式碼如下,我們構建了一個canvasDraw類,檢測滑鼠的down、up和move事件,進行畫圖,並且將此時滑鼠的座標傳送給伺服器。
<canvas id="drawBoard" width="350" height="350"></canvas>
<button @click="clearDraw()">clear</button>
export default {
mounted: function(){
this.draw = new canvasDraw("drawBoard",this.ws);
this.draw.draw();
},
methods:{
clearDraw:function(){
this.draw.clearCanvas();
}
}
}
class canvasDraw{
constructor(id,ws){
this.ws= ws;
this.canvas = document.getElementById(id);
this.ctx = this.canvas.getContext('2d');
this.stage_info = this.canvas.getBoundingClientRect()
this.path = {
beginX: 0,
beginY: 0,
endX: 0,
endY: 0
}
this.isDraw=false
}
draw(){
let that = this
this.canvas.onmousedown = () => {
that.ctx.strokeStyle = "#000"
that.ctx.beginPath()
that.path.beginX = event.pageX - that.stage_info.left
that.path.beginY = event.pageY - that.stage_info.top
that.ctx.moveTo(
that.path.beginX,
that.path.beginY
)
that.isDraw=true
}
this.canvas.onmousemove = () => {
if(that.isDraw){
that.drawing(event)
}
}
this.canvas.onmouseup = () => {
that.isDraw=false
that.ws.send('stop,')
}
}
drawing(e) {
this.path.endX = e.pageX - this.stage_info.left
this.path.endY = e.pageY - this.stage_info.top
this.ctx.lineTo(
this.path.endX,
this.path.endY
)
this.ctx.stroke()
this.ws.send("draw"+','+this.path.beginX+','+this.path.beginY+','+this.path.endX+','+this.path.endY)
}
clearCanvas(){
this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
this.ws.send('clear,')
}
}
然後是接受部分,接受部分就把伺服器發過來的座標解析出來,安裝順序畫在canvas上即可。關鍵程式碼如下。
<canvas id="showing" width="350" height="350"></canvas>
export default {
mounted: function(){
this.canvas = document.getElementById('showing')
this.ctx = this.canvas.getContext('2d')
this.ctx.strokeStyle = "#000"
},
watch:{
msg(newval,oldval){
if(this.msg[0]=="draw"||this.msg[0]=="stop"){
if(this.isDraw==1&&this.msg[0]!='stop'){
this.ctx.beginPath()
this.ctx.moveTo(this.msg[1],this.msg[2])
this.isDraw=0
}else if(this.isDraw==0&&this.msg[0]=='stop'){
this.isDraw=1
}
this.ctx.lineTo(this.msg[3],this.msg[4])
this.ctx.stroke()
}else if(this.msg[0]=='clear'){
this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
}
}
},
methods:{
clearDraw:function(){
this.draw.clearCanvas();
}
}
}
最後是一個座位和聊天的模組,比較簡單,看一下原始碼就懂了,以後還會慢慢修改的。