服务器 - 导致形状无法在 Canvas Node.js 上呈现的客户端通信
Server - Client communication causing Shapes to not Render on Canvas Node.js
我正在尝试创建在线多人游戏,但出于某种原因,我无法在屏幕上绘制玩家。我认为问题与服务器没有正确地将数据发送到客户端有关,但我已经包含了整个(注释的)代码以防万一不是这种情况。
index.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Online Game</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<canvas id="myCanvas" width="600" height="600"></canvas
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/addons/p5.sound.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="script.js"></script>
</body>
</html>
非常简单,我定义 canvas 和客户端脚本 script.js
index.js
:
const express = require('express');
const app = express();
const http = require("http").createServer(app);
const io = require("socket.io")(http);
app.get('/',function(req, res) {
res.sendFile(__dirname + '/index.html');
});
app.use('/',express.static(__dirname));
/* Server */
// Movement keys
const W = 87;
const A = 65;
const S = 83;
const D = 68;
// The data
let data = {players:{}} ;
let width = 600;
let height = 600;
io.on("connection", socket => {
// New player connected
console.log("player connected");
// Create new player
data.players[socket.id] = {
pos:{x:300, y:300},
speed:10,
size:30,
color:{r:255, g:0, b:0}
};
console.log(data);
socket.on("disconnect", () => {
// Player disconnected
console.log("player disconnected");
// Delete player
delete data.players[socket.id];
});
// Movement event
socket.on("move", key => {
// Get the current player
let player = data.players[socket.id];
console.log(player.pos)
// Check which movement key was pressed, and move accordingly
if(key == W) {
player.pos.y -= player.speed;
console.log('up')
}
if(key == A) {
player.pos.x -= player.speed;
console.log('left')
}
if(key == S) {
player.pos.y += player.speed;
console.log('down')
}
if(key == D) {
player.pos.x += player.speed;
console.log('right')
}
// Check if player is touching the boundry, if so stop them from moving past it
if(player.pos.x > width - player.size) {
player.pos.x = width - player.size;
}
if(player.pos.x < 0) {
player.pos.x = 0;
}
if(player.pos.y > height - player.size) {
player.pos.y = height - player.size;
}
if(player.pos.y < 0) {
player.pos.y = 0;
}
});
});
http.listen(4141);
这是服务器代码,它负责创建玩家和跟踪运动。写得有点草率
script.js
:
const socket = io();
/* Setup */
let canvas = document.getElementById('myCanvas');
let ctx = canvas.getContext('2d');
/* Update & Events */
// Create the movement keys
const W = 87;
const A = 65;
const S = 83;
const D = 68;
// Get the update from the server
socket.on("update", data => {});
//receive input to move player
document.addEventListener('keydown', function (event) {
if (event.key === 'w') {
socket.emit("move", W);
}
if (event.key === 'a') {
socket.emit("move", A);
}
if (event.key === 's') {
socket.emit("move", S);
}
if (event.key === 'd') {
socket.emit("move", D);
}
});
function draw(){
// Draw each player
for(let playerID of Object.keys(data.players)) {
// Get the the player from the player's id
let player = data.players[playerID];
// Draw the player
ctx.startPath();
ctx.arc(player.pos.x, player.pos.y, player.size, 0, Math.PI*2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
}
draw();
最后一个 for
循环是不起作用的部分。它应该从 update
事件中读取 data
地图并在各自的位置渲染所有玩家,但事实并非如此。
我试过调试它。移动事件没有问题,canvas也没有。如果我将 ctx.fillRect(x, y, size, size)
硬编码到程序中,它就会显示出来。所以我认为这与未正确发送 data
变量有关。我是否遗漏了一些明显的东西?
更新
所以我意识到我忘记从 index.js
发出更新事件并更新了一些脚本
index.js
:
socket.on("move", key => {
// Get the current player
let player = data.players[socket.id];
console.log(player.pos)
// Check which movement key was pressed, and move accordingly
if(key == W) {
player.pos.y -= player.speed;
console.log('up')
}
if(key == A) {
player.pos.x -= player.speed;
console.log('left')
}
if(key == S) {
player.pos.y += player.speed;
console.log('down')
}
if(key == D) {
player.pos.x += player.speed;
console.log('right')
}
// Check if player is touching the boundry, if so stop them from moving past it
if(player.pos.x > width - player.size) {
player.pos.x = width - player.size;
}
if(player.pos.x < 0) {
player.pos.x = 0;
}
if(player.pos.y > height - player.size) {
player.pos.y = height - player.size;
}
if(player.pos.y < 0) {
player.pos.y = 0;
}
socket.emit('update', data);
});
它现在发出事件。但是当我尝试接收它时,
script.js
:
socket.on("update", data => {
// Draw each player
for(let playerID of Object.keys(data.players)) {
// Get the the player from the player's id
let player = data.players[playerID];
// Draw the player
ctx.startPath();
ctx.arc(player.pos.x, player.pos.y, player.size, 0, Math.PI*2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
});
它仍然没有呈现。
更新 2
现在所有数据都通过了,唯一的问题是形状没有渲染。与 canvas
有关
事实证明这是显而易见的。在 canvas 上绘图的语法是 beginPath
而不是 startPath
我正在尝试创建在线多人游戏,但出于某种原因,我无法在屏幕上绘制玩家。我认为问题与服务器没有正确地将数据发送到客户端有关,但我已经包含了整个(注释的)代码以防万一不是这种情况。
index.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Online Game</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<canvas id="myCanvas" width="600" height="600"></canvas
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/addons/p5.sound.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="script.js"></script>
</body>
</html>
非常简单,我定义 canvas 和客户端脚本 script.js
index.js
:
const express = require('express');
const app = express();
const http = require("http").createServer(app);
const io = require("socket.io")(http);
app.get('/',function(req, res) {
res.sendFile(__dirname + '/index.html');
});
app.use('/',express.static(__dirname));
/* Server */
// Movement keys
const W = 87;
const A = 65;
const S = 83;
const D = 68;
// The data
let data = {players:{}} ;
let width = 600;
let height = 600;
io.on("connection", socket => {
// New player connected
console.log("player connected");
// Create new player
data.players[socket.id] = {
pos:{x:300, y:300},
speed:10,
size:30,
color:{r:255, g:0, b:0}
};
console.log(data);
socket.on("disconnect", () => {
// Player disconnected
console.log("player disconnected");
// Delete player
delete data.players[socket.id];
});
// Movement event
socket.on("move", key => {
// Get the current player
let player = data.players[socket.id];
console.log(player.pos)
// Check which movement key was pressed, and move accordingly
if(key == W) {
player.pos.y -= player.speed;
console.log('up')
}
if(key == A) {
player.pos.x -= player.speed;
console.log('left')
}
if(key == S) {
player.pos.y += player.speed;
console.log('down')
}
if(key == D) {
player.pos.x += player.speed;
console.log('right')
}
// Check if player is touching the boundry, if so stop them from moving past it
if(player.pos.x > width - player.size) {
player.pos.x = width - player.size;
}
if(player.pos.x < 0) {
player.pos.x = 0;
}
if(player.pos.y > height - player.size) {
player.pos.y = height - player.size;
}
if(player.pos.y < 0) {
player.pos.y = 0;
}
});
});
http.listen(4141);
这是服务器代码,它负责创建玩家和跟踪运动。写得有点草率
script.js
:
const socket = io();
/* Setup */
let canvas = document.getElementById('myCanvas');
let ctx = canvas.getContext('2d');
/* Update & Events */
// Create the movement keys
const W = 87;
const A = 65;
const S = 83;
const D = 68;
// Get the update from the server
socket.on("update", data => {});
//receive input to move player
document.addEventListener('keydown', function (event) {
if (event.key === 'w') {
socket.emit("move", W);
}
if (event.key === 'a') {
socket.emit("move", A);
}
if (event.key === 's') {
socket.emit("move", S);
}
if (event.key === 'd') {
socket.emit("move", D);
}
});
function draw(){
// Draw each player
for(let playerID of Object.keys(data.players)) {
// Get the the player from the player's id
let player = data.players[playerID];
// Draw the player
ctx.startPath();
ctx.arc(player.pos.x, player.pos.y, player.size, 0, Math.PI*2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
}
draw();
最后一个 for
循环是不起作用的部分。它应该从 update
事件中读取 data
地图并在各自的位置渲染所有玩家,但事实并非如此。
我试过调试它。移动事件没有问题,canvas也没有。如果我将 ctx.fillRect(x, y, size, size)
硬编码到程序中,它就会显示出来。所以我认为这与未正确发送 data
变量有关。我是否遗漏了一些明显的东西?
更新
所以我意识到我忘记从 index.js
发出更新事件并更新了一些脚本
index.js
:
socket.on("move", key => {
// Get the current player
let player = data.players[socket.id];
console.log(player.pos)
// Check which movement key was pressed, and move accordingly
if(key == W) {
player.pos.y -= player.speed;
console.log('up')
}
if(key == A) {
player.pos.x -= player.speed;
console.log('left')
}
if(key == S) {
player.pos.y += player.speed;
console.log('down')
}
if(key == D) {
player.pos.x += player.speed;
console.log('right')
}
// Check if player is touching the boundry, if so stop them from moving past it
if(player.pos.x > width - player.size) {
player.pos.x = width - player.size;
}
if(player.pos.x < 0) {
player.pos.x = 0;
}
if(player.pos.y > height - player.size) {
player.pos.y = height - player.size;
}
if(player.pos.y < 0) {
player.pos.y = 0;
}
socket.emit('update', data);
});
它现在发出事件。但是当我尝试接收它时,
script.js
:
socket.on("update", data => {
// Draw each player
for(let playerID of Object.keys(data.players)) {
// Get the the player from the player's id
let player = data.players[playerID];
// Draw the player
ctx.startPath();
ctx.arc(player.pos.x, player.pos.y, player.size, 0, Math.PI*2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
});
它仍然没有呈现。
更新 2
现在所有数据都通过了,唯一的问题是形状没有渲染。与 canvas
有关事实证明这是显而易见的。在 canvas 上绘图的语法是 beginPath
而不是 startPath