我正在学习如何使用websocket和socket.io库.我正在创建一个测试2D在线游戏.在游戏中,用户控制一个球.通信方案如下:
Client (game.js):
- 向服务器发送消息
"new player"
,如果连接了新的播放器,则发送socket.id
. - 向服务器发送消息
"movement"
,如果玩家按下/解压控制键,则发送表单{ up: boolean, down: boolean, right: boolean, left: boolean, ID: socket.id }
的所按键的对象. - 当接收到消息
"state"
时,应该呈现连接到游戏but for some reason it does not happen的所有玩家(我在游戏中只看到自己).
Server (server.js):
- 当接收到消息
"new player"
时,在players
对象中存储所连接的玩家的坐标[socket.id from the client]: {x: number, y: number}
. - 当接收到消息
"movement"
时,根据按下的键改变玩家在players
对象中的坐标. - 每隔
16,67
毫秒向客户端发送一条"state"
消息.
game.js
代码:
var socket = io();
socket.on("connect", function () {
socket.emit("new player", socket.id);
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const gridSize = 50;
const playerSize = 20;
const speed = 25;
let playerX;
let playerY;
let movement = {
up: false,
down: false,
left: false,
right: false,
shift: false,
ID: socket.id
};
function drawGrid() {
let colorIndex = 0;
for (let x = 0; x < canvas.width; x += gridSize) {
for (let y = 0; y < canvas.height; y += gridSize) {
ctx.fillStyle = "green";
ctx.fillRect(x, y, gridSize, gridSize);
}
}
}
function drawPlayer() {
if (!playerX) return;
if (!playerY) return;
ctx.beginPath();
ctx.arc(playerX, playerY, playerSize, 0, Math.PI * 2);
ctx.fillStyle = "red";
ctx.fill();
}
function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
function updateCamera() {
if (!playerX) return;
if (!playerY) return;
const cameraX = canvas.width / 2 - playerX;
const cameraY = canvas.height / 2 - playerY;
ctx.translate(cameraX, cameraY);
}
function update() {
clearCanvas();
updateCamera();
drawGrid();
drawPlayer();
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
function handleKeyPress(event) {
switch (event.key) {
case "a":
movement.left = true;
break;
case "d":
movement.right = true;
break;
case "w":
movement.up = true;
break;
case "s":
movement.down = true;
break;
case "Shift":
movement.shift = true;
break;
}
}
function handleKeyRelease(event) {
switch (event.key) {
case "a":
movement.left = false;
break;
case "d":
movement.right = false;
break;
case "w":
movement.up = false;
break;
case "s":
movement.down = false;
break;
case "Shift":
movement.shift = false;
break;
}
}
window.addEventListener("keydown", handleKeyPress);
window.addEventListener("keyup", handleKeyRelease);
function gameLoop() {
update();
requestAnimationFrame(gameLoop);
socket.emit("movement", movement);
}
window.addEventListener("resize", () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
update();
});
gameLoop();
socket.on("state", function (players) {
clearCanvas();
playerX = players[socket.id]?.x;
playerY = players[socket.id]?.y;
ctx.fillStyle = "yellow";
for (var id in players) {
if (id === socket.id) continue;
var player = players[id];
ctx.beginPath();
ctx.arc(player.x, player.y, playerSize, 0, 2 * Math.PI);
ctx.fill();
}
});
});
server.js
代码:
let express = require('express');
let http = require('http');
let path = require('path');
let socketIO = require('socket.io');
let app = express();
let server = http.Server(app);
let io = socketIO(server);
let port = 5000;
app.set('port', port);
app.use('/static', express.static(__dirname + '/static'));
app.get('/', function (request, response) {
response.sendFile(path.join(__dirname, 'index.html'));
});
server.listen(port, function () {
console.log('Starting server on port: ' + port);
});
var players = {};
io.on('connection', function (socket) {
socket.on('new player', function (ID) {
players[ID] = {
x: 959,
y: 496.5
};
});
socket.on('movement', function (data) {
var player = players[data.ID] || {};
if (data.left) {
if (data.shift) {
player.x -= 7.5
} else {
player.x -= 15;
}
}
if (data.up) {
player.y -= 15;
}
if (data.right) {
if (data.shift) {
player.x += 7.5
} else {
player.x += 15;
}
}
if (data.down) {
player.y += 15;
}
});
});
setInterval(function () {
io.sockets.emit('state', players);
}, 1000 / 60);
index.html
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Canvas Game</title>
<style>
body {
margin: 0;
overflow: hidden;
}
canvas {
display: block;
background-color: #f0f0f0;
}
</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<script src="/socket.io/socket.io.js"></script>
<script src="static/game.js"></script>
</body>
</html>
我不明白到底是什么问题.我想我已经正确配置了WebSocket通信.但尽管如此,当一些人进入游戏时,出于某种原因,他们在游戏中看不到对方.
游戏预览(红球为球员):