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!
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?