0

我在使用 Node Socket.IO 时遇到了一些问题

我已将所有代码放入 pastebins

服务器文件

var io = require("socket.io").listen(1337);

io.set("log level", "0");

var particles = [];
var players = [];
var remove_loop;
var particle;



io.sockets.on("connection", function(socket) {

    //connection
    socket.emit("hello");
    console.log("A new connection has been established");

    //new player
    socket.on("new_player", function() {
        players.push(socket.id);
        console.log("New player connected.");
        console.log("ID: " + socket.id);
    });

    //new particle
    socket.on("new_particle", function(data) {
        particle = data;
        socket.broadcast.emit("particles_data", particle);
    });

});

游戏文件

window.onload = function() {

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");

    //display settings
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    setInterval(function() {
        if(canvas.width != window.innerWidth || canvas.height != window.innerHeight) {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        }
    }, 1000);

    //remove cursor
    document.getElementById("canvas").style.cursor = "none";

    //server connection
    var socket = io.connect("http://localhost:1337");


    //variables
    var update_loop;
    var draw_loop;
    var local_player;
    var mouse_x;
    var mouse_y;
    var remote_players;
    var particles;
    var remove_loop;
    var explosion;
    var background_color;


    init();
    function init() {
        //initialize

        local_player = new Player();
        background_color = "000000";
        explosion = true;
        remote_players = [];
        particles = [];

        draw_loop = setInterval(function() { draw(); }, 10);
        update_loop = setInterval(function() { update(); }, 10);

        //server
        socket.on("hello", function() {
            socket.emit("new_player");
        });

        socket.on("particles_data", function(data) {
            particles.push(data);
        });

    };


    function update() {

        for(var i = 0; i < particles.length; i++) {
            particles[i].move();
        }

    };


    function draw() {
        //background_color
        ctx.fillStyle = "#" + background_color;
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        //remove particles
        setInterval(function() {
        if(!remove_loop) remove_loop = setInterval(function() {
                setTimeout(function() {
                    if(particles.length > 0) {
                        particles.shift();
                    }
                }, 1); 
            }, 20);
    }, 10);

        //particles
        for(var i = 0; i < particles.length; i++) {
            if(particles[i].x < canvas.width &&
                particles[i].y < canvas.width) {
                if(particles[i].x < canvas.width &&
                    particles[i].y < canvas.height) { 
                    particles[i].draw(ctx);
                }
            }
        }

    }

    function newParticle() {
        socket.emit("new_particle", new Particle(local_player.x, local_player.y, local_player.color));
        particles.push(new Particle(local_player.x, local_player.y, local_player.color));
    };

    //move mouse
    canvas.onmousemove = function(event) {
        if(!event) event = window.event;
        local_player.x = event.pageX;
        local_player.y = event.pageY;

        newParticle();
    };

    //touch mouse (phones/tables)
    canvas.onmousedown = function(event) {
        if(!event) event = window.event;
        local_player.x = event.pageX;
        local_player.y = event.pageY;

        newParticle();
    }

};

播放器文件

function Player() {
    this.x = 0;
    this.y = 0;
    this.color = Math.floor(Math.random() * 999999);
    while (this.color < 100000) {
        this.color = Math.floor(Math.random() * 999999);
    }
};

粒子文件

