From 3c8bc448d8bb87fce50b0c881875daa951b477b0 Mon Sep 17 00:00:00 2001 From: Nathan Date: Fri, 4 Oct 2024 16:13:21 +0100 Subject: [PATCH] Add basic room functionality --- public/index.html | 7 +- public/main.js | 174 ++++++++++++++++++++++++++++++++++++++++++- public/shapes.js | 33 +++++++++ public/style.css | 7 ++ server.js | 184 +++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 401 insertions(+), 4 deletions(-) create mode 100644 public/shapes.js diff --git a/public/index.html b/public/index.html index 7dabda3..d53294d 100644 --- a/public/index.html +++ b/public/index.html @@ -8,12 +8,17 @@ +

Rooms will not be HTML buttons eventually, but for now...

+ + + + - diff --git a/public/main.js b/public/main.js index 42be640..1086031 100644 --- a/public/main.js +++ b/public/main.js @@ -1 +1,173 @@ -var socket = io(); +const socket = io({autoConnect: false}); +const canvas = document.getElementById('canvas');; +const ctx = canvas.getContext('2d'); + +const cardWidth = 240; +const cardHeight = 360; + +const cards = new Image(); +const back = new Image(); + +let room; +let hand = []; +let turn; +let playerName; + +// Canvas Initialisation +init(); +function init() { + console.log('init'); + + ctx.font = "12px Arial"; + canvas.style.backgroundColor = 'rgb(143 153 150)'; + cards.src = 'images/deck.svg'; + back.src = 'images/uno.svg'; + + document.addEventListener('touchstart', onclick, false); + document.addEventListener('click', onclick, false); + playerName = getCookie('playerName'); + + if (playerName == null) { + playerName = prompt('Enter your name: ', 'Guest'); + + if (playerName == null || playerName == "") { + playerName = 'Guest'; + } + + setCookie('playerName', playerName, 24 * 3600); + } + + console.log('>> socket.connect()'); + socket.connect(); +} + + +// Cookies are temp, will need logins, etc. +function setCookie(name, value, seconds) { + let date = new Date(); + date.setTime(date.getTime() + (seconds * 1000)); + let expires = "expires=" + date.toUTCString(); + document.cookie = name + "=" + value + ";" + expires + ";path=/"; +} + +function getCookie(name) { + name += "="; + let cookies = document.cookie.split(';'); + + for(let i = 0; i < cookies.length; i++) { + let cookie = cookies[i]; + while (cookie.charAt(0) == ' ') { + cookie = cookie.substring(1); + } + if (cookie.indexOf(name) == 0) { + return cookie.substring(name.length, cookie.length); + } + } + return null; +} + + +// Connect +socket.on('connect', connect); +function connect(){ + console.log('+ Frontend Connect'); +} + +// getRooms +function requestRooms(filter = 'all'){ + console.log('>> requestRooms:'+filter); + socket.emit('requestRooms', filter); +} +function clearRoomList(){ + // Create a list of Rooms + let list = document.getElementById('joinRoomButtons'); + // Empty the ul, as to not dupe room buttons, or have rooms that's don't exist + list.innerHTML = ""; +} +function returnRooms(data){ + clearRoomList(); + + // Create a list of Rooms + let list = document.getElementById('joinRoomButtons'); + + let roomCount = Object.keys(data['roomData']).length; + if(roomCount < 1){ + alert('No Rooms'); + return 0; + } + + let rooms = data['roomData']; + // Loops the returned rooms, and add to the list (to be joinable) + for (let room in rooms) { + //console.log(rooms[room].name); + + // Making something akin to this: + //
  • + let button = document.createElement('button'); + button.appendChild(document.createTextNode(rooms[room].name)); + button.setAttribute("onclick","requestJoinRoom("+rooms[room].id+");"); + let li = document.createElement('li'); + li.appendChild(button); + + list.appendChild(li); + } + +} +socket.on('returnRooms', function (data) { + console.log('<< returnRooms'); + returnRooms(data); +}); + + +// createRoom +function requestCreateRoom(){ + console.log('+ requestCreateRoom'); + socket.emit('requestCreateRoom', playerName); +} +function returnCreateRoom(data){ + +} +socket.on('returnCreateRoom', function (data) { + console.log('<< returnCreateRoom'); + console.log(data); +}); + + +// joinRoom +function requestJoinRoom(roomId) { + console.log('+ requestJoinRoom '.roomId); + socket.emit('requestJoinRoom', playerName, roomId); + room = 0; + hand = []; + turn = false; + console.log('>> Room Request'); +} + +socket.on('responseJoinRoom', function (name) { + if (name != 'error') { + room = name; + console.log('<< Room Response: ' + name); + + // Room Name + ctx.fillText(name, 0, 10); + + // Deck + deck = new Rectangle({ + name: 'deck', + x: canvas.width-cardWidth/2-40, + y: canvas.height-cardHeight/2-60, + width: cardWidth/2, + height: cardHeight/2, + fillStyle: "#FF0000" + }); + deck.draw(); + //ctx.fillRect(canvas.width-cardWidth/2-60, canvas.height/2-cardHeight/4, cardWidth/2, cardHeight/2); + + // Player Name + ctx.fillText(playerName, 100, 390); + } else { + socket.disconnect(); + alert('Rooms are full! Try again later'); + } +}); + diff --git a/public/shapes.js b/public/shapes.js new file mode 100644 index 0000000..ec7cd21 --- /dev/null +++ b/public/shapes.js @@ -0,0 +1,33 @@ +// https://stackoverflow.com/a/29676404 + +context = document.getElementById("canvas").getContext("2d"); +defaultFillStyle = '#000'; + +function Rectangle(params) { + this.name = params.name; + this.x = params.x || 0; + this.y = params.y || 0; + this.width = params.width || 0; + this.height = params.height || 0; + this.fillStyle = params.fillStyle || "#FFFFFF"; + this.strokeStyle = params.strokeStyle || "#000000"; + this.lineWidth = params.lineWidth || 0; +} + +Rectangle.prototype.draw = function () { + if (this.fillStyle) { + console.log('X: '+this.x+' Y: '+this.y); + console.log('W: '+this.width+' H: '+this.height); + } + if (this.fillStyle) { + context.fillStyle = this.fillStyle; + context.fillRect(this.x, this.y, this.width, this.height); + context.fillStyle = defaultFillStyle; // Reset back to default + } + if (this.strokeStyle && this.lineWidth) { + context.strokeStyle = this.strokeStyle; + context.lineWidth = this.lineWidth; + context.strokeRect(this.x, this.y, this.width, this.height); + } +} + diff --git a/public/style.css b/public/style.css index cbb32d0..926e58b 100644 --- a/public/style.css +++ b/public/style.css @@ -9,3 +9,10 @@ canvas{ display: block; } +.dib{display: inline-block; margin: 0; margin-bottom: 8px;} + +.joinRoomButtons li{ + display: inline-block; + margin-left: 6px; +} + diff --git a/server.js b/server.js index 6dc6276..de34cb3 100644 --- a/server.js +++ b/server.js @@ -7,11 +7,191 @@ const io = require('socket.io')(http); app.use(express.static(__dirname + '/public')); +http.listen(port, () => console.log('listening on port ' + port)); + io.on('connection', onConnection); -http.listen(port, () => console.log('listening on port ' + port)); +// Variables +let numRooms = 0; +let numRoomsToPreGen = 1; +const maxRooms = 3; +const maxPlayersPerRoom = 2; +const maxSpectatorsPerRoom = 0; + +// All the room +//let data = []; // Normal array +let data = {}; // Object array (this one for returning to player, and JSON stringify while keeping named ids) +let roomData = {}; +for (let roomId = 1; roomId <= numRoomsToPreGen; roomId++) { + // Never have more rooms than max rooms!!! + if(numRooms > maxRooms){ + break; + } + + createRoom(roomId); +} function onConnection(socket){ - console.log('a user connected'); + + console.log('+ User connected'); + console.log(''); + + socket.on('requestRooms', function(filter) { + requestRooms(socket, filter); + }); + + socket.on('requestJoinRoom', function(playerName, roomId) { + requestJoinRoom(socket, playerName, roomId); + }); + + socket.on('requestCreateRoom', function(playerName) { + requestCreateRoom(socket, playerName); + }); + +} + +function requestRooms(socket, filter){ + console.log('+ requestRooms recieved'); + console.log('- filter: '+filter); + + let response = getRooms(filter, dump = true); + io.to(socket.id).emit('returnRooms', response); + + console.log(''); +} + +function getRooms(filter = 'all', dump = false){ + console.log('+ getRooms'); + let response = { + random: 'randomStuff', + roomData: roomData, + }; + + if(dump){ + console.log(response); + console.log(''); + } + + return response; +} + +function requestCreateRoom(socket, playerName){ + console.log('+ createRoom recieved'); + console.log('- requested by: '+playerName); + + response = createRoom(roomId = false, dump = true); + io.to(socket.id).emit('returnCreateRoom', response); + + if(response.success){ + let response = getRooms(filter = 'all', dump = true); + io.to(socket.id).emit('returnRooms', response); + } + + console.log(''); +} + +function createRoom(roomId = false, dump = true){ + let roomName = false; + if(roomId == false){ + roomId = numRooms + 1; + } + console.log(roomId); + + let response = { + success: false, + message: 'No idea bossman' + }; + + // Max room limit reached + console.log(numRooms); + console.log(maxRooms); + if(numRooms >= maxRooms){ + console.log('- Room limit reached'); + + response = { + success: false, + message: 'No space '+numRooms+' out of '+maxRooms+' created.' + }; + + // Create room + }else{ + console.log('- Creating room') + let room = {}; + room['id'] = roomId; + room['name'] = 'Room:'+room['id']; + roomName = room['name']; + room['password'] = ''; + room['timeout'] = {}; + room['timeout']['s'] = 10; + room['people'] = 0; + + //room['deck'] = []; + //room['turn'] = 0; + + // Removed players for now, players may be seperate + // and back-end only with an assoc. to current room + + //let players = {}; + //for (let j = 0; j < maxPlayersPerRoom; j++) { + //let p = {}; + //p['id'] = 0; + //p['name'] = ""; + //p['hand'] = {}; + //players[j] = p; + //} + + //room['players'] = players; + roomData[roomId] = room; + numRooms = numRooms + 1; + + response = { + success: true, + message: 'Room Created: '+roomName, + }; + } + + if(dump){ + console.log(response); + console.log(''); + } + return response; +} + +// TODO: break into requestJoinRoom, and JoinRoom? +// Maybe not needed here? As won't be done via backend? +function requestJoinRoom(socket, playerName, roomId){ + + console.log('+ requestJoinRoom recieved'); + socket.playerName = playerName; + + for (let i = 1; i <= numRooms; i++) { + let name = 'Room_' + i; + let people = roomData[i]['people']; + + console.log('- people: '+people); + console.log('- maxPlayersPerRoom: '+maxPlayersPerRoom); + + if (true || people < maxPlayersPerRoom) { + + people = roomData[i]['people'] += 1; + socket.join(name); + console.log('>> User ' + socket.playerName + + ' connected on ' + name + ' (' + (people) + '/' + maxPlayersPerRoom + ')'); + + io.to(socket.id).emit('responseJoinRoom', name); + + if (people >= maxPlayersPerRoom) { + console.log('- starting game'); + //startGame(name); + } + + return; + + } + } + + io.to(socket.id).emit('responseRoom', 'error'); + console.log('>> Rooms exceeded'); + }