Setting socket data over draw background || scope problem?


#1

Hi,

I just created this account because i spent two entire afternoons trying to debug the following code: (As of now it doesn’t work (but i feel like it should))

With the risk of asking a question with an obvious answer, her goes:

1 Description of problem
I recreated the link to sockets.io made by Daniel Shifman in his introduction to sockets. With this I made a send data to a server concerning the postion of every ship in play.

This data is communicated well enough and i receive the x position from other browsers. With this I want to draw the other )from another browser’ in the client window.

When iI console.log the data it displays fine. However when I attempt draw something with this x-value it does not display over my background. (it works if i cancel out the background).

Any suggestions as to how i can visualise my data?

Things i’ve tried:

  • Setting a referencing function in draw()
  • attempting to data to another variable
  • Moving the function as to where the data is called around throughout my project.
  • sending the data over to draw as a parameter
  • changing the parameters ( name and function calls --> seems silly but one does what one can)
  • I tried moving the background call but it is essential that it remains in draw for the rest of my project to display correctly.

As i receive data form sockets, the data from the other browser is received correctly but the data from the “own” is set to undefined.
I have no clue as to why but since it is the other ship i wanted to display i went along and filtered the undefined data out.

I’ve uploaded a screenshot of my project running with the console open. As you can see here the x-data from the other browser is displayed.

How do I manipulate it so that the background does not override this data?

Below you can see a screenshot of newDrawing function (which is displaying the x in the console but is not showing the rectangle)

Only p5.js and socket.io are used in this project.

I would sincerely like to know how i can make my dreams happen and as to why this problem is tearing my brain into pieces.

Any advice would be much appreciated!


#2

Since I could only upload one image. See the newDrawing function here newdrawing


#3

Would you mind posting you sketch code and your server code? If you don’t know how to do that use ``` ``` and then paste your code within the back ticks.


#4

Not at all, Although I must apologize. I can make a wonderous mess of things.
I also added the ship.js file just in case.

--- Server code: --- 
var express = require('express');
var app = express();
var server = app.listen(3000);
app.use(express.static('public'));
console.log("my server is running");
var socket = require('socket.io');
var io = socket(server);
io.sockets.on('connection', newConnection);

function newConnection(socket) {
    console.log('new connection' + socket.id);
    console.log(socket.id);
    socket.on('ship', mouseMsg); //FUNCTIE VOOR ONTVANGEN VAN DATA --> mouseMsg 
    function mouseMsg(data) {
        //io.sockets.on('ship', data);
        console.log(data.x);
        var moreData = data.x;
        socket.broadcast.emit('ship', moreData); //DATA TERUG NAAR CLIENT
        //        if (socket.id == socket.id){
        //            socket.broadcast.emit('ship', data);
        //        }
        //io.sockets.emit('ship', data); //DEZE STUURT NAAR IEDEREEN INCL. ZELF
        console.log(data.x);
    }
}

--- Sketch ---
var socket;
var drops = [];
var lifes = [];
var ship;
var score = 0;
var highscore = 0;
var lifelost = false;
var spliceIt = false;
var myVar;

function setup() {
    createCanvas(innerWidth, innerHeight);
    for (var i = 0; i < 10; i++) {
        drops[i] = new Drop();
    };
    socket = io.connect('http://localhost:3000'); // maakt connectie met de server vanaf de client
    //socket.on('mouse', newDrawing);
    resetSketch();
    socket.on('ship', newDrawing);
}

function newDrawing(moreData) {
    if (moreData !== undefined) {
        console.log(moreData);
        noStroke();
        fill(255, 0, 100);
        rect(moreData, height - 60, 20, 60);
    }
}

