简体   繁体   中英

How to make a room system with socket.io?

I'm creating a multiplayer game, so far so good but I was testing a room system I made a while back that I was using now and it seems that when I try to load into the game that has more than 2 worlds (and they are both full) the server infinitely creates more and more worlds... Which its supposedly only meant to create one!

I basically have an array where i store all the worlds (rooms) like so: let Worlds = [{/*World 0*/},{/**Worlds 1/}, /*ect, ect*/]

So here is the room system: (Check all the comments in this script for a better understanding)

let PlayersRoom;
let PlayersIndex;

for (let index = 0; index < Worlds.length; index++) {//Checks every single world
    if (Worlds[index].Players.length >= maxplayerlimit){ //Checks if the world is maxed out in players
        if (index == Worlds.length - 1) {//checks if its the last iteration in the loop
            Worlds.push(worldtemplate);//Creates a new world
            index = 0; //restarts the loop
        }
    } else {//Room has available slot
        client.join("World " + index);//Join the room
        PlayersRoom = index;//Set the players room to this index
        break;//stop the loop
    }
}

So, I went to a different approach where i would create a server browser and every 10 or so seconds i would ask the server an update on all the worlds created in the server like so:

let serverlist = []

function requestServerList() {
    socket.emit('UpdateServerList')//Ask the server for an update on the server list.
    document.getElementById('serverlist').innerHTML = 'Reloading...' //clear the Dom element
    serverlist = []//clear the array
}

socket.on("GetServerInfo", UpdateServerList(Data) => {
    if (!Data.isserver) {//If there is a server that exists!
        document.getElementById('serverlist').innerHTML = 'No Rooms Available'
        return;//Stop the function
    }
    //If so then push a new div element with all of the Data from the server
    serverlist.push(`
    <div class="server-column" id="${Data.id}" onclick="startGame('${Data.id}', ${Data.index})">
        Name of Room: ${Data.name}

        <span style="padding-left: 100px; text-align:right;">
            Amount Of Players: ${Data.players.in}/${Data.players.max}
        </span>
    </div>
    `)

    let data = serverlist.join('<br>')//Replace all of the commas in the server list with <br>
    document.getElementById('serverlist').innerHTML = data //Set all the elements in the browser to the newly updated array
});

The server then emits all of the worlds by using a for loop with all the data:

client.on("UpdateServerList", () => {
    for (let index = 0; index < Worlds.length; index++) {//acts like an if, so if there are no rooms then ignore.
        //Send the client info.
        client.emit("GetServerInfo", {isserver: true, id: Worlds[index].id, index: index, players: {max: Worlds[index].maxplayerlimit, in: Worlds[index].Players.length}, name: Worlds[index].name})
    }

    //Tell the client that there are no servers
    if (Worlds.length == 0) client.emit("GetServerInfo", {isserver: false});
})

This would mean when i click on any of the servers in the server list i would join that server simple like so:

socket.on('Join Game', (Info) => {
    if (Worlds[PlayersRoomIndex].Players.length >= Worlds[PlayersRoomIndex].maxplayerlimit) {//If that server has maximum players
        client.emit('CantJoin', {Reason: "That world has reach max players"})//tell the client it cant join
        return;//end the function
    }
    //else tell the client it can join
    client.emit('Can Join')
        
    client.join(Info.id);//Join the room with that id the client requested.

    //Do some other stuff like telling other players the new play updating the client on the worlds info ect.
});

Now if there were no rooms created, then i would have to create a room. You can do this inside the server list or outside, What i did was have lots of inputs like Name, Id, MaxPlayers ect then send the values to the server like so:

function CreateRoom() {
    document.getElementById('SubmitCreateRoom').disabled = "true"//Disable the submit button so they cant spam

    //Get all the values on the inputs
    let Id = document.getElementById('IdofRoom').value;
    let Name = document.getElementById('NameofRoom').value;
    let MaxPlayer = document.getElementById('MaxofRoom').value

    //Tell the server the brand new room with data like id, name ect
    socket.emit("CreateNewRoom", {id: Id, name: Name, max: MaxPlayer})

}

Server would then get that data and push it into an array where all the rooms are.

function addroom(name, id, maxplayerlimit) {
    return {//Return an object with all the data that was inputed
        Players: [],
        name: name,
        id: id,
        maxplayerlimit: maxplayerlimit,
        Bullets: [],
        Size: {
            w: 1234,
            h: 1234,
        },
        StaticObjects: [],
        Enemys: [],
    };
}

client.on('CreateNewRoom', (Data) => {
    for (let index = 0; index < Worlds.length; index++) {
        if (Worlds[index].id == Data.id) {
            //Put some thing like client.emit('error', {reason: "Already a room created!"}) idk
            return;
        }
    }
    Worlds.push(addroom(Data.name, Data.id, Data.max)/*Returns an Object That gets pushed into an array*/)

    // Then if u want u can tell the client to join the room 
    // client.emit("RecieveRoomIndex", Data.id ,Worlds.length - 1)
})

Thats how i did it (; If you have any questions or problems reporting this answer please comment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM