Support for current player
This commit is contained in:
parent
0264b55eaf
commit
e3e1304430
|
@ -0,0 +1,93 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="143.40671mm"
|
||||
height="67.173225mm"
|
||||
viewBox="0 0 143.40671 67.173226"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
sodipodi:docname="baton.svg">
|
||||
<defs
|
||||
id="defs2">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient837">
|
||||
<stop
|
||||
style="stop-color:#225500;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop833" />
|
||||
<stop
|
||||
style="stop-color:#cdde87;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop835" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient837"
|
||||
id="linearGradient839"
|
||||
x1="46.49107"
|
||||
y1="217.55084"
|
||||
x2="106.49107"
|
||||
y2="217.55084"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(144.34952,-283.94879)" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="358.38013"
|
||||
inkscape:cy="245.7383"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1355"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-4.7877181,-183.96423)">
|
||||
<rect
|
||||
style="opacity:1;fill:url(#linearGradient839);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.79374999;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="rect815"
|
||||
width="60"
|
||||
height="140"
|
||||
x="190.84059"
|
||||
y="-136.39795"
|
||||
transform="rotate(87.362214)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
|
@ -53,10 +53,11 @@
|
|||
<div id="bag"></div>
|
||||
<p><span data-l10n="text-content">Number of tiles in the bag:</span><br /><span id="remaining-letters">102</span><br /><span id="help-bag" data-l10n="text-content">Click on it to take one.</span><a href="#" id="help-clear" style="display:none"></a></p>
|
||||
<table id="participants">
|
||||
<tr><th data-l10n="text-content">Participant</th><th data-l10n="text-content">Rack</th><th data-l10n="text-content">Score</th></tr>
|
||||
<tr id="participants-placeholder"><td colspan="3" data-l10n="text-content">Waiting for other participants…</td></tr>
|
||||
<tr><th data-l10n="text-content">Participant</th><th data-l10n="text-content">Rack</th><th data-l10n="text-content">Score</th><th data-l10n="text-content">Turn</th></tr>
|
||||
<tr id="participants-placeholder"><td colspan="4" data-l10n="text-content">Waiting for other participants…</td></tr>
|
||||
</table>
|
||||
<p id="help-scores" data-l10n="text-content">Click on someone's score to change it.</p>
|
||||
<p id="help-turn" data-l10n="text-content">Who's turn? Click on the Turn button!</p>
|
||||
<button id="clear-rack" class="minibutton" data-l10n="text-content">Put back all the tiles of your rack in the bag</button>
|
||||
</div>
|
||||
</body>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -126,3 +126,9 @@ msgstr "Le problème est résolu. Désolé pour la gêne occasionnée !"
|
|||
|
||||
msgid "It seems your browser went offline. Please reconnect to continue playing."
|
||||
msgstr "On dirait que votre navigateur est hors ligne. Merci de bien vouloir vous reconnecter pour continuer à jouer."
|
||||
|
||||
msgid "Turn"
|
||||
msgstr "Tour"
|
||||
|
||||
msgid "Who's turn? Click on the Turn button!"
|
||||
msgstr "À qui le tour ? Cliquez sur le bouton Tour !"
|
|
@ -132,3 +132,6 @@ msgstr ""
|
|||
|
||||
msgid "It seems your browser went offline. Please reconnect to continue playing."
|
||||
msgstr ""
|
||||
|
||||
msgid "Turn"
|
||||
msgstr ""
|
|
@ -262,6 +262,7 @@ Game.prototype.init = function () {
|
|||
this.racks = {};
|
||||
this.scores = {};
|
||||
this.lastUpdated = new Date();
|
||||
this.currentPlayer = "";
|
||||
|
||||
shuffleInPlace(this.bag);
|
||||
};
|
||||
|
@ -272,7 +273,8 @@ Game.prototype.toJSON = function () {
|
|||
bag: this.bag,
|
||||
racks: this.racks,
|
||||
scores: this.scores,
|
||||
lastUpdated: this.lastUpdated.toISOString()
|
||||
lastUpdated: this.lastUpdated.toISOString(),
|
||||
currentPlayer: this.currentPlayer
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -283,6 +285,7 @@ Game.fromJSON = function (obj) {
|
|||
game.racks = obj.racks || {};
|
||||
game.scores = obj.scores || {};
|
||||
game.lastUpdated = obj.lastUpdated ? new Date(obj.lastUpdated) : new Date();
|
||||
game.currentPlayer = obj.currentPlayer || "";
|
||||
return game;
|
||||
};
|
||||
|
||||
|
@ -313,6 +316,11 @@ Game.prototype.setPlayerScore = function (player, score) {
|
|||
});
|
||||
};
|
||||
|
||||
Game.prototype.setCurrentPlayer = function (player) {
|
||||
this.currentPlayer = player;
|
||||
this.pendingEvents.push({currentPlayer: player});
|
||||
};
|
||||
|
||||
Game.prototype.playerJoined = function (playerName) {
|
||||
if (playerName) {
|
||||
this.getPlayerRack(playerName); // Create the player's rack
|
||||
|
@ -500,6 +508,7 @@ function handleCommand(cmd, gameNumber, playerName, response) {
|
|||
"error": 0,
|
||||
"gameNumber": gameNumber,
|
||||
"playerName": playerName,
|
||||
"currentPlayer": game.currentPlayer,
|
||||
"rack": game.getPlayerRack(playerName),
|
||||
"board": game.board,
|
||||
"remainingLetters": game.bag.length,
|
||||
|
@ -516,7 +525,13 @@ function handleCommand(cmd, gameNumber, playerName, response) {
|
|||
|
||||
case "score": {
|
||||
game.setPlayerScore(cmd.player, cmd.score);
|
||||
response.write("{\"error\":0}");
|
||||
response.write('{"error":0}');
|
||||
break;
|
||||
}
|
||||
|
||||
case "currentPlayer": {
|
||||
game.setCurrentPlayer(cmd.player);
|
||||
response.write('{"error":0}');
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -701,6 +716,7 @@ function handleCommands(cmds, responseAndType) {
|
|||
writeMessage(responseAndType,
|
||||
JSON.stringify({
|
||||
"playerName": cmds.playerName,
|
||||
"currentPlayer": game.currentPlayer,
|
||||
"gameNumber": gameNumber,
|
||||
"letterValues": game.letterValues,
|
||||
"rack": game.getPlayerRack(cmds.playerName),
|
||||
|
|
|
@ -47,7 +47,7 @@ html, #board, [draggable], .tile {
|
|||
color: green;
|
||||
}
|
||||
|
||||
#clear-game, #help-scores, #clear-rack {
|
||||
#clear-game, #help-scores, #clear-rack, #help-turn {
|
||||
white-space:pre-wrap;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ html, #board, [draggable], .tile {
|
|||
-webkit-user-drag: element;
|
||||
}
|
||||
|
||||
#help-clear, #help-bag, #help-scores {
|
||||
#help-clear, #help-bag, #help-scores, #help-turn {
|
||||
font-size:small
|
||||
}
|
||||
|
||||
|
@ -218,6 +218,17 @@ td.blink {
|
|||
animation:td-blink 1s
|
||||
}
|
||||
|
||||
.current-player {
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
.current-player td:first-child:before {
|
||||
position:absolute;
|
||||
left:-1em;
|
||||
color:red;
|
||||
content: "→";
|
||||
}
|
||||
|
||||
@keyframes chat-blink {
|
||||
0% {
|
||||
background:rgba(255, 255, 150, 0);
|
||||
|
@ -334,11 +345,11 @@ td.blink {
|
|||
padding:0.33ex 1ex
|
||||
}
|
||||
|
||||
#participants td:nth-child(3) {
|
||||
#participants .score-cell {
|
||||
min-width:4em;
|
||||
}
|
||||
|
||||
#participants td:nth-child(3):hover {
|
||||
#participants .score-cell:hover, .turn-cell button:hover {
|
||||
cursor:pointer;
|
||||
background:#FFA
|
||||
}
|
||||
|
@ -353,6 +364,19 @@ td.blink {
|
|||
font-style:italic;
|
||||
}
|
||||
|
||||
.turn-cell button {
|
||||
padding:0 2px;
|
||||
background:white;
|
||||
min-height:1em;
|
||||
height:1em;
|
||||
margin:0;
|
||||
display:flex;
|
||||
}
|
||||
|
||||
.turn-cell img {
|
||||
width:1em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@media screen and (max-height:650px) {
|
||||
#board td , #rack .tile-placeholder {
|
||||
|
|
38
trivabble.js
38
trivabble.js
|
@ -57,6 +57,7 @@
|
|||
let bag;
|
||||
|
||||
const playerLetters = [];
|
||||
let currentPlayer = "";
|
||||
|
||||
let audioNotification;
|
||||
let audioChat;
|
||||
|
@ -608,6 +609,23 @@
|
|||
return msgDom;
|
||||
}
|
||||
|
||||
function refreshCurrentPlayer() {
|
||||
const row = tablePlayers[currentPlayer];
|
||||
if (currentPlayer && row && !row.classList.contains("current-player")) {
|
||||
row.classList.add("current-player");
|
||||
blink(row.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
function setCurrentPlayer(player) {
|
||||
if (currentPlayer && tablePlayers[currentPlayer]) {
|
||||
tablePlayers[currentPlayer].classList.remove("current-player");
|
||||
}
|
||||
|
||||
currentPlayer = player;
|
||||
refreshCurrentPlayer();
|
||||
}
|
||||
|
||||
function handleReceivedData(data) {
|
||||
if (Array.isArray(data)) {
|
||||
data.forEach(handleReceivedData);
|
||||
|
@ -632,6 +650,10 @@
|
|||
chatMessage(data.msg.sender, data.msg.content);
|
||||
}
|
||||
|
||||
if (typeof data.currentPlayer === "string") {
|
||||
setCurrentPlayer(data.currentPlayer);
|
||||
}
|
||||
|
||||
if (data.players) {
|
||||
if (participantPlaceholder) {
|
||||
participantPlaceholder.parentNode.removeChild(participantPlaceholder);
|
||||
|
@ -659,6 +681,7 @@
|
|||
row.appendChild(document.createElement("td"));
|
||||
row.appendChild(document.createElement("td"));
|
||||
|
||||
row.lastChild.className = "score-cell";
|
||||
row.lastChild.onclick = (
|
||||
function (row) {
|
||||
return function () {
|
||||
|
@ -688,6 +711,19 @@
|
|||
}
|
||||
)(row);
|
||||
|
||||
row.appendChild(document.createElement("td"));
|
||||
row.lastChild.className = "turn-cell";
|
||||
row.lastChild.appendChild(document.createElement("button"));
|
||||
const img = new Image();
|
||||
img.src = "baton.svg";
|
||||
row.lastChild.lastChild.appendChild(img);
|
||||
row.lastChild.lastChild.onclick = (function (playerName) {
|
||||
sendCmds([{
|
||||
cmd: "currentPlayer",
|
||||
player: playerName === currentPlayer ? "" : playerName
|
||||
}]);
|
||||
}).bind(null, playerName);
|
||||
|
||||
tablePlayers[playerName] = row;
|
||||
}
|
||||
|
||||
|
@ -703,6 +739,8 @@
|
|||
blink(countCell);
|
||||
}
|
||||
}
|
||||
|
||||
refreshCurrentPlayer();
|
||||
}
|
||||
|
||||
if (data.playerName) {
|
||||
|
|
Loading…
Reference in New Issue