0

I'm having some trouble with Node Socket.IO

I have put all my code in pastebins

Server file

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

});

Game file

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

};

Player file

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

Particle file

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

Now the problem is that there's an error in my traffic between the server and all sockets. What I want to do is make it possible that when one has particle objects to send them to the server and the server sends them to everyone except the original sender.

I did this through socket.broadcast.emit(); This went successful.

However when the objects arrive at the other sockets I get this error:

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

For every particle object that exists at that moment. If anyone knows why my objects lose their methods and would be so friendly to help a programmer in distress I'd be absolutely delighted :)

Thanks in advance!

0

2 Answers 2

2

From what I know Socket.IO expected JSON data as 2nd parameter for the emit function. JSON data format doesn't support function as values according to http://www.json.org/

You are sending a javascript object and expecting the object to be created from the json on a different client. This is not how Socket.IO communication works.

Instead of doing that you should send the data required to construct the object and use that to construct the object on the client.

You could do some thing like the following

Change this line

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

to

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

and then the event listener

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

to handle the creation of object from the data

socket.on("particles_data", function(data) {
  particles.push(new Particle(data.x, data.y, data.color));
});
Sign up to request clarification or add additional context in comments.

2 Comments

So how would I do this? Do I send the Particle() function? and how would I send this? I've never worked with JSON.
This actually helps alot, thanks! I think it makes sense actually to do it this way then to send an actual object.
2

When an object is serialized to JSON, it loses all type information. This is what socket.io is transmitting.

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} 

You can't tell if it's a particle or a monkey or something else.

When you receive this object, you need to convert it to a Particle first.

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

You could define a constructor and create it again:

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

Or you could change its prototype:

var particle = $.extend(new Particle(), data); // here using jQuery helper method

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.