1. 程式人生 > >canvas+websocket+vue做一個你畫我猜小遊戲

canvas+websocket+vue做一個你畫我猜小遊戲

做這個主要是學習使用一下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();
		}
	}
}

最後是一個座位和聊天的模組,比較簡單,看一下原始碼就懂了,以後還會慢慢修改的。