socket.iophaser-framework

Troubles with using Socket.io and Phaser 3


I’m following a walkthrough on creating a Multiplayer Card Game using Phaser 3 and Socket.io Linked here: https://www.youtube.com/watch?v=6KaGqh1spfs&list=PLCbP9KGntfcEDAiseVwYVbrmJdoYajNtw&index=6

But when implementing the socket.io, it has an error:

Cannot set properties of undefined (setting 'socket')

TypeError: Cannot set properties of undefined (setting 'socket')

Below is the current relevant code I have:

const server = require('express')();
const http = require('http').createServer(server);
const cors = require('cors');
const shuffle = require('shuffle-array');
let players = {};
let readyCheck = 0;

const io = require("socket.io")(http, {
    cors:{
        origin:'http://localhost:8080',
        methods:["GET", "POST"]
    }
});

io.on('connection', function (socket) {
    console.log('A User Connected: ' + socket.id);

    players[socket.id] = {
        inDeck: [],
        inHand: [],
        isPlayerA: false
    }

    if (Object.keys(players).length < 2) {
        players[socket.id].isPlayerA = true;
        io.emit('firstTurn');
    }

    socket.on('dealDeck', function(socketId) {
        players[socketID].inDeck = shuffle(["boolean", "ping"]);
        console.log(players);
        if(Object.keys(players).length < 2) return;
        io.emit('changeGameState', "Initializing")
    })
})

http.listen(3000, function () {
    console.log('Server Started!');
})

Additionally:

import io from 'socket.io-client';

export default class SocketHandler {
    constructor(scene){

        // Port 3000 is where the server is listening to as well
        scene.socket = io('http://localhost:3000');

        // Log that the connection is established, Activate the "Deal Cards""
        scene.socket.on('connect', () => {
            console.log('Connected!');
            scene.scoket.emit('dealDeck', scene.socket.id);
        })

        // When acknowledging that the first turn is commencing, change the turn
        scene.socket.on('firstTurn', () => {
            scene.GameHandler.changeTurn();
        })

        // Recieve the current "Game State" and respond accordingly
        scene.socket.on('changeGameState', (gameState) => {
            scene.GameHandler.changeGameState(gameState);

            // If Initializing, Deal one card each to signify which card back
            if (gameState === "Initializing") {
                scene.DeckHandler.dealCard(1000, 860, "cardBack", "playerCard");
                scene.DeckHandler.dealCard(1000, 125, "cardBack", "opponentCard");

                // Set the Deal Cards button to interactive, and change its colour to signify
                scene.dealCards.setInteractive();
                scene.dealCards.setColor('#00ffff');
            }
        })

        // If the socketID is the same as the one recieved
        scene.socket.on('dealCards', (socketId, cards) => {
            if (socketId === scene.socket.id) {

                // Give the player the cards, offset the cards so they aren't all stacked
                for (let i in cards) {
                    let card = scene.GameHandler.playerHand.push(scene.DeckHandler.dealCard(155 + (i * 155), 860, cards[i], "playerCard"));
                }

                // Otherwise, deal the opponent "card backs"
            } else {
                for (let i in cards) {
                    let card = scene.GameHandler.opponentHand.push(scene.DeckHandler.dealCard(155 + (i * 155), 135, "cardBack", "opponentCard"));
                }
            }
        })

        scene.socket.on('cardPlayed', (cardName, socketId) => {
            if (socketId !== scene.socket.id) {

                // Remove cards from opponents hand when played
                scene.GameHandler.opponentHand.shift().destroy();
                scene.DeckHandler.dealCard(scene.dropZone.x, scene.dropZone.y, cardName, "opponentCard");
            }
        })
    }
}

Any ideas / suggestions for fixes are greatly appreciated!


Solution

  • Due to my assumptions and the comment

    "...SocketHandler is being called in game.js, during the create() function. I believe that scene.socket = io('http://localhost3000'); is indeed the problem, as it's what the console identifies..."

    The issue has to do with the fact, that your are calling new SocketHandler(), without a parameter, or the variable you are passing as a parameter is undefined.

    Without seeing more relevant code, this is as far as an resolution can go.

    Tipp: Checking the original code of the tutorial, I would have to say check the game.js file in the scenes folder. Are you really calling the SocketHandler, there as in the provided code this.SocketHandler = new SocketHandler(this); and are you passing this as parameter?