使用socket.io发射数组 [英] Emitting an array using socket.io

查看:59
本文介绍了使用socket.io发射数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于一个学校项目,我正在使用socket.io制作多人蛇游戏.我试图同步您玩耍的蛇的身体(snake1,这是一个将向量作为位置的数组.蛇本身就是对象),并使用socket.io将其发送给其他玩家.要发送正文,请使用 socket.emit('snakeBody',snake1.body).但是,当我加载页面时,出现错误未捕获的RangeError:超出最大调用堆栈大小".我最初以为是数组,但是当我尝试将正态变量与向量同步时,仍然出现错误(当我同步正态变量或数组时,其中没有向量,它确实可以工作).我的问题是,是否可以使用socket.io将带有向量的数组与值同步.

For a school project I'am making a multiplayer snake game with socket.io. I tried to sync the body of the snake you play (snake1, which is an array with vectors as location. The snakes them self are objects) and send that with socket.io to the other player. To send the body I use socket.emit('snakeBody', snake1.body). But when I load the page i get the error "Uncaught RangeError: Maximum call stack size exceeded". I first thought it was the array but when i try to sync a normal variable with a vector i still got the error (when i sync normal variables or arrays, without a vector in it, it does work). My question is if it is possible to sync an array with a vectors as values using socket.io.

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

The index.js file (the file where all the socket things happen):

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文件(游戏的基础.套接字发送和接收的位置)

The game.js file (the base of the game. Where the socket sends and receives)

//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
}

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

The snake class: It is possible that it will call function that do not exist in this part but thats because I removed them because they were not directly important for this question.

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;
  }
}

推荐答案

当您收到超出最大调用堆栈大小"错误时,这意味着在代码中的某个地方,您正在调用一个函数,该函数又调用另一个函数,并且如此反复,直到您达到调用堆栈限制为止.我不确定这在您的情况下如何适用,您分享的内容并不多.

When you get a `Maximum call stack size exceeded" error, it means that somewhere in your code, you are calling a function which in turn calls another function and so forth, until you hit the call stack limit. I'm not sure how that would apply in your case here, you're not sharing much.

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

My quick suggestion for you would be to send your data as string:

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

然后在另一端进行解析:

Then on the other end, parse it:

const snakeBody = JSON.parse(snakeBody)

这篇关于使用socket.io发射数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