使用 socket.io 发射数组

Emitting an array using socket.io

为了学校项目,我正在使用 socket.io 制作一款多人贪吃蛇游戏。我试图同步你玩的蛇的 body(snake1,这是一个以向量为位置的数组。蛇本身是 objects),并将其与 socket.io 一起发送给另一个播放器。要发送 body,我使用 socket.emit('snakeBody', snake1.body)。但是当我加载页面时,出现错误 "Uncaught RangeError: Maximum call stack size exceeded"。我首先认为它是数组,但是当我尝试将普通变量与向量同步时,我仍然遇到错误(当我同步普通变量或数组时,其中没有向量,它确实有效)。我的问题是是否可以使用 socket.io.

将数组与向量作为值同步

index.js 文件(所有套接字发生的文件):

var express = require('express');
var app = express();

var server = app.listen(3000);
app.use(express.static('public'));

console.log("The server is live");

var socket = require('socket.io');
var io = socket(server);

io.sockets.on('connection', newConnection);

function newConnection(socket) {
  socket.on('snakeBody', body);

  function body(data) {
    socket.broadcast.emit('testBody', data);
  }
}

game.js文件(游戏的基础。套接字发送和接收的地方)

//Defines both snakes
var snake1;
var snake2;

var socket;

function setup() {
  //The canvas for p5js to show something
  createCanvas(400, 400);

  //The starting location for the snakes (the snakes are objects in a class)
  snake1 = new Snake(200, 200);
  snake2 = new Snake(150, 250);

  //Socket server ip
  socket = io.connect('https://myIP.com');
  socket.on('snakeBody', newSnake);
}

function draw() {
  background(0);

  snake1.loop(255, 0, 0, 1, 340);

  //Sends all the players data to the server to be send to the other player
  socket.emit('snakeBody', snake1.body);
}


function newSnake(newSnake) {
  //The function that will do thing when it receives something from the socket
}

蛇class: 它可能会调用这部分中不存在的函数,但那是因为我删除了它们,因为它们对这个问题并不直接重要。

class Snake {

  //----------------------------------------------//
  //                 Snake Setup:                 //
  //----------------------------------------------//

  //Contains all building info
  constructor(x, y) {
    //Snake elements:
    this.body = [];
    this.body[0] = createVector(x, y);
    this.head = '';
    this.part = '';

    //Game elements:
    //Dimension
    this.dim = 10;
    //Direction 
    this.x = 0;
    this.y = 0;
    //Speed 
    this.s = 2;
    //Score
    this.scoreLeng = 0;
  }

  //Contains all functions that needs to be looped
  loop(r, g, b, p, t) {
    //Move and update
    this.move(p);
    this.update();

    //If snake is dead
    if (this.gameOver()) {
      //Respawn
      this.respawn(p);
    }

    //If snake eat
    if (this.eat(food)) {
      //Grow
      this.grow();
      //Update food location
      food.update();
      //Play eat sound
      // eatSound.play();
    }
    //Show snake
    this.show(r, g, b, t);
  }

  //----------------------------------------------//
  //            All snake functions:              //
  //----------------------------------------------//

  show(r, g, b, t) {
    //Loop thru every body part of array
    for (var i = 0; i < this.body.length; i++) {
      //Rectangle with rgb color:
      fill(r, g, b);
      noStroke();
      rect(this.body[i].x, this.body[i].y, this.dim, this.dim);
    }
    //Score text:
    textSize(17);
    text("score:" + this.scoreLeng, t, 395);
  }

  dir(x, y) {
    //Directions:
    this.x = x;
    this.y = y;
  }

  update() {
    //Copy of the last element of the array:
    this.head = this.body[this.body.length - 1].copy();
    //Shift the array
    this.body.shift();

    //Add direction to snake location
    this.head.x += this.x;
    this.head.y += this.y;

    //Push head to end of array
    this.body.push(this.head);
  }

  gameOver() {
    //If snake is outside play area 
    if (this.head.x == 400 || this.head.y == 400 || this.head.x < 0 || this.head.y < 0) {
      return true;
    }

    //Loop thru body parts in array
    for (var i = 0; i < this.body.length - 1; i++) {
      //Alle body parts in part variable
      this.part = this.body[i];
      //If head of snake hits part
      if (this.part.x == this.head.x && this.part.y == this.head.y) {
        return true;
      }
    }

    //Loop thru body array
    for (var j = 0; j < this.body.length - 1; j++) {
      //If snake 1 or snake 2 head hits parts of other snake
      if (snake1.head.x == this.body[j].x && snake1.head.y == this.body[j].y) {
        console.log("snake 1 is dead");
      }
      if (snake2.head.x == this.body[j].x && snake2.head.y == this.body[j].y) {
        console.log("snake 2 is dead");
      }
    }

    return false;
  }
}

当您收到“超过最大调用堆栈大小”错误时,这意味着您在代码中的某处调用了一个函数,该函数又调用了另一个函数,依此类推,直到达到调用堆栈限制。我我不确定这将如何适用于您的情况,您分享的内容不多。

我对您的快速建议是将数据作为字符串发送:

socket.emit('snakeBody', JSON.stringify(snake1.body))

然后在另一端解析它:

const snakeBody = JSON.parse(snakeBody)