You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

230 lines
7.4 KiB

//===== Constructor
const Controls = function() {
this.moves = 0;
this.names = {};
this.timers = {};
this.currentWinningGuess = Infinity;
this.drawGuesses();
document.addEventListener('L-connected', this.msgConnected.bind(this));
document.addEventListener('L-move', this.msgMove.bind(this));
// Message handlers: "Local message" and "Global message"
// document.addEventListener('G-move', this.msgMove.bind(this));
// document.addEventListener('G-win', this.msgWin.bind(this));
document.addEventListener('G-attempt', this.msgAttempt.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));
// Click handlers
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) {
clearTimeout(this.timers.countdown);
this.timers.countdown = this.countdownTick.bind(this);
const countdown = document.getElementById('controls-countdown');
countdown.dataset.tick = seconds;
this.countdownTick();
};
Controls.prototype.countdownTick = function() {
const countdown = document.getElementById('controls-countdown');
const tick = countdown.dataset.tick * 1;
countdown.dataset.tick = tick - 1;
const s = (tick !== 1) ? 's' : '';
countdown.innerHTML = `${tick} second${s}!`;
if (tick === 0) {
this.countdownComplete();
return;
}
this.timers.countdown = setTimeout(this.countdownTick.bind(this), 1000);
};
Controls.prototype.countdownComplete = function() {
document.getElementById('controls-countdown').dataset.tick = 0;
} ;
Controls.prototype.drawGuesses = function() {
const container = document.getElementById('controls-guesses');
container.querySelectorAll('.controls-guess').forEach(el => el.parentNode.removeChild(el));
for (let i = 1; i <= 30; i++) {
const guess = document.createElement('div');
guess.className = 'controls-guess';
guess.innerHTML = i;
guess.setAttribute('data-value', i);
guess.addEventListener('click', this.onClickGuess.bind(this))
container.appendChild(guess);
}
};
Controls.prototype.showWaiting = function() {
document.getElementById('controls-start').parentNode.style.display = '';
document.getElementById('controls-walls').parentNode.style.display = '';
document.getElementById('controls-robots').parentNode.style.display = '';
document.getElementById('controls-stop').parentNode.style.display = 'none';
// document.getElementById('controls-moves-reset').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.msgAttempt = function() {
alert("Ready for winning attempt!");
};
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;
this.currentWinningGuess = guess;
document.getElementById('controls-panic').querySelector('.controls-alert-urgent').innerHTML = (`${this.names[msg.id]}${blurb}${guess} moves.`);
this.showPanic();
this.countdownStart(5);
}
Controls.prototype.msgConnected = function() {
this.showWaiting();
};
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 && 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)
});
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) {
const guess = evt.currentTarget.dataset.value * 1;
if (!guess || guess < 1) {
return;
}
if (guess < this.currentWinningGuess) {
this.dispatch('L-guess', { moves: evt.currentTarget.dataset.value });
} else {
alert(`That doesn't beat ${this.currentWinningGuess} - try again!`)
}
}
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');
};