Countdown timer built.

master
Ben Burlingham 5 years ago
parent 9afd3d8364
commit 94130bd067
  1. 47
      client/connection.js
  2. 3
      client/content.js
  3. 283
      client/controls.js
  4. 30
      controls.css
  5. 6
      index.css
  6. 22
      index.html
  7. 3
      notes.txt
  8. 18
      server.js

@ -2,16 +2,28 @@
const Connection = function() {
// Local event listeners
document.addEventListener('L-robots', () => {
this.ws.send(JSON.stringify({ head: { type: 'reposition-robots' }}));
document.addEventListener('L-start', () => {
this.ws.send(JSON.stringify({ type: 'start' }));
});
document.addEventListener('L-walls', () => {
this.ws.send(JSON.stringify({ head: { type: 'regenerate-walls' }}));
document.addEventListener('L-stop', () => {
this.ws.send(JSON.stringify({ type: 'stop' }));
});
document.addEventListener('L-skip', () => {
this.ws.send(JSON.stringify({ type: 'skip' }));
});
document.addEventListener('L-guess', (evt) => {
this.ws.send(JSON.stringify({ head: { type: 'guess' }, rawBody: evt.detail }));
this.ws.send(JSON.stringify({ type: 'guess', rawBody: evt.detail }));
});
document.addEventListener('L-robots', () => {
this.ws.send(JSON.stringify({ type: 'robots' }));
});
document.addEventListener('L-walls', () => {
this.ws.send(JSON.stringify({ type: 'walls' }));
});
document.addEventListener('L-join', (evt) => {
@ -20,7 +32,8 @@ const Connection = function() {
};
Connection.prototype.connect = function(){
const names = ["Biff", "Morty", "Herb", "Chester", "Lyle", "Cap", "Dale", "Ned", "Mindy"]
const names = ["Biff", "Morty", "Herb", "Chester", "Lyle", "Cap", "Dale", "Ned", "Mindy", "Frankie", "Gabriel", "Mona", "Dolores",
"Sepulveda", "Venus", "Blingbing", "Cyrpt"]
const r = Math.floor(Math.random() * names.length);
const rawInput = names[r] //prompt("What is your name?");
@ -57,21 +70,13 @@ Connection.prototype.onReceiveMessage = function({ data }) {
let eventName;
switch (msg.type) {
case 'players':
eventName = 'G-players';
break;
case 'robots':
eventName = 'G-robots';
break;
case 'walls':
eventName = 'G-walls';
break;
case 'guess':
eventName = 'G-guess';
break;
case 'guess': eventName = 'G-guess'; break;
case 'players': eventName = 'G-players'; break;
case 'robots': eventName = 'G-robots'; break;
case 'skip': eventName = 'G-skip'; break;
case 'start': eventName = 'G-start'; break;
case 'stop': eventName = 'G-stop'; break;
case 'walls': eventName = 'G-walls'; break;
}
if (eventName) {

@ -11,7 +11,8 @@ const Content = function({ parent, squares }) {
// this.drawSquares();
// document.addEventListener('L-conn-open', this.msgStartGame.bind(this));
// document.addEventListener('G-walls', this.msgStart.bind(this));
// document.addEventListener('G-robots', this.msgStart.bind(this));
// document.addEventListener('board-reset', this.onReset.bind(this));
// from connection: board.drawRobots(data.body);
// from connection: board.drawWalls(data.body);

283
client/controls.js vendored

@ -4,39 +4,58 @@ const Controls = function() {
this.moves = 0;
this.names = {};
// this.buildGuesses();
// this.setUi('connecting');
this.drawGuesses();
document.addEventListener('L-conn-open', this.msgJoin.bind(this));
document.addEventListener('L-move', this.msgMove.bind(this));
// Message handlers: "Local message" and "Global message"
// document.addEventListener('G-move', this.onMoveIncrement.bind(this));
// document.addEventListener('G-win', this.onMoveIncrement.bind(this));
// document.addEventListener('G-start', this.msgStartGame.bind(this));
// document.addEventListener('G-stop', this.msgStartGame.bind(this));
// document.addEventListener('G-players', this.msgStartGame.bind(this)); <--- controls.playersUpdate(data.body)
// document.addEventListener('G-move', this.msgMove.bind(this));
// document.addEventListener('G-win', this.msgWin.bind(this));
document.addEventListener('G-guess', this.msgGuess.bind(this));
document.addEventListener('G-skip', this.msgSkip.bind(this));
document.addEventListener('G-start', this.msgStart.bind(this));
document.addEventListener('G-stop', this.msgStop.bind(this));
document.addEventListener('G-players', this.msgPlayers.bind(this));
// document.addEventListener('G-walls', this.msgStartGame.bind(this));
// document.addEventListener('G-robots', this.msgStartGame.bind(this));
// document.addEventListener('G-guess', this.msgStartGame.bind(this)); <--- controls.onReceiveGuess(data.body);
// document.addEventListener('L-move', this.onMoveIncrement.bind(this));
// document.addEventListener('L-conn-error', this.onConnectionError.bind(this));
// document.addEventListener('L-skip-timer', this.msgStartGame.bind(this));
// document.addEventListener('L-skip-timer', this.msgStartGame.bind(this));
// Click handlers
// document.getElementById('controls-moves-reset').addEventListener('click', this.onMoveReset.bind(this));
// document.getElementById('controls-start-game').addEventListener('click', this.onStartGame.bind(this));
// document.getElementById('controls-stop-game').addEventListener('click', this.onStopGame.bind(this));
// document.getElementById('controls-regenerate-walls').addEventListener('click', this.onRegenWalls.bind(this));
// document.getElementById('controls-reposition-robots').addEventListener('click', this.onRepositionRobots.bind(this));
// document.getElementById('controls-timer-skip').addEventListener('click', this.onSkipTimer.bind(this));
document.getElementById('controls-start').addEventListener('click', this.onClickStart.bind(this));
document.getElementById('controls-stop').addEventListener('click', this.onClickStop.bind(this));
document.getElementById('controls-walls').addEventListener('click', this.onClickWalls.bind(this));
document.getElementById('controls-robots').addEventListener('click', this.onClickRobots.bind(this));
document.getElementById('controls-reset').addEventListener('click', this.onClickReset.bind(this));
document.getElementById('controls-skip').addEventListener('click', this.onClickSkip.bind(this));
}
//===== UI
Controls.prototype.countdownStart = function(seconds) {
const countdown = document.getElementById('controls-countdown');
countdown.dataset.tick = seconds - 1;
setTimeout(this.countdownTick.bind(this), 1000);
};
Controls.prototype.countdownTick = function() {
const countdown = document.getElementById('controls-countdown');
const tick = countdown.dataset.tick * 1;
countdown.dataset.tick = tick - 1;
if (tick === 0) {
this.countdownComplete();
return;
}
const s = (tick !== 1) ? 's' : '';
countdown.innerHTML = `${tick} second${s}!`;
setTimeout(this.countdownTick.bind(this), 1000);
};
Controls.prototype.countdownComplete = function() {
alert("boom")
};
Controls.prototype.drawGuesses = function() {
const container = document.getElementById('controls-guesses');
container.querySelectorAll('.controls-guess').forEach(el => el.parentNode.removeChild(el));
@ -58,117 +77,131 @@ Controls.prototype.showWaiting = function() {
document.getElementById('controls-stop').parentNode.style.display = 'none';
// document.getElementById('controls-moves-reset').parentNode.style.display = 'none';
// document.getElementById('controls-timer-skip').parentNode.style.display = 'none';
// document.getElementById('controls-guesses').parentNode.style.display = 'none';
document.getElementById('controls-guesses').style.display = 'none';
document.getElementById('controls-panic').style.display = 'none';
};
Controls.prototype.showGuessing = function() {
document.getElementById('controls-start').parentNode.style.display = 'none';
document.getElementById('controls-walls').parentNode.style.display = 'none';
document.getElementById('controls-robots').parentNode.style.display = 'none';
document.getElementById('controls-panic').style.display = 'none';
document.getElementById('controls-stop').parentNode.style.display = '';
// document.getElementById('controls-moves-reset').parentNode.style.display = '';
document.getElementById('controls-guesses').style.display = '';
}
Controls.prototype.showPanic = function() {
this.showGuessing();
document.getElementById('controls-panic').style.display = '';
};
//===== Message handlers
Controls.prototype.msgGuess = function(evt) {
const blurbs = [ " has a solution: ", " can do it in ", " says, maybe ", " wagers ",
" reckons ", " is pretty sure it's ", ", confidently: ", " wants it to be ",
" says ", " hazards ", " guesses ", " thinks it might be "];
const blurb = blurbs[Math.floor(Math.random() * blurbs.length)];
const msg = evt.detail;
const guess = msg.guess;
document.getElementById('controls-panic').querySelector('.controls-alert-urgent').innerHTML = (`${this.names[msg.id]}${blurb}${guess} moves.`);
this.showPanic();
this.countdownStart(30);
}
Controls.prototype.msgJoin = function() {
this.showWaiting();
};
// Controls.prototype.playersUpdate = function(names) {
// const container = document.getElementById('controls-players');
// const keys = Object.keys(names);
Controls.prototype.msgMove = function() {
this.moves++;
document.getElementById('controls-moves').innerHTML = this.moves;
};
Controls.prototype.msgPlayers = function(evt) {
const container = document.getElementById('controls-players');
const names = evt.detail.body;
const keys = Object.keys(names);
// if (keys.length > 0) {
// const nobody = document.getElementById('controls-players-nobody');
// nobody.parentNode.removeChild(nobody);
// }
if (keys.length > 0) {
const nobody = document.getElementById('controls-players-nobody');
nobody && nobody.parentNode.removeChild(nobody);
}
// keys.forEach(connectionId => {
// const id = `player-${connectionId}`;
// if (document.getElementById(id)) {
// return;
// }
// const n = document.createElement('div');
// n.id = id;
// n.innerHTML = names[connectionId];
// n.className = 'controls-player';
// container.appendChild(n)
// });
// console.log(names)
// this.names = names;
// // container.querySelectorAll('.controls-player').forEach(el => {
// // if (!names[el.id]) {
// // container.removeChild(el);
// // }
// // })
// };
// Controls.prototype.onReceiveGuess = function(message) {
// console.log(this.names[message.id] + ' has a solution')
// }
// Controls.prototype.onClickGuess = function(evt) {
// const e = new CustomEvent('guess', { detail: { moves: evt.currentTarget.dataset.value } });
// document.dispatchEvent(e);
// }
// Controls.prototype.onMoveIncrement = function() {
// this.moves++;
// document.getElementById('controls-moves').innerHTML = this.moves;
// };
// Controls.prototype.onMoveReset = function() {
// this.moves = 0;
// document.getElementById('controls-moves').innerHTML = this.moves;
// const event = new Event('board-reset');
// document.dispatchEvent(event);
// };
// Controls.prototype.onStartGame = function() {
// this.setUi('gameStarted');
// const evt = new Event('startGame');
// document.dispatchEvent(evt);
// }
// Controls.prototype.onStopGame = function() {
// this.setUi('gameStopped');
// const evt = new Event('stopGame');
// document.dispatchEvent(evt);
// }
// Controls.prototype.onRegenWalls = function() {
// const evt = new Event('regenerateWalls');
// document.dispatchEvent(evt);
// }
// Controls.prototype.onRepositionRobots = function() {
// const evt = new Event('repositionRobots');
// document.dispatchEvent(evt);
// }
// Controls.prototype.setUi = function(state) {
// switch(state) {
// case 'gameStarted':
// document.getElementById('controls-start-round').parentNode.style.display = 'none';
// document.getElementById('controls-regenerate-walls').parentNode.style.display = 'none';
// document.getElementById('controls-reposition-robots').parentNode.style.display = 'none';
// document.getElementById('controls-stop-round').parentNode.style.display = '';
// document.getElementById('controls-moves-reset').parentNode.style.display = '';
// document.getElementById('controls-timer-skip').parentNode.style.display = '';
// document.getElementById('controls-guesses').parentNode.style.display = '';
// break;
// case 'gameStopped':
// document.getElementById('controls-start-round').parentNode.style.display = '';
// document.getElementById('controls-regenerate-walls').parentNode.style.display = '';
// document.getElementById('controls-reposition-robots').parentNode.style.display = '';
// document.getElementById('controls-stop-round').parentNode.style.display = 'none';
// document.getElementById('controls-moves-reset').parentNode.style.display = 'none';
// document.getElementById('controls-timer-skip').parentNode.style.display = 'none';
// document.getElementById('controls-guesses').parentNode.style.display = 'none';
// break;
// }
// }
keys.forEach(connectionId => {
const id = `player-${connectionId}`;
if (document.getElementById(id)) {
return;
}
const n = document.createElement('div');
n.id = id;
n.innerHTML = names[connectionId];
n.className = 'controls-player';
container.appendChild(n)
});
this.names = names;
container.querySelectorAll('.controls-player').forEach(el => {
const id = el.id.split('player-').pop();
if (!this.names[id]) {
container.removeChild(el);
}
});
};
Controls.prototype.msgSkip = function() {
this.coundownComplete();
};
Controls.prototype.msgStart = function() {
this.showGuessing();
};
Controls.prototype.msgStop = function() {
this.showWaiting();
}
//===== Click handlers
Controls.prototype.dispatch = function(evt, data) {
const e = (data ? new CustomEvent(evt, { detail: data }) : new Event(evt));
document.dispatchEvent(e);
}
Controls.prototype.onClickGuess = function(evt) {
this.dispatch('L-guess', { moves: evt.currentTarget.dataset.value });
}
Controls.prototype.onClickRobots = function() {
this.dispatch('L-robots');
}
Controls.prototype.onClickSkip = function() {
this.dispatch('L-skip');
}
Controls.prototype.onClickStart = function() {
this.dispatch('L-start');
}
Controls.prototype.onClickStop = function() {
this.dispatch('L-stop');
}
Controls.prototype.onClickWalls = function() {
this.dispatch('L-walls');
}
Controls.prototype.onClickReset = function() {
this.moves = 0;
document.getElementById('controls-moves').innerHTML = this.moves;
this.dispatch('L-reset');
};

@ -28,13 +28,20 @@
margin: 24px 0 12px 0;
}
.controls-alert {
.controls-alert-info {
background: #21dfae;
color: #222;
padding: 12px;
margin: 24px 0 12px 0;
}
.controls-alert-urgent {
background: #DE4F21;
color: #fff;
padding: 12px;
margin: 24px 0 12px 0;
}
.controls-row {
align-items: center;
display: flex;
@ -48,21 +55,14 @@
width: 100%;
}
#controls-players {
}
.controls-player {
padding: 8px;
}
#controls-local {
}
.controls-guess {
background: none;
cursor: pointer;
float: left;
display: inline-block;
font-size: 12px;
height: 30px;
line-height: 30px;
@ -75,12 +75,22 @@
}
#controls-footer {
background: #9A748C;
bottom: 0;
left: 0;
padding: 24px;
position: absolute;
right: 0;
text-align: center;
}
#controls-footer a {
color: #639699;
font-size: 24px;
text-decoration: none;
}
#controls-footer a:hover {
text-decoration: underline;
}
.controls-button {

@ -12,9 +12,5 @@ PALETTE:
21DFAE Aquamarine
4D3243 Plum
DE4F21 Fire
EXPERIMENTAL:
9A748C
639699
364B4D
639699 Cadet
*/

@ -75,23 +75,27 @@
<div class='controls-subtitle'>Local</div>
<div class="controls-row">
<div>Moves:</div>
<div id="controls-moves">4</div>
<div class='controls-button' id='controls-moves-reset'>Reset</div>
<div id="controls-moves">-</div>
<div class='controls-button' id='controls-reset'>Reset</div>
</div>
<div class="controls-row">
<div>Timer:</div>
<div id="controls-timer">0:42</div>
<div class='controls-button' id='controls-timer-skip'>Skip</div>
<div id="controls-guesses">
<div class="controls-alert-info">How many moves to win?</div>
</div>
<div id="controls-guesses">
<div class="controls-alert">How many moves to win?</div>
<div id="controls-panic">
<div class='controls-alert-urgent'></div>
<div class="controls-row">
<div>Countdown:</div>
<div id="controls-countdown">30 seconds!</div>
<div class='controls-button' id='controls-skip'>Skip</div>
</div>
</div>
</div>
<div id="controls-footer">
<div>Heart (match head height)</div>
<a href='http://buymeacoff.ee/5EGitAV' target='_blank'>&#9825;</a>
</div>
</div>

@ -9,4 +9,5 @@
// TODO tutorial
// TODO walls algorigthm
// TODO fix overlapping robot arrows
// TODO win declare/add/remove
// TODO win declare/add/remove
// TODO restore state on join

@ -23,7 +23,7 @@ const Server = {
},
messageOthers: (ws, message) => {
DEBUG && console.log(`Sending to other ${wss.clients.size - 1} client(s):`);
DEBUG && console.log(`Sending to other client(s):`);
DEBUG && console.log(message);
wss.clients.forEach((client) => {
@ -49,7 +49,7 @@ const Server = {
DEBUG && console.log(ws.id);
G.removePlayer(ws.id);
Server.messageOthers({ type: 'players', body: G.getPlayers() });
Server.messageOthers(ws, { type: 'players', body: G.getPlayers() });
},
onConnect: (ws, req) => {
@ -75,21 +75,22 @@ const Server = {
DEBUG && console.log('Received message: ');
DEBUG && console.log(message);
if (!message.head) {
if (!message.type) {
DEBUG && console.warn("Unprocessable message: ")
DEBUG && console.warn(message);
return;
}
switch (message.head.type) {
switch (message.type) {
case 'guess':
Server.messageAll({ type: 'guess', guess: 29, id: ws.id });
const santizedGuess = message.rawBody.moves * 1;
santizedGuess && Server.messageAll({ type: 'guess', guess: santizedGuess, id: ws.id });
break;
case 'robots':
Server.messageAll({ type: 'robots', body: G.getRobots()});
break;
case 'walls':
Server.messageAll({ type: 'walls', body: G.getWalls()});
case 'skip':
Server.messageAll({ type: 'start' });
break;
case 'start':
Server.messageAll({ type: 'start' });
@ -97,6 +98,9 @@ const Server = {
case 'stop':
Server.messageAll({ type: 'stop' });
break;
case 'walls':
Server.messageAll({ type: 'walls', body: G.getWalls()});
break;
default:
console.warn("Unknown message type: ", message.head.type)
}

Loading…
Cancel
Save