Как сделать переподключение клиента, socket.io

386
05 октября 2021, 04:00

Делаю игру, похожую на agar.io, имеется много клиентов, реализовано с помощью socket.io в Node.js и с помощью p5.js. Если 1-ый игрок съедает 2-го игрока, и радиус круга 1-го игрока больше радиуса 2-го, то радиус 1-го игрока увеличивается, а круг 2-го игрока должен исчезнуть(убираю из массива этот круг) и переподключиться к серверу снова, но уже в другом месте и с меньшим размером. Как сделать это переподключение? В коде Sketch.js есть комментарии после строчки "if (blob.eats2(blobs[i]) == 1) {", в котором я попытался это сделать, т.е. когда 1-ый игрок "ест" 2-го, я создаю новый объект(круг), передаю на сервер id съеденного игрока, и вместе с ними координаты и размер нового круга, в Server.js принимаю эти данные, и создаю новый объект, которому присваиваю переданные данные, в том числе id только что съеденного игрока(т.е. клиент не переподключается, а ему создаётся только новый круг). В следующей строчке в Sketch.js "socket.emit('disconnect2', data2);" я снова передаю данные на сервер, и удаляю "съеденный" круг из массива. Вопрос в том, правильно ли я это делаю, т.к. Node.js выдаёт ошибку при создании круга для съеденного игрока. Или лучше сделать переподключение клиента и давать ему новое id?

Server.js:

var blobs = [];
function Blob(id, x, y, r) {
  this.id = id;
  this.x = x;
  this.y = y;
  this.r = r;
}
// Using express: http://expressjs.com/
var express = require('express');
// Create the app
var app = express();
// Set up the server
// process.env.PORT is related to deploying on heroku
var server = app.listen(3000, listen);
// This call back just tells us that the server has started
function listen() {
  var host = server.address().address;
  var port = server.address().port;
  console.log('Example app listening at http://' + host + ':' + port);
}
app.use(express.static('public'));

// WebSocket Portion
// WebSockets work with the HTTP server
var io = require('socket.io')(server);
setInterval(heartbeat, 33);
function heartbeat() {
  io.sockets.emit('heartbeat', blobs);
}
// Register a callback function to run when we have an individual connection
// This is run for each individual user that connects
io.sockets.on('connection',
  // We are given a websocket object in our function
  function(socket) {
    console.log("We have a new client: " + socket.id);
    socket.on('start',
      function(data) {
        console.log(socket.id + " " + data.x + " " + data.y + " " + data.r);
        var blob = new Blob(socket.id, data.x, data.y, data.r);
        blobs.push(blob);
      }
    );
    socket.on('update',
      function(data) {
        //console.log(socket.id + " " + data.x + " " + data.y + " " + data.r);
        var blob;
        for (var i = 0; i < blobs.length; i++) {
          if (socket.id == blobs[i].id) {
            blob = blobs[i];
          }
        }
        blob.x = data.x;
        blob.y = data.y;
        blob.r = data.r;
      }
    );
    socket.on('disconnect', function() {
      console.log("Client has disconnected");
       var blob;
       var m;
        for (var i = 0; i < blobs.length; i++) {
          if (socket.id == blobs[i].id) {
            m=i;
          }
        }
        blobs.splice(m,1);
    });
    socket.on('disconnect2', function(data) {
      console.log("Client" +socket.id +"has respawned");
       var blob;
       var m;
        for (var i = 0; i < blobs.length; i++) {
          if (blobs[i].id == data.id1) {
            m=i;
          }
        }
        blobs.splice(m,1);
        socket.on('start2',
      function(data) {
        console.log(data.id1 + " " + data.x + " " + data.y + " " + data.r);
        var blob = new Blob(data.id1, data.x, data.y, data.r);
        blobs.push(blob);
      }
    );
        });
  }
);

Blob.js:

