added text shadow, users are broadcasted properly to clients
This commit is contained in:
parent
bf85779edb
commit
24e2c2735e
87
index.html
87
index.html
@ -4,12 +4,18 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Multiplayer Game</title>
|
<title>Multiplayer Game</title>
|
||||||
<link rel="stylesheet" type="text/css" href="mflx.min.css">
|
<link rel="stylesheet" type="text/css" href="mflx.min.css">
|
||||||
|
<style type="text/css">
|
||||||
|
.text-with-shadow {
|
||||||
|
text-shadow: -1px -1px 1px #000, 1px -1px 1px #000,
|
||||||
|
-1px 1px 1px #000, 1px 1px 1px #000; color: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<button id="create-room">Create Room</button>
|
<button id="create-room">Create Room</button>
|
||||||
<input id="join-code" placeholder="Enter room code">
|
<input id="join-code" placeholder="Enter room code">
|
||||||
<button id="join-room">Join Room</button>
|
<button id="join-room">Join Room</button>
|
||||||
<div class="players"></div>
|
<div class="flx(wrap) players"></div>
|
||||||
<div id="status"></div>
|
<div id="status"></div>
|
||||||
<button id="start-game" style="display: none;">Start Game</button>
|
<button id="start-game" style="display: none;">Start Game</button>
|
||||||
<button id="spin-wheel" style="display: none;">Spin Wheel</button>
|
<button id="spin-wheel" style="display: none;">Spin Wheel</button>
|
||||||
@ -23,8 +29,61 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
//================general Purpose functions=========================================//
|
||||||
|
function cryptoSecureShuffle(array) {
|
||||||
|
const shuffledArray = [...array]; // Create a copy to avoid mutating the original array
|
||||||
|
const n = shuffledArray.length;
|
||||||
|
|
||||||
//wheel==========================================================================
|
// Fisher-Yates shuffle
|
||||||
|
for (let i = n - 1; i > 0; i--) {
|
||||||
|
// Generate a cryptographically secure random index
|
||||||
|
let randIndex;
|
||||||
|
do {
|
||||||
|
// Generate a random value in the range [0, 2^32)
|
||||||
|
const randomBuffer = new Uint32Array(1);
|
||||||
|
window.crypto.getRandomValues(randomBuffer);
|
||||||
|
randIndex = randomBuffer[0] >>> 0; // Convert to a non-negative integer
|
||||||
|
} while (randIndex >= Math.floor(2 ** 32 / (i + 1)) * (i + 1)); // Avoid bias
|
||||||
|
|
||||||
|
// Compute the unbiased index
|
||||||
|
randIndex %= (i + 1);
|
||||||
|
|
||||||
|
// Swap the elements
|
||||||
|
[shuffledArray[i], shuffledArray[randIndex]] = [shuffledArray[randIndex], shuffledArray[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return shuffledArray;
|
||||||
|
}
|
||||||
|
//====================making Name Tags/ assigning colors to names================//
|
||||||
|
let nameColors = [
|
||||||
|
'#ff0000','#ff8700','#ffd300','#deff0a','#a1ff0a',
|
||||||
|
'#0aff99','#0aefff','#147df5','#580aff','#be0aff'
|
||||||
|
]
|
||||||
|
nameColors = cryptoSecureShuffle(nameColors);
|
||||||
|
function assignColors(names, colors) {
|
||||||
|
let result = [];
|
||||||
|
let n = 0; // Keep track of name index
|
||||||
|
let c = 0; // Keep track of color index
|
||||||
|
|
||||||
|
if (names.length > colors.length) {
|
||||||
|
// Assign colors cyclically
|
||||||
|
while (n < names.length) {
|
||||||
|
result.push({ name: names[n], color: colors[c] });
|
||||||
|
n++;
|
||||||
|
c = (c + 1) % colors.length; // Cycle through the colors
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Assign colors directly, keeping track of indices
|
||||||
|
while (n < names.length) {
|
||||||
|
result.push({ name: names[n], color: colors[c] });
|
||||||
|
n++;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
//=========================================wheel==========================================//
|
||||||
const wheel = [
|
const wheel = [
|
||||||
'lose a turn', 800, 350, 450, 700, 300, 600, 5000,
|
'lose a turn', 800, 350, 450, 700, 300, 600, 5000,
|
||||||
300, 600, 300, 500, 800, 550, 400, 300, 900, 500, 'spin again',
|
300, 600, 300, 500, 800, 550, 400, 300, 900, 500, 'spin again',
|
||||||
@ -132,7 +191,6 @@
|
|||||||
spinSpeed = wheelSpinSpeedData[targetIndex]; // Initial speed
|
spinSpeed = wheelSpinSpeedData[targetIndex]; // Initial speed
|
||||||
|
|
||||||
function animate() {
|
function animate() {
|
||||||
|
|
||||||
if ( spinSpeed < 0.001) {
|
if ( spinSpeed < 0.001) {
|
||||||
spinning = false;
|
spinning = false;
|
||||||
console.log(`Landed on: ${wheel[targetIndex]}`);
|
console.log(`Landed on: ${wheel[targetIndex]}`);
|
||||||
@ -163,6 +221,21 @@
|
|||||||
// Trigger spin after 2 seconds
|
// Trigger spin after 2 seconds
|
||||||
//setTimeout(simulateServerResponse, 2000);
|
//setTimeout(simulateServerResponse, 2000);
|
||||||
|
|
||||||
|
//==================================end of Wheel=====================================//
|
||||||
|
function drawPlayers(message) {
|
||||||
|
let players = document.querySelector('.players');
|
||||||
|
//assignColors(names, colors) {
|
||||||
|
let processedNametags = assignColors(message.clients,nameColors);
|
||||||
|
const playersHtml = processedNametags.map(client => {
|
||||||
|
if (client.name === message.leaderName) {
|
||||||
|
return `<span class='mr-2 btn is-round text-with-shadow' style='background-color:${client.color};'>⭐ ${client.name} ⭐</span>`; // Highlight the leader with stars
|
||||||
|
} else {
|
||||||
|
return `<span class='mr-2 btn is-round text-with-shadow' style='background-color:${client.color};'>${client.name}</span>`;
|
||||||
|
}
|
||||||
|
}).join(""); // Combine all elements into a single string
|
||||||
|
|
||||||
|
players.innerHTML = playersHtml;
|
||||||
|
}
|
||||||
const socket = new WebSocket("ws://localhost:8080");
|
const socket = new WebSocket("ws://localhost:8080");
|
||||||
|
|
||||||
document.getElementById("create-room").onclick = () => {
|
document.getElementById("create-room").onclick = () => {
|
||||||
@ -188,18 +261,25 @@
|
|||||||
document.getElementById("guess-letter").value = ""; // Clear input
|
document.getElementById("guess-letter").value = ""; // Clear input
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
socket.onmessage = (event) => {
|
socket.onmessage = (event) => {
|
||||||
const message = JSON.parse(event.data);
|
const message = JSON.parse(event.data);
|
||||||
|
|
||||||
if (message.type === "room_created") {
|
if (message.type === "room_created") {
|
||||||
document.getElementById("status").innerText = `Room created! Code: ${message.roomCode}`;
|
document.getElementById("status").innerText = `Room created! Code: ${message.roomCode}`;
|
||||||
|
drawPlayers(message);
|
||||||
if (message.isLeader) {
|
if (message.isLeader) {
|
||||||
document.getElementById("start-game").style.display = "inline";
|
document.getElementById("start-game").style.display = "inline";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message.type === "joined_room") {
|
if (message.type === "joined_room") {
|
||||||
|
|
||||||
|
drawPlayers(message);
|
||||||
const status = message.isLeader ? "You are the party leader!" : "You joined the room!";
|
const status = message.isLeader ? "You are the party leader!" : "You joined the room!";
|
||||||
|
// document.querySelector('.players').innerHtml += `<span>${}<span>`
|
||||||
|
|
||||||
document.getElementById("status").innerText = `Room Code: ${message.roomCode} - ${status}`;
|
document.getElementById("status").innerText = `Room Code: ${message.roomCode} - ${status}`;
|
||||||
if (message.isLeader) {
|
if (message.isLeader) {
|
||||||
document.getElementById("start-game").style.display = "inline";
|
document.getElementById("start-game").style.display = "inline";
|
||||||
@ -246,6 +326,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (message.type === "new_leader") {
|
if (message.type === "new_leader") {
|
||||||
|
drawPlayers(message);
|
||||||
document.getElementById("status").innerText = "You are now the party leader!";
|
document.getElementById("status").innerText = "You are now the party leader!";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
37
server.js
37
server.js
@ -50,7 +50,7 @@ wss.on("connection", (ws) => {
|
|||||||
|
|
||||||
if (data.type === "create_room") {
|
if (data.type === "create_room") {
|
||||||
const roomCode = uuidv4().slice(0, 5);
|
const roomCode = uuidv4().slice(0, 5);
|
||||||
ws.name = DefaultNames
|
ws.name = getRandomName();
|
||||||
rooms[roomCode] = {
|
rooms[roomCode] = {
|
||||||
clients: [ws],
|
clients: [ws],
|
||||||
leader: ws,
|
leader: ws,
|
||||||
@ -61,7 +61,10 @@ wss.on("connection", (ws) => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
ws.roomCode = roomCode;
|
ws.roomCode = roomCode;
|
||||||
ws.send(JSON.stringify({ type: "room_created", roomCode, isLeader: true }));
|
ws.send(JSON.stringify({ type: "room_created", roomCode,
|
||||||
|
isLeader: true,
|
||||||
|
clients: rooms[roomCode].clients.map((i)=> i.name),
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.type === "join_room") {
|
if (data.type === "join_room") {
|
||||||
@ -76,14 +79,26 @@ wss.on("connection", (ws) => {
|
|||||||
ws.send(JSON.stringify({ type: "error", message: "Game has already Started!!!" }));
|
ws.send(JSON.stringify({ type: "error", message: "Game has already Started!!!" }));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
ws.name = getRandomName();
|
||||||
rooms[roomCode].clients.push(ws);
|
rooms[roomCode].clients.push(ws);
|
||||||
ws.roomCode = roomCode;
|
ws.roomCode = roomCode;
|
||||||
ws.send(JSON.stringify({
|
const room = rooms[ws.roomCode];
|
||||||
|
room.clients.forEach((client) => {
|
||||||
|
client.send(JSON.stringify({
|
||||||
type: "joined_room", roomCode,
|
type: "joined_room", roomCode,
|
||||||
isLeader: rooms[roomCode].leader === ws
|
isLeader: rooms[roomCode].leader === ws ,
|
||||||
|
clients: rooms[roomCode].clients.map((i)=> i.name),
|
||||||
|
leaderName:rooms[roomCode].leader.name
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
type: "joined_room_you", roomCode,
|
||||||
|
isLeader: rooms[roomCode].leader === ws,
|
||||||
|
you:ws.name
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
console.log('clients: ',rooms[roomCode].clients);
|
//console.log('clients: ',rooms[roomCode].leader.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.type === "start_game") {
|
if (data.type === "start_game") {
|
||||||
@ -136,12 +151,24 @@ wss.on("connection", (ws) => {
|
|||||||
|
|
||||||
ws.on("close", () => {
|
ws.on("close", () => {
|
||||||
if (ws.roomCode && rooms[ws.roomCode]) {
|
if (ws.roomCode && rooms[ws.roomCode]) {
|
||||||
|
console.log('closing');
|
||||||
const room = rooms[ws.roomCode];
|
const room = rooms[ws.roomCode];
|
||||||
|
const roomCode = ws.roomCode;
|
||||||
room.clients = room.clients.filter((client) => client !== ws);
|
room.clients = room.clients.filter((client) => client !== ws);
|
||||||
if (room.leader === ws && room.clients.length > 0) {
|
if (room.leader === ws && room.clients.length > 0) {
|
||||||
|
console.log('closing within room leader')
|
||||||
room.leader = room.clients[0];
|
room.leader = room.clients[0];
|
||||||
room.leader.send(JSON.stringify({ type: "new_leader" }));
|
room.leader.send(JSON.stringify({ type: "new_leader" }));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
room.clients.forEach((client) =>
|
||||||
|
client.send(JSON.stringify({
|
||||||
|
type: "joined_room", roomCode,
|
||||||
|
isLeader: rooms[roomCode].leader === ws ,
|
||||||
|
clients: rooms[roomCode].clients.map((i)=> i.name),
|
||||||
|
leaderName:rooms[roomCode].leader.name
|
||||||
|
}))
|
||||||
|
);
|
||||||
if (room.clients.length === 0) delete rooms[ws.roomCode];
|
if (room.clients.length === 0) delete rooms[ws.roomCode];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user