webSocket+ws包+canvas实现简陋版球球大作战

本文介绍了一个使用Node.js和WebSocket实现的多人在线小游戏。游戏通过服务器不断生成食物,并允许玩家通过键盘操作来吃掉这些食物以增加大小。同时,玩家还可以吞噬比自己小的其他玩家。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

server.js

var express = require('express');
var WebSocket = require('ws');
var app = express();
app.use(express.static('./'));

var webS = new WebSocket.Server({host:'10.9.22.171',port:8080},()=>{
	console.log('success')
});

var clients = [];
var user = [];
var food = [];

function rand(n,m){
	var c = m - n + 1;
	return Math.floor(Math.random() * c + n);
}

webS.on('connection',(client)=>{
	console.log('客户端连接成功');
	clients.push(client);

	setInterval(()=>{
		if(food.length < 100){
			for(var i = 0 ; i < 10 ; i++){
				food.push([rand(1,999),rand(1,499)]);
			}
		}
		for(var i = 0 ; i < clients.length ; i++){
			clients[i].send(JSON.stringify({user,food}));
		}
	},1000)

	client.on('message',(msg)=>{
		var msg = JSON.parse(msg);
		if(msg.user){
			for(var i = 0 ; i < clients.length ; i++){
				if(msg.user.uname == user[i].uname){
					user[i] = msg.user;
					if(msg.k){
						food.splice(msg.k,1);
					}
					if(msg.i !== undefined){
						user[msg.i] = {uname:msg.name,x:rand(1,999),y:rand(1,499),color:[rand(0,255),rand(0,255),rand(0,255)],size:2};
					}
					break;
				}
			}
			for(var i = 0 ; i < clients.length ; i++){
				clients[i].send(JSON.stringify({user,food}));
			}
		}else{
			user.push(msg);
			for(var i = 0 ; i < clients.length ; i++){
				clients[i].send(JSON.stringify({user,food}));
			}
		}
	})

	client.on('close',()=>{
		for(var i = 0 ; i < clients.length ; i++){
			if(client == clients[i]){
				clients.splice(i,1);
				user.splice(i,1);
				break;
			}
		}
		console.log('客户端关闭连接')
	})
})

app.listen('8090',()=>{
	console.log('app success')
})

index.html

<!DOCTYPE html>
<html>
<head>
	<title></title>
	<style type="text/css">
		*{margin:0;padding:0;}
		body{background:#333;}
		canvas{display:block;position:absolute;top:0;left:0;right:0;bottom:0;margin:auto;}
	</style>
</head>
<body>
</body>
<script type="text/javascript">
	var uname = prompt("请输入用户名");
	var ws = new WebSocket("ws://10.9.22.171:8080");
	ws.onopen = ()=>{
		console.log('连接建立');
		class qq{
			constructor(){
				this.timer = null;
				this.user = {uname:uname.substr(0,6)+this.rand(0,99),x:this.rand(1,999),y:this.rand(1,499),color:[this.rand(0,255),this.rand(0,255),this.rand(0,255)],size:2};
				this.food = '';
				this.userlist = '';
				this.fx = [0,0];
				this.init()
			}
			init(){
				document.body.innerHTML = "";
				document.body.innerHTML += "<canvas></canvas>";
				this.canvas = document.getElementsByTagName('canvas')[0];
				this.context = this.canvas.getContext('2d');
				this.canvas.width = 1000;
				this.canvas.height = 500;
				ws.send(JSON.stringify(this.user));
			}
			refresh(){
				this.context.clearRect(0,0,1000,500);
				this.context.fillStyle = "rgb(0,0,0)";
				this.context.fillRect(0,0,1000,500);
				this.context.fillStyle = "rgb(255,255,255)";
				this.food.forEach((v)=>{
					this.context.beginPath();
					this.context.arc(v[0],v[1],1,0,2*Math.PI);
					this.context.fill();
					this.context.closePath();
				})
				//console.log(this.userlist)
				if(this.userlist.length != 0){
					this.userlist.forEach((v)=>{
						this.context.beginPath();
						this.context.fillStyle = "rgb("+v.color[0]+","+v.color[1]+","+v.color[2]+")";
						this.context.arc(v.x,v.y,v.size,0,2*Math.PI);
						this.context.fill();
						this.context.fillText(v.uname,v.x,v.y);
						this.context.closePath();
					})
				}

			}
			rand(n,m){
				var c = m - n + 1;
				return Math.floor(Math.random() * c + n);
			}

		}
		var qiuqiu = new qq()

		document.onkeydown=function(event){
			var e = e || event;
			if(e.keyCode == 37){
				qiuqiu.fx[0] = -5;
			}
			if(e.keyCode == 38){
				qiuqiu.fx[1] = -5;
			}
			if(e.keyCode == 39){
				qiuqiu.fx[0] = 5;
			}
			if(e.keyCode == 40){
				qiuqiu.fx[1] = 5;
			}

			qiuqiu.user.x += qiuqiu.fx[0];
			qiuqiu.user.y += qiuqiu.fx[1];
			for(var k = 0 ; k < qiuqiu.food.length ; k++){
				if( (Math.pow((qiuqiu.user.x-qiuqiu.food[k][0]),2)+Math.pow((qiuqiu.user.y-qiuqiu.food[k][1]),2)) < Math.pow((qiuqiu.user.size+1),2) ){
					qiuqiu.user.size += 1/qiuqiu.user.size;
					ws.send(JSON.stringify({user:qiuqiu.user,k}));
				}
				if(k == qiuqiu.food.length-1){
					ws.send(JSON.stringify({user:qiuqiu.user}));
				}
			}
			for(var i = 0 ; i < qiuqiu.userlist.length ; i++){
				if(qiuqiu.userlist[i].uname != qiuqiu.user.uname && qiuqiu.userlist[i].size < qiuqiu.user.size && (Math.pow((qiuqiu.userlist[i].x-qiuqiu.user.x),2)+Math.pow((qiuqiu.userlist[i].y-qiuqiu.user.y),2)) < Math.pow((qiuqiu.user.size+qiuqiu.userlist[i].size),2) ){
					qiuqiu.user.size += qiuqiu.userlist[i].size/qiuqiu.user.size;
					ws.send(JSON.stringify({user:qiuqiu.user,i,name:qiuqiu.userlist[i].uname}));
				}
				if(k == qiuqiu.userlist.length-1){
					ws.send(JSON.stringify({user:qiuqiu.user}));
				}
			}
		}
		document.onkeyup=function(event){
			var e = e || event;
			if(e.keyCode == 37){
				qiuqiu.fx[0] = 0;
			}
			if(e.keyCode == 38){
				qiuqiu.fx[1] = 0;
			}
			if(e.keyCode == 39){
				qiuqiu.fx[0] = 0;
			}
			if(e.keyCode == 40){
				qiuqiu.fx[1] = 0;
			}
		}

		ws.onmessage = (msg)=>{
			data = JSON.parse(msg.data);
			qiuqiu.food = data.food;
			qiuqiu.userlist = data.user;
			for(var i = 0 ; i < qiuqiu.userlist.length ; i++){
				if(qiuqiu.user.uname ==  qiuqiu.userlist[i].uname){
					qiuqiu.user = qiuqiu.userlist[i];
				}
			}
			qiuqiu.refresh();
		}

		ws.onclose = ()=>{
			console.log('服务端关闭连接')
		}
	}
</script>
</html>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风舞红枫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值