检查用户是否点击了除他们之外的客户端

Check if user clicks on client besides them

我正在尝试检测用户是否点击了他们以外的客户端。如果您尝试项目 (https://multiplayer-movement.stcollier.repl.co/) 并打开控制台,(使用箭头键移动)如果您点击自己,控制台 returns true 但这不适用于您单击任何其他客户端。这是我的 JavaScript:

var socket = io();
var player; //var player = players[id]
//let fps = performance.now();
let playerWidth = 25;
let playerHeight = 25;

var movement = {
  up: false,
  down: false,
  left: false,
  right: false
}
document.addEventListener('keydown', function(event) {
  switch (event.keyCode) {
    case 37: //Arrow LEFT
      movement.left = true;
      break;
    case 38: //Arrow UP
      movement.up = true;
      break;
    case 39: //Arrow RIGHT
      movement.right = true;
      break;
    case 40: //Arrow Down
      movement.down = true;
      break;
  }
});
document.addEventListener('keyup', function(event) {
  switch (event.keyCode) {
    case 37: //Arrow LEFT
      movement.left = false;
      break;
    case 38: //Arrow UP
      movement.up = false;
      break;
    case 39: //Arrow RIGHT
      movement.right = false;
      break;
    case 40: //Arrow Down
      movement.down = false;
      break;
  }
});

socket.emit('new player');

/*var lastUpdateTime = (new Date()).getTime();
setInterval(function() {
  socket.emit('movement', movement);
  var currentTime = (new Date()).getTime();
  timeDifference = currentTime - lastUpdateTime;
  lastUpdateTime = currentTime;
}, 1000 / 60);*/

setInterval(function() {
  socket.emit('movement', movement);
}, 1000 / 60);

var canvas = document.getElementById('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var ctx = canvas.getContext('2d');
//ctx.fillRect(0, 0, 800, 600);
socket.on('state', function(players) {
  //console.log(players);
  ctx.fillStyle = "white";
  ctx.fillRect(0, 0, canvas.width, canvas.height)
  for (var id in players) {
    player = players[id];
    ctx.fillStyle = 'green';
    ctx.fillRect(player.x, player.y, playerWidth, playerHeight)
  }
});

function canShoot(p2, event) {
  var mouseX = event.clientX;
  var mouseY = event.clientY;
  if (mouseX >= p2.x && mouseX <= p2.x + playerWidth && mouseY >= p2.y && mouseY <= mouseY + playerHeight) {
    return true;
  }
  else {
    return false;
  }
}
document.body.onclick = function() {
    if (canShoot(player, event)) {
    console.log(true)
  }
}

我检测用户是否点击客户端的函数在这里:

function canShoot(p2, event) {
  var mouseX = event.clientX;
  var mouseY = event.clientY;
  if (mouseX >= p2.x && mouseX <= p2.x + playerWidth && mouseY >= p2.y && mouseY <= mouseY + playerHeight) {
    return true;
  }
  else {
    return false;
  }
}

这是我的服务器代码:

const http = require("http");
const express = require("express");
const socketio = require("socket.io");
const path = require("path");

const app = express();
const httpserver = http.Server(app);
const io = socketio(httpserver);

const gamedirectory = path.join(__dirname, "public");

app.use(express.static(gamedirectory));

httpserver.listen(3000);

var players = {};
let speed = 4;
var timeDifference;

io.on('connection', function(socket) {
  console.log("A user connected.")
  socket.on('new player', function() { //adds client on connection
    players[socket.id] = {
      x: 0, //x and y spawn point
      y: 0
    };
  });
  socket.on('disconnect', function() {
    console.log('A user disconnected.');
    delete players[socket.id]; //deletes client on disconnection
  });
  socket.on('movement', function(data) {
    var player = players[socket.id] || {};
    if (data.left) {
      player.x -= speed;
    }
    if (data.up) {
      player.y -= speed;
    }
    if (data.right) {
      player.x += speed;
    }
    if (data.down) {
      player.y += speed;
    }
  });
});

/*setInterval(function() {
  io.sockets.emit('state', players);
}, 1000 / 60);*/

var lastUpdateTime = (new Date()).getTime();
setInterval(function() {
  io.sockets.emit('state', players);
  var currentTime = (new Date()).getTime();
  timeDifference = currentTime - lastUpdateTime;
  lastUpdateTime = currentTime;
}, 1000 / 60);

那么我该如何解决这个问题,以便如果用户点击,他们可以点击其他客户端?

谢谢。

我认为您遇到的问题是:

for (var id in players) {
    player = players[id];
    ctx.fillStyle = 'green';
    ctx.fillRect(player.x, player.y, playerWidth, playerHeight)
}

循环将继续进行,直到到达最后一个玩家。这意味着您的 'player' 变量将在每次循环时重新分配,直到它到达最后一个玩家,即您的客户,这将是 'player' 的值。因此,它只能看到你的玩家的坐标。

试试这个:

var socket = io();
let player = []; // array of ALL players
//let fps = performance.now();
let playerWidth = 25;
let playerHeight = 25;

var movement = {
  up: false,
  down: false,
  left: false,
  right: false
}
document.addEventListener('keydown', function(event) {
  switch (event.keyCode) {
    case 37: //Arrow LEFT
      movement.left = true;
      break;
    case 38: //Arrow UP
      movement.up = true;
      break;
    case 39: //Arrow RIGHT
      movement.right = true;
      break;
    case 40: //Arrow Down
      movement.down = true;
      break;
  }
});
document.addEventListener('keyup', function(event) {
  switch (event.keyCode) {
    case 37: //Arrow LEFT
      movement.left = false;
      break;
    case 38: //Arrow UP
      movement.up = false;
      break;
    case 39: //Arrow RIGHT
      movement.right = false;
      break;
    case 40: //Arrow Down
      movement.down = false;
      break;
  }
});

socket.emit('new player');

/*var lastUpdateTime = (new Date()).getTime();
setInterval(function() {
  socket.emit('movement', movement);
  var currentTime = (new Date()).getTime();
  timeDifference = currentTime - lastUpdateTime;
  lastUpdateTime = currentTime;
}, 1000 / 60);*/

setInterval(function() {
  socket.emit('movement', movement);
}, 1000 / 60);

var canvas = document.getElementById('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var ctx = canvas.getContext('2d');
//ctx.fillRect(0, 0, 800, 600);
socket.on('state', function(players) {
  //console.log(players);
  ctx.fillStyle = "white";
  ctx.fillRect(0, 0, canvas.width, canvas.height)
  let i = 0;
  for (var id in players) {
    player[player.length] = players[id];
    ctx.fillStyle = 'green';
    ctx.fillRect(player[i].x, player[i].y, playerWidth, playerHeight)
    i++;
  }
});

function canShoot(p2, event) {
  var mouseX = event.clientX;
  var mouseY = event.clientY;
  for (var i = 0; i < p2.length; i++) {
  if (mouseX >= p2[i].x && mouseX <= p2[i].x + playerWidth && mouseY >= p2[i].y && mouseY <= mouseY + playerHeight) {
    return true;
  }
  else {
    return false;
  }
}
}
document.body.onclick = function() {
    if (canShoot(player, event)) {
    console.log(true)
  }
}

请注意,我将变量更改为数组。

let player = [];

这样,您可以检测是否点击了任何玩家,而不仅仅是循环中的最后一个玩家(您的玩家)。然后,我在这里添加了一个循环:

for (var i = 0; i < p2.length; i++) {
  if (mouseX >= p2[i].x && mouseX <= p2[i].x + playerWidth && mouseY >= p2[i].y && mouseY <= mouseY + playerHeight) {
    return true;
  }
  else {
    return false;
 }
}

这将循环查看是否有任何玩家被点击。

最后,我改变了这个:

player = players[id];

为此:

player[player.length] = players[id];

让每个玩家在阵列中都有自己的位置,这样您就可以让多个玩家检查,而不仅仅是您自己。