我正在尝试创建一款在线多人游戏,但由于某些原因,我无法将玩家绘制在屏幕上。我认为这个问题与服务器没有正确地将数据发送到客户端有关,但我已经包含了整个(注释)代码,以防情况并非如此。
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>
非常简单,我定义了画布和客户端脚本,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
地图并渲染所有玩家在各自的位置,但它不是。
我试过调试它。move事件没有问题,画布也没有问题。如果我硬编码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
结果很明显。在画布上绘图的语法是beginPath
而不是startPath