javascript - Java Script & Socket IO:无法从客户端向服务器发出值来操作服务器上的变量
问题描述
我正在制作简单的多人贪吃蛇游戏来掌握如何使用 socket.io,而在我的一生中,我无法让客户端向服务器发出值。在客户端的my 下方function advanceSnake()
,当蛇在坐标内撞击时,它应该发出一个名为 'tf' 的对象,其值为 'true': socket.emit('makeFood', {tf: true})
。在我的服务器端我有它,所以当它接收到它应该设置的数据 var food = true
但它不会改变
io.sockets.on('makeFood', function(data) {
food = data.tf;
});
我定期运行一个函数
function main() {
setTimeout(function onTick() {
if (food == true) {
createFood()};
main();
}, 500);
}
看看是否var food == true
但它从不调用该函数createFood()
我不相信在服务器端var food
设置true
。任何帮助将不胜感激。谢谢!
客户:
////// CLIENT //////
var socket = io.connect('http://localhost:8000');
/** CONSTANTS **/
const CANVAS_BORDER_COLOR = 'black';
const CANVAS_BACKGROUND_COLOR = 'white';
const SNAKE_COLOR = 'lightgreen';
const SNAKE_BORDER_COLOR = 'darkgreen';
var myName = prompt("Name","test");
if(myName !== undefined){
socket.emit('newPlayer',{
name: myName
});
}
let snake = [
{x: 150, y: 150}
];
// Horizontal velocity
let dx = 0;
// Vertical velocity
let dy = 0;
// Score variable
let score = 0;
// Get the canvas element from index.html
var canvas = document.getElementById('gameCanvas');
// Return a two dimensional drawing context
var ctx = canvas.getContext('2d');
// Select the color to fill the canvas
ctx.fillStyle = CANVAS_BACKGROUND_COLOR;
// Select the color to fill border of canvas
ctx.strokeStyle = CANVAS_BORDER_COLOR;
// Draw a 'filled' rectangle to cover the entire canvas
ctx.fillRect(0, 0, gameCanvas.width, gameCanvas.height);
//Draw a border around the entire canvas
ctx.strokeRect(0, 0, gameCanvas.width, gameCanvas.height);
function randomTen(min, max) {
return Math.round((Math.random() * (max-min) + min ) / 20) * 20;
}
function advanceSnake() {
// Constant for adding snake head
const head = {x: snake[0].x + dx, y: snake[0].y + dy};
// Add a new head with coordinates of dx, dy
snake.unshift(head);
if ((snake[0].x >= bigFoodXNeg && snake[0].x <= bigFoodXPos) && (snake[0].y >= bigFoodYNeg && snake[0].y <= bigFoodYPos)) {
score += 1;
document.getElementById('score').innerHTML = score;
socket.emit('makeFood', {tf: true})
} else {
// Remove the last part of the snake
snake.pop();
}
}
function drawSnake() {
snake.forEach(drawSnakePart);
}
function drawSnakePart(snakePart) {
// Set the color of the snake part
ctx.fillStyle = SNAKE_COLOR;
// Set the border color of the snake part
ctx.strokestyle = SNAKE_BORDER_COLOR;
// Draw a 'filled' rectangle to represent the snake part at the coordinates
// the part is located
ctx.fillRect(snakePart.x, snakePart.y, 10, 10);
// Draw a border around the snake part
ctx.strokeRect(snakePart.x, snakePart.y, 10, 10);
}
function clearCanvas(){
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.fillRect(0, 0, gameCanvas.width, gameCanvas.height);
ctx.strokeRect(0, 0, gameCanvas.width, gameCanvas.height);
}
document.addEventListener('keydown', changeDirection);
function changeDirection(event) {
const LEFT_KEY = 65;
const RIGHT_KEY = 68;
const UP_KEY = 87;
const DOWN_KEY = 83;
if (changingDirection) return;
changingDirection = true;
const keyPressed = event.keyCode;
const goingUp = dy === -10;
const goingDown = dy === 10;
const goingRight = dx === 10;
const goingLeft = dx === -10;
if (keyPressed === LEFT_KEY && !goingRight) {
dx = -10;
dy = 0;
}
if (keyPressed === RIGHT_KEY && !goingLeft) {
dx = 10;
dy = 0;
}
if (keyPressed === UP_KEY && !goingDown) {
dx = 0;
dy = -10;
}
if (keyPressed === DOWN_KEY && !goingUp) {
dx = 0;
dy = 10;
}
}
function didGameEnd() {
for (let i = 4; i <snake.length; i++) {
const didCollide = snake[i].x ===snake[0].x && snake[i].y === snake[0].y;
if (didCollide) return true;
}
const hitLeftWall = snake[0].x < 0;
const hitRightWall = snake[0].x > gameCanvas.width - 10;
const hitTopWall = snake[0].y < 0;
const hitBottomWall = snake[0].y > gameCanvas.height - 10;
return hitLeftWall ||
hitRightWall ||
hitTopWall ||
hitBottomWall;
}
function drawFood() {
ctx.fillStyle = 'orange';
ctx.strokestyle = 'orange';
ctx.fillRect(foodX, foodY, 20, 20);
ctx.strokeRect(foodX, foodY, 20, 20);
}
socket.on('displayFood', function(food) {
foodX = food.x;
foodY = food.y;
bigFoodXPos = foodX + 10;
bigFoodXNeg = foodX - 10;
bigFoodYPos = foodY + 10;
bigFoodYNeg = foodY - 10;
})
function main() {
if (didGameEnd()) return;
setTimeout(function onTick() {
changingDirection = false;
clearCanvas();
drawFood();
advanceSnake();
drawSnake();
// Call main again
main();
}, 25);
}
main();
服务器:
////// SERVER //////
// io.sockets.emit('subject', content) ## SEND TO CLIENTS
var express = require('express');
var socket = require('socket.io');
var players = [];
// App Setup
var app = express();
var server = app.listen(8000, function() {
console.log('Listening to requests on port 8000');
});
// Static files
app.use(express.static('public'));
// Socket setup
var io = socket(server);
var food = true;
createFood();
io.on('connection', function(socket) {
console.log('made socket connection', socket.id);
socket.on('newPlayer', function(data){
players.push({
id: socket.id,
name: data.name,
dx: 0,
dy: 0
});
console.log(players[players.length-1].name + " has joined");
//console.log(create);
displayFood();
});
});
io.sockets.on('makeFood', function(data) {
food = data.tf;
});
function randomTen(min, max) {
return Math.round((Math.random() * (max-min) + min ) / 20) * 20;
}
function createFood() {
foodX = randomTen(0, 800 - 40);
foodY = randomTen(0, 800 - 40);
console.log("Food created at: " + foodX + ", " + foodY);
displayFood();
food = false;
}
function displayFood() {
io.sockets.emit('displayFood', {
x : foodX,
y : foodY,
});
}
function main() {
setTimeout(function onTick() {
if (food == true) {
createFood()};
main();
}, 500);
}
main();
解决方案
我终于找到了我自己问题的答案。我在客户端改变了一些东西,即
io.sockets.on('makeFood', function(data) {
food = data.tf;
至:
socket.emit('makeFood')
这样我就可以只向标记的套接字发出信号,'makefood'
而不是使这个面向对象(我出于绝望而这样做),因为确实没有理由。在服务器端,它没有向播放器调用函数,因为我在函数io.sockets.on
的外部使用io.on
(我认为它可以工作,但显然不行)所以我将其更改为socket.on
并将其移动io.on('connection', function(socket)
到结果是:
服务器:
io.on('connection', function(socket) {
console.log('made socket connection', socket.id);
socket.on('newPlayer', function(data){
players.push({
id: socket.id,
name: data.name,
dx: 0,
dy: 0
});
console.log(players[players.length-1].name + " has joined");
//console.log(create);
displayFood();
});
socket.on('makeFood', function() {
createFood();
});
});
现在食物更新到客户端。顺便说一句,function createFood() {
我调用了另一个函数,该函数发出食物的 x、y 坐标。这就是为什么我能够看到客户端更新的食物:
socket.on('displayFood', function(food) {
foodX = food.x;
foodY = food.y;
});
希望这对其他人有帮助!:)
推荐阅读
- java - 不能在java中使用另一个类的公共方法
- javascript - 如何从特定秒到另一个特定秒播放 youtube 视频?
- c++ - Eigen C++ 中的向量向量
- jsf - 实现逻辑以仅显示一个按钮
- r - 通过将条件识别行中的值复制到新列中来扩大数据框
- kubernetes - Kubernetes:如何删除 StatefulSet 管理的特定 pod 而无需重新创建它?
- javascript - 如何将 setInterval 和 setTimeout 添加到循环中?
- java - Jlink 弹簧靴
- python - & 带数字的运算符
- powershell - 在 Powershell 中根据大小重命名文件