function mouseDragged(Ship) {
    //console.log(ship);
    var data = {
        x: ship.x
        , y: ship.y
        , w: ship.w
        , h: ship.h
    };
    //console.log(data.x);
    socket.emit('ship', data); // Emit is de brug naar de server
} //EINDE mouseDragged
function scoreIt() {
    this.score++;
    textSize(32);
    text(score, 10, 30);
    text(this.highscore, 10, 60);
} //EINDE scoreIt
function loseLife() {
    lifelost = true;
    if (lifelost === true) {
        clearTimeout(myVar)
    }
} //EINDE loseLife            
function eindSpel() {
    if (lifes.length === 0) {
        alert("You got wet");
        resetSketch();
    } //EINDE IF
} //EINDE EINDSPEL
//HIER BEGINT DE DRAW FUNCTIE
function resetSketch() {
    ship = new Ship();
    this.highscore = 0;
    //        var data = {
    //        x: ship.x, 
    //        y: ship.y,
    //        w: ship.w,
    //        h: ship.h,
    //        score: highscore
    //    }
    for (var i = 0; i < 3; i++) {
        lifes[i] = new Life();
    };
    //socket.emit('ship', data) // Emit is de brug naar de server
} //EINDE RESETSKETCH
function draw(moreData) {
    background(228, 246, 255);
    //BEGIN DROP HITS SHIP
    for (var i = 0; i < drops.length; i++) {
        if (frameCount % 40 == 0) {
            drops[i].push = new Drop();
        }
        if (drops[i].hits(ship)) {
            drops[i].highlight();
            if (this.score > this.highscore) {
                this.highscore = this.score;
            }
            this.score = 0;
            myVar = setTimeout(loseLife, 250);
            eindSpel();
        } //EINDE IF DROPS HIT SHIP
        drops[i].show();
        drops[i].fall();
    } //EINDE FOR DROPS
    for (var j = lifes.length - 1; j >= 0; j--) {
        stroke(51);
        if (lifelost === true) {
            lifelost = false;
            lifes.splice(j, 1);
            console.log("happened");
        } //Einde if spliceIT
        line(innerWidth - 15 * j, 30, innerWidth - 15, 60);
    } //EINDE FOR LIFES ARRAY
    ship.show();
    ship.move();
    ship.limit();
    scoreIt();
    mouseDragged();
    newDrawing();
} //EINDE DRAW
function keyReleased() {
    if (key != ' ') {
        ship.setDir(0);
    }
}

function keyPressed() {
    if (keyCode === RIGHT_ARROW) {
        ship.setDir(1);
    }
    else if (keyCode === LEFT_ARROW) {
        ship.setDir(-1);
    }
}

--- ship ---
function Ship() {
    this.x = width / 2;
    this.xdir = 0;
    this.y = height - 60;
    this.w = 20;
    this.h = 60;
    this.show = function () {
        fill(51);
        rect(this.x, this.y, this.w, this.h);
    }
    this.setDir = function (dir) {
        this.xdir = dir;
    }
    this.move = function (dir) {
        this.x += this.xdir * 8;
        //  this.x = mouseX;
        //this.y = mouseY;
    }
    this.limit = function () {
            if (this.x < 0) {
                this.x = innerWidth;
            } //IF
            else if (this.x > innerWidth) {
                this.x = 0;
            } //ELSE IF
        } //LIMIT
} //:CONSTRUCTOR



#5

As you know, draw() is called back at about 60 frameRate() by default: :paintbrush:

  1. p5js.org/reference/#/p5/draw
  2. p5js.org/reference/#/p5/frameRate

It also means your background() clears the canvas at that same FPS: :flying_saucer:
p5js.org/reference/#/p5/background

So it’s pretty much moot to draw inside a callback. It’d last 1 blink frame only after all: :roll_eyes:

Either store the data received inside your callback in some global variable in order to display it later under draw() or… do the drawing in a separate p5.Graphics via createGraphics(): :bulb:

  1. p5js.org/reference/#/p5/createGraphics
  2. p5js.org/reference/#/p5.Graphics

#6

Thanks a bunch for the advice and steering me in the right direction.