function Particle(x, y, color) {
    this.start_x = x;
    this.start_y = y;
    this.speed = Math.floor(Math.random() * 3 + 1);
    this.x = x;
    this.y = y;
    this.size = Math.floor(Math.random() * 3 + 1);
    this.color = "#" + color;
    this.direction = Math.floor(Math.random() * 8);
    this.move = function() {
        this.speedDecreaseChance = Math.random(Math.random() * 100);
        //Chance that the particle loses it's velocity like you would
        //see with real particles
        if(this.speedDecreaseChance > 3) { this.speed -= 0.5 };
        //It's important that they move -AWAY- from X and Y.
        this.subDirection = Math.floor(Math.random() * 2);
        if(this.direction == 0) { //upper left
            if(this.subDirection == 0) {
                this.x -= this.speed;
            } else if(this.subDirection == 1) {
                this.y -= this.speed;
            } 
        } else if(this.direction == 1) { //bottom right
            if(this.subDirection == 0) {
                this.x += this.speed;
            } else if(this.subDirection == 1) {
                this.y += this.speed;
            }
        } else if(this.direction == 2) { //upper right
            if(this.subDirection == 0) {
                this.x += this.speed;
            } else if(this.subDirection == 1) {
                this.y -= this.speed;
            } 
        } else if(this.direction == 3) { //bottom left
            if(this.subDirection == 0) {
                this.x -= this.speed;
            } else if(this.subDirection == 1) {
                this.y += this.speed;
            }
        } else if(this.direction == 4) { //left
            this.x -= this.speed/1.5;
            if(this.subDirection == 0) {
                this.y -= this.speed;
            } else if(this.subDirection == 1) {
                this.y += this.speed;
            }
        } else if(this.direction == 5) { //up
            this.y -= this.speed/1.5;
            if(this.subDirection == 0) {
                this.x -= this.speed;
            } else if(this.subDirection == 1) {
                this.x += this.speed;
            }
        } else if(this.direction == 6) { //right
            this.x += this.speed/1.5;
            if(this.subDirection == 0) {
                this.y -= this.speed;
            } else if(this.subDirection == 1) {
                this.y += this.speed;
            }
        } else if(this.direction == 7) { //down
            this.y += this.speed/1.5;
            if(this.subDirection == 0) {
                this.x -= this.speed;
            } else if(this.subDirection == 1) {
                this.x += this.speed;
            }
        }
    };
    this.draw = function(ctx) {
        ctx.beginPath();
        ctx.shadowColor = this.color;
        ctx.shadowBlur = 8;
        ctx.arc(this.x, this.y, this.size ,0 ,2*Math.PI);
        ctx.fillStyle = this.color;
            ctx.fill();
        ctx.shadowBlur = 0;
    };
};

现在的问题是服务器和所有套接字之间的流量存在错误。我想要做的是使当一个人有粒子对象将它们发送到服务器并且服务器将它们发送给除了原始发送者之外的所有人时成为可能。

我是通过 socket.broadcast.emit(); 这很成功。

但是,当对象到达其他套接字时,我收到此错误:

Uncaught TypeError: Object #<Object> has no method 'move'
Uncaught TypeError: Object #<Object> has no method 'draw' 

对于当时存在的每个粒子对象。如果有人知道为什么我的对象会丢失它们的方法并且会如此友好地帮助处于困境中的程序员,我会非常高兴:)

提前致谢!

4

2 回答 2

2

据我所知,Socket.IO 期望 JSON 数据作为发射函数的第二个参数。根据http://www.json.org/,JSON数据格式不支持作为值的函数

您正在发送一个 javascript 对象,并期望从不同客户端上的 json 创建该对象。这不是 Socket.IO 通信的工作方式。

而不是这样做,您应该发送构造对象所需的数据并使用它在客户端上构造对象。

您可以执行以下操作

更改此行

socket.emit("new_particle", new Particle(local_player.x, local_player.y, local_player.color));

socket.emit("new_particle", {x:local_player.x, y:local_player.y, color:local_player.color});

然后是事件监听器

socket.on("particles_data", function(data) {
  particles.push(data);
});

处理从数据创建对象

socket.on("particles_data", function(data) {
  particles.push(new Particle(data.x, data.y, data.color));
});
于 2013-07-04T09:57:45.343 回答
2

当一个对象被序列化为 JSON 时,它会丢失所有类型信息。这就是 socket.io 正在传输的内容。

var particle = new Particle(1, 2, 'ccc');
console.log(JSON.stringify(particle)); // {"start_x":1,"start_y":2,"speed":3,"x":1,"y":2,"size":3,"color":"#ccc","direction":5} 

你无法分辨它是粒子还是猴子或其他东西。

当您收到此对象时,您需要将其转换为Particle第一个。

socket.on("particles_data", function(data) {
    var particle = ...;
    particles.push(particle);
});

您可以定义一个构造函数并再次创建它:

var particle = new Particle(data.x, data.y, data.color);

或者你可以改变它的原型:

var particle = $.extend(new Particle(), data); // here using jQuery helper method
于 2013-07-04T10:21:03.737 回答