Setting socket data over draw background || scope problem?

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!

1 Like

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

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.

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


1 Like

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
2 Likes

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