function Blob(x, y, r) {
  this.pos = createVector(x, y);
  this.r = r;
  this.vel = createVector(0, 0);
  var flag = -1;
  this.update = function() {
    var newvel = createVector(mouseX - width / 2, mouseY - height / 2);
    newvel.div(50);
    //newvel.setMag(3);
    newvel.limit(3);
    this.vel.lerp(newvel, 0.2);
    this.pos.add(this.vel);
  }
  this.eats = function(other) {
    var d = dist(this.pos.x,this.pos.y, other.pos.x,other.pos.y);
    if (d < this.r + other.r) {
      var sum = PI * this.r * this.r + PI * other.r * other.r;
      this.r = sqrt(sum / PI);
      return true;
    } else {
      return false;
    }
  }
   this.eats2 = function(other) {
     var d = dist(this.pos.x,this.pos.y, other.x,other.y);
      if (d < this.r + other.r) {
      var sum = PI * this.r * this.r + PI * other.r * other.r;
      if(this.r>other.r){
        this.r = sqrt(sum / PI);
        flag = 1;
      }
      else if(this.r<other.r){
        other.r = sqrt(sum / PI);
        flag = 2;
      }
      return flag;
    } else {
      return false;
    }
  }
  this.constrain = function() {
    blob.pos.x = constrain(blob.pos.x, -width / 2, width / 2);
    blob.pos.y = constrain(blob.pos.y, -height / 2, height / 2);
  }
  this.show = function() {
    fill(255);
    ellipse(this.pos.x, this.pos.y, this.r * 2, this.r * 2);
  }
}

Sketch.js:

var socket;
var blob;
var blobs = [];
var blobz = [];
var zoom = 1;
function setup() {
  createCanvas(600, 600);
  // Start a socket connection to the server
  // Some day we would run this server somewhere else
  socket = io.connect('http://localhost:3000');
 for (var i = 0; i < 200; i++) {
    var x = random(-width,width);
    var y = random(-height,height);
    blobz[i] = new Blob(x, y, 4);
  }
  blob = new Blob(random(width), random(height), random(8, 24));
  // Make a little object with x and y
  var data = {
    x: blob.pos.x,
    y: blob.pos.y,
    r: blob.r
  };
  socket.emit('start', data);
  socket.on('heartbeat',
    function(data) {
      // console.log(data);
      blobs = data;
    }
  );
}
function draw() {
  background(0);
  // console.log(blob.pos.x, blob.pos.y);
  translate(width / 2, height / 2);
  var newzoom = 64 / blob.r;
  zoom = lerp(zoom, newzoom, 0.1);
  scale(zoom);
  translate(-blob.pos.x, -blob.pos.y);
  // for (var i = blobz.length-1; i >=0; i--) {
  //   blobz[i].show();
  //   if (blob.eats(blobz[i])) {
  //     blobz.splice(i, 1);
  //   }
  // }

  for (var i = blobs.length - 1; i >= 0; i--) {
    var id = blobs[i].id;
      if (id !== socket.id) {
      fill(0, 0, 255);
      ellipse(blobs[i].x, blobs[i].y, blobs[i].r * 2, blobs[i].r * 2);
      fill(255);
      textAlign(CENTER);
      textSize(4);
      text(blobs[i].id, blobs[i].x, blobs[i].y + blobs[i].r);
    if (blob.eats2(blobs[i]) == 1) {
      // blob = new Blob(random(width), random(height), random(8, 24));
      // var data2 = {id1:blobs[i].id,
      //                x: blob.pos.x,
      //                y: blob.pos.y,
      //                r: blob.r};
      // socket.emit('start2', data2);
      // socket.emit('disconnect2', data2);
      console.log(1);
     }
     else if (blob.eats2(blobs[i]) == 2) {
      console.log(2);
     }
     else {
      console.log(-1);
     }
    }
  }
  blob.show();
  if (mouseIsPressed) {
    blob.update();
  }
  blob.constrain();
  var data = {
    x: blob.pos.x,
    y: blob.pos.y,
    r: blob.r
  };
  socket.emit('update', data);
   }
READ ALSO
Отсеивание по категориям React

Отсеивание по категориям React

Привет! Есть такая проблема, есть категории(тип, торговая марка) у них есть подкатегорииУсловный бренд а, б, в

172
AJAX передает пустой $_POST

AJAX передает пустой $_POST

Всем доброго дня!

110