Messaging taxonomy update.

master
Ben Burlingham 5 years ago
parent 94130bd067
commit 917c9db2ab
  1. 18
      README.txt
  2. 2
      client/connection.js
  3. 42
      client/content.js
  4. 37
      client/controls.js
  5. 2
      index.html
  6. 13
      notes.txt
  7. 3
      server.js
  8. 15
      server/game.js

@ -0,0 +1,18 @@
## Architecture:
- Local events are broadcast as custom events prefixed `L-`
- Incoming global messages are broadcast as custom events prefixed with `G`
## TODO
- move websocket server to /core
- robot icons with personality
- dynamic socket server resolution
- namespace server to /ricochet
- cookie room link
- no cancel from name prompt
- limit concurrent players, make sure connections are closed
- window resize update board
- donate link
- tutorial
- walls algorigthm
- win declare/add/remove
- restore state on join

@ -60,7 +60,7 @@ Connection.prototype.onError = function(err) {
Connection.prototype.onReceiveMessage = function({ data }) {
const msg = JSON.parse(data);
console.warn(msg);
console.warn(JSON.stringify(msg));
if (!msg.type) {
console.warn("Unprocessable message: ", msg)

@ -9,29 +9,31 @@ const Content = function({ parent, squares }) {
this.listeners = {};
this.initialRobotState = [];
// 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);
// from connection: board.onReceiveGuess(data.body);
this.drawSquares();
document.addEventListener('L-reset', this.onReset.bind(this));
document.addEventListener('G-walls', this.msgWalls.bind(this));
document.addEventListener('G-robots', this.msgRobots.bind(this));
};
//===== Event handlers
Content.prototype.msgRobots = function(evt) {
this.initialRobotState = evt.detail.body;
this.drawRobots()
}
//===== Event handlers
Content.prototype.drawRobots = function(robots) {
this.initialRobotState = robots;
Content.prototype.drawRobots = function() {
this.robots = {};
this.parent.querySelectorAll('.content-robot').forEach(el => el.parentNode.removeChild(el));
this.parent.querySelectorAll('.content-arrows').forEach(el => el.parentNode.removeChild(el));
robots.forEach(({ color, i, j }) => {
this.initialRobotState.forEach(({ color, i, j }) => {
const { x, y } = this.squares.ijToXy({ i, j });
const s = this.squares.sideLength;
const id = color.replace('#', '').toUpperCase();
@ -61,19 +63,19 @@ Content.prototype.drawRobots = function(robots) {
arrows.style.top = (y - s) + 'px';
const up = this.drawArrow({
direction: 'up', label: '▲', i, j, left: s, top: 0, parentId: id
direction: 'up', label: '▲', i, j, left: (s * 1.25), top: (s * 0.5), parentId: id
});
const down = this.drawArrow({
direction: 'down', label: '▼', i, j, left: s, top: (2 * s), parentId: id
direction: 'down', label: '▼', i, j, left: (s * 1.25), top: (s * 2), parentId: id
});
const left = this.drawArrow({
direction: 'left', label: '◀', i, j, left: 0, top: s, parentId: id
direction: 'left', label: '◀', i, j, left: (s * 0.5), top: (s * 1.25), parentId: id
});
const right = this.drawArrow({
direction: 'right', label: '▶', i, j, left: (2 * s), top: s, parentId: id
direction: 'right', label: '▶', i, j, left: (s * 2), top: (s * 1.25), parentId: id
});
arrows.appendChild(up);
@ -89,7 +91,7 @@ Content.prototype.drawRobots = function(robots) {
};
Content.prototype.drawArrow = function({ direction, label, i, j, left, top, parentId }) {
const s = this.squares.sideLength;
const s = this.squares.sideLength / 2;
const arrow = document.createElement('div');
arrow.className = 'content-arrow';
@ -125,7 +127,9 @@ Content.prototype.drawSquares = function() {
}
};
Content.prototype.drawWalls = function(edges) {
Content.prototype.msgWalls = function(msg) {
const edges = msg.detail.body;
this.walls = {};
this.parent.querySelectorAll('.content-wall-x').forEach(el => el.parentNode.removeChild(el));
@ -186,7 +190,7 @@ Content.prototype.moveRobot = function({ id, i, j }) {
this.updateArrowVisibilities();
var event = new Event('move-increment');
var event = new Event('L-move');
document.dispatchEvent(event);
}
@ -237,7 +241,7 @@ Content.prototype.onReceiveGuess = function() {
}
Content.prototype.onReset = function() {
this.drawRobots(this.initialRobotState);
this.drawRobots();
};
Content.prototype.findNextObstacle = function({ direction, i, j }) {

37
client/controls.js vendored

@ -3,6 +3,8 @@
const Controls = function() {
this.moves = 0;
this.names = {};
this.timers = {};
this.currentWinningGuess = Infinity;
this.drawGuesses();
@ -12,6 +14,7 @@ const Controls = function() {
// 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));
@ -31,10 +34,13 @@ const Controls = function() {
//===== 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 - 1;
countdown.dataset.tick = seconds + 1;
setTimeout(this.countdownTick.bind(this), 1000);
this.countdownTick();
};
Controls.prototype.countdownTick = function() {
@ -49,12 +55,13 @@ Controls.prototype.countdownTick = function() {
const s = (tick !== 1) ? 's' : '';
countdown.innerHTML = `${tick} second${s}!`;
setTimeout(this.countdownTick.bind(this), 1000);
this.timers.countdown = setTimeout(this.countdownTick.bind(this), 1000);
};
Controls.prototype.countdownComplete = function() {
alert("boom")
};
document.getElementById('controls-countdown').dataset.tick = 0;
} ;
Controls.prototype.drawGuesses = function() {
const container = document.getElementById('controls-guesses');
@ -99,6 +106,10 @@ Controls.prototype.showPanic = function() {
//===== 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 ",
@ -108,9 +119,11 @@ Controls.prototype.msgGuess = function(evt) {
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(30);
this.countdownStart(5);
}
Controls.prototype.msgJoin = function() {
@ -176,7 +189,17 @@ Controls.prototype.dispatch = function(evt, data) {
}
Controls.prototype.onClickGuess = function(evt) {
this.dispatch('L-guess', { moves: evt.currentTarget.dataset.value });
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() {

@ -75,7 +75,7 @@
<div class='controls-subtitle'>Local</div>
<div class="controls-row">
<div>Moves:</div>
<div id="controls-moves">-</div>
<div id="controls-moves">0</div>
<div class='controls-button' id='controls-reset'>Reset</div>
</div>

@ -1,13 +0,0 @@
// TODO move websocket server to /core
// TODO dynamic socket server resolution
// TODO namespace server to /ricochet
// TODO cookie room link
// TODO no cancel from name prompt
// TODO limit concurrent players, make sure connections are closed
// TODO window resize update board
// TODO donate link
// TODO tutorial
// TODO walls algorigthm
// TODO fix overlapping robot arrows
// TODO win declare/add/remove
// TODO restore state on join

@ -84,7 +84,10 @@ const Server = {
switch (message.type) {
case 'guess':
const santizedGuess = message.rawBody.moves * 1;
santizedGuess && Server.messageAll({ type: 'guess', guess: santizedGuess, id: ws.id });
G.onGuess(santizedGuess).then(Server.messageAll.bind(null, { type: 'attempt', id: ws.id }));
break;
case 'robots':
Server.messageAll({ type: 'robots', body: G.getRobots()});

@ -4,6 +4,8 @@ const players = {};
const Game = function() {
this.id = uuid.v4();
this.countdownTimer = null;
this.winningGuess = Infinity;
}
Game.prototype.addPlayer = function(id, name) {
@ -95,4 +97,17 @@ Game.prototype.getWalls = function() {
return edges;
};
Game.prototype.onGuess = function(guess) {
return new Promise((resolve, reject) => {
if (guess < 1 || guess >= this.guess) {
reject();
}
this.guess = guess;
clearTimeout(this.countdownTimer);
this.countdownTimer = setTimeout(resolve, 5 * 1000);
});
};
module.exports = Game;
Loading…
Cancel
Save