Starting movement stack implementation.

master
Ben Burlingham 5 years ago
parent a1a88ea319
commit 303dbd939b
  1. 7
      README.txt
  2. 20
      client/content.js
  3. 65
      client/controls.js
  4. 1
      index.html

@ -3,17 +3,18 @@
- Incoming global messages are broadcast as custom events prefixed with `G`
## TODO
- be able to "back up" in a move sequence
- move guess and move logic out of server (clean up server file)
- restore state on join
- robot icons with personality
- robot GUIDs
- move guess and move logic out of server (clean up server file)
- countdown skip
- no cancel from name prompt
- window resize update board
- walls algorigthm
- win declare/add/remove
- be able to "back up" in a move sequence
- restore state on join
- limit concurrent players, make sure connections are closed, clean up empty rooms
- cookie room link, add to all messages, namespace them

@ -7,7 +7,6 @@ const Content = function({ parent, squares }) {
this.walls = {};
this.robots = {};
this.listeners = {};
this.initialRobotState = [];
this.playerId = null;
this.isSolving = false;
@ -15,6 +14,7 @@ const Content = function({ parent, squares }) {
this.drawSquares();
// Message handlers: "Local message" and "Global message"
document.addEventListener('L-reset', this.msgReset.bind(this));
document.addEventListener('G-connected', this.msgConnected.bind(this));
@ -26,13 +26,13 @@ const Content = function({ parent, squares }) {
//===== UI
Content.prototype.drawRobots = function() {
Content.prototype.drawRobots = function(robotPositions) {
this.robots = {};
this.parent.querySelectorAll('.content-robot').forEach(el => el.parentNode.removeChild(el));
this.parent.querySelectorAll('.content-arrows').forEach(el => el.parentNode.removeChild(el));
this.initialRobotState.forEach(({ color, i, j }) => {
robotPositions.forEach(({ color, i, j }) => {
const { x, y } = this.squares.ijToXy({ i, j });
const s = this.squares.sideLength;
const id = color.replace('#', '').toUpperCase();
@ -46,20 +46,11 @@ Content.prototype.drawRobots = function() {
robot.style.borderRadius = (s / 2) + 'px';
robot.style.height = s + 'px';
robot.style.width = s + 'px';
robot.style.left = x + 'px';
robot.style.top = y + 'px';
robot.dataset.i = i;
robot.dataset.j = j;
// Get robot from ij: document.querySelector('[data-robot=i-j]')
// robot.dataset.robot = ij;
const arrows = document.createElement('div');
arrows.className = 'content-arrows';
arrows.id = `arrows-${id}`;
arrows.style.position = 'absolute';
arrows.style.left = (x - s) + 'px';
arrows.style.top = (y - s) + 'px';
const up = this.drawArrow({
direction: 'up', label: '▲', i, j, left: (s * 1.25), top: (s * 0.5), parentId: id
@ -282,15 +273,14 @@ Content.prototype.onArrowClick = function(evt) {
const detail = { id, i: i2, j: j2, emitIf: this.isSolving };
const evtMove = new CustomEvent('L-move', { detail });
document.dispatchEvent(evtMove);
};
//===== Message handlers
Content.prototype.msgRobots = function(evt) {
this.initialRobotState = evt.detail.body;
this.drawRobots()
const robotPositions = evt.detail.body;
this.drawRobots(robotPositions);
};
Content.prototype.msgWalls = function(evt) {

65
client/controls.js vendored

@ -1,34 +1,38 @@
//===== Constructor
const Controls = function() {
this.moves = 0;
this.names = {};
this.positions = [];
this.timers = {};
this.currentWinningGuess = Infinity;
this.drawGuesses();
// this.drawGuesses();
// Message handlers: "Local message" and "Global message"
document.addEventListener('L-connected', this.msgConnected.bind(this));
document.addEventListener('L-move', this.msgMove.bind(this));
document.addEventListener('L-reset', this.msgReset.bind(this));
document.addEventListener('L-undo', this.msgUndo.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-players', this.msgPlayers.bind(this));
document.addEventListener('G-robots', this.msgPlayers.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-reset').addEventListener('click', this.onClickReset.bind(this));
document.getElementById('controls-robots').addEventListener('click', this.onClickRobots.bind(this));
document.getElementById('controls-skip').addEventListener('click', this.onClickSkip.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-undo').addEventListener('click', this.onClickUndo.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
@ -104,6 +108,14 @@ Controls.prototype.showPanic = function() {
document.getElementById('controls-panic').style.display = '';
};
Controls.prototype.updateMoves = function() {
// Initial robot placement is first move, to allow undo, but doesn't count as a move.
const moves = this.positions.length - 1;
document.getElementById('controls-moves').innerHTML = moves;
document.getElementById('controls-undo').style.display = moves > 0 ? 'auto' : 'none';
};
//===== Message handlers
Controls.prototype.msgAttempt = function() {
@ -130,9 +142,18 @@ Controls.prototype.msgConnected = function() {
this.showWaiting();
};
Controls.prototype.msgMove = function() {
this.moves++;
document.getElementById('controls-moves').innerHTML = this.moves;
Controls.prototype.msgUndo = function(evt) {
// Remove most recent move and return to the one before that.
this.moves.pop();
const secondToLast = this.moves.pop();
const evtMove = new CustomEvent('L-move', { detail: secondToLast });
document.dispatchEvent(evtMove);
};
Controls.prototype.msgMove = function(evt) {
this.moves.push(evt.detail);
this.updateMoves();
};
Controls.prototype.msgPlayers = function(evt) {
@ -169,6 +190,11 @@ Controls.prototype.msgPlayers = function(evt) {
});
};
Controls.prototype.msgReset = function() {
this.moves = [];
this.updateMoves();
};
Controls.prototype.msgSkip = function() {
this.coundownComplete();
};
@ -200,31 +226,32 @@ Controls.prototype.onClickGuess = function(evt) {
} 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.onClickUndo = function() {
this.dispatch('L-undo');
};
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');
};

@ -76,6 +76,7 @@
<div class="controls-row">
<div>Moves:</div>
<div id="controls-moves">0</div>
<div class='controls-button' id='controls-undo'>Undo</div>
<div class='controls-button' id='controls-reset'>Reset</div>
</div>

Loading…
Cancel
Save