0

Node Socket.IO で問題が発生しています

すべてのコードをペーストビンに入れました

サーバーファイル

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

オブジェクトが 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 に答える
2

私が知っていることから、Socket.IOは出力関数の2番目のパラメーターとしてJSONデータを期待していました。JSON データ形式は、 http://www.json.org/に従って関数を値としてサポートしていません

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 に答える