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.
 
 
 

262 lines
8.5 KiB

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="ricochet.css">
<link href="https://fonts.googleapis.com/css2?family=Montserrat&display=swap" rel="stylesheet">
</head>
<body>
<div class="controls-container">
<div class='controls-title'>Puzzle Robots</div>
<div class="controls-room">
<span>Room ID</span>
<input type="text" id='game-id'>
<button type='button'>&gt;</button>
</div>
<!-- <div class="rounds">
<button type='button' id='game-start'>Start New Round</button>
<div class="timer">0:42</div>
</div> -->
<div id="controls-players">
<div class='controls-subtitle'>Players</div>
</div>
<div class="moves">
<div class="move-count">1</div>
<div class="move-count">2</div>
<div class="move-count">3</div>
<div class="move-count">4</div>
<div class="move-count">5</div>
<div class="move-count">6</div>
<div class="move-count">7</div>
<div class="move-count">8</div>
<div class="move-count">9</div>
<div class="move-count">10</div>
<br>
<div class="move-count">11</div>
<div class="move-count">12</div>
<div class="move-count">13</div>
<div class="move-count">14</div>
<div class="move-count">15</div>
<div class="move-count">16</div>
<div class="move-count">17</div>
<div class="move-count">18</div>
<div class="move-count">19</div>
<div class="move-count">20</div>
<br>
<div class="move-count">21</div>
<div class="move-count">22</div>
<div class="move-count">23</div>
<div class="move-count">24</div>
<div class="move-count">25</div>
<div class="move-count">26</div>
<div class="move-count">27</div>
<div class="move-count">28</div>
<div class="move-count">29</div>
<div class="move-count">30</div>
</div>
</div>
<div class="board-container">
<div id="board"></div>
</div>
<script>
// TODO dynamic sizing of squares based on available height
// TODO dynamic move population
// TODO move websocket server to /core
// TODO dynamic socket server resolution
// TODO namespace server to /ricochet
// TODO [soap, xmpp]
// TODO a message must have a head and a body
// TODO your favorite games
const Cookie = {
getCookie: function(name) {
var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
return v ? decodeURI(v[2]) : null;
},
setCookie: function(name, value, days) {
var d = new Date;
d.setTime(d.getTime() + 24*60*60*1000*days);
document.cookie = name + "=" + encodeURI(value) + ";path=/;expires=" + d.toGMTString();
},
deleteCookie: function(name) {
Util.setCookie(name, '', -1);
}
};
const Controls = {
addPlayer: () => {
const rawInput = prompt("What is your name?");
connection.send(JSON.stringify({ head: { type: 'addPlayer' }, body: rawInput }))
},
removePlayer: (rawInput) => {
connection.send(JSON.stringify({ head: { type: 'removePlayer' }, body: rawInput }))
},
updatePlayers: (names) => {
const container = document.getElementById('controls-players');
console.log(names)
Object.keys(names).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)
});
// container.querySelectorAll('.controls-player').forEach(el => {
// if (!names[el.id]) {
// container.removeChild(el);
// }
// })
},
};
const Board = {
squaresPerSide: 20,
squareSize: 40,
placeSquares: () => {
const board = document.getElementById('board');
board.style.width = (Board.squaresPerSide * Board.squareSize + 1) + 'px';
board.style.height = (Board.squaresPerSide * Board.squareSize + 1) + 'px';
while (board.hasChildElements) {
board.removeChild(board.firstChild);
}
for (let i = 0; i < Board.squaresPerSide; i++) {
for (let j = 0; j < Board.squaresPerSide; j++) {
const square = document.createElement('div');
square.className = 'square';
board.appendChild(square);
}
}
},
placeRobots: (robots) => {
robots.forEach(robot => {
const [color, x, y] = robot;
const r = document.createElement('div');
r.className = 'board-robot';
r.style.background = color;
r.style.left = 40 * x + 'px';
r.style.top = 40 * y + 'px';
document.getElementById('board').appendChild(r);
})
},
placeWall: (id, className, x, y) => {
if (document.getElementById(id)) {
return;
}
const w = document.createElement('wall');
w.id = id;
w.style.top = x + 'px';
w.style.left = y + 'px';
w.className = className;
document.getElementById('board').appendChild(w);
},
placeWalls: (walls) => {
walls.forEach(wall => {
const [x, y, north, south, east, west] = wall;
const pxX = 40 * x;
const pxY = 40 * y;
if (north) {
Board.placeWall(`${x}-${y}-n`, "board-wall-y", pxX, pxY);
}
if (south) {
Board.placeWall(`${x}-${y}-s`, "board-wall-y", pxX, pxY + Board.squareSize);
}
if (east) {
Board.placeWall(`${x}-${y}-e`, "board-wall-x", pxX, pxY);
}
if (west) {
Board.placeWall(`${x}-${y}-e`, "board-wall-x", pxX + Board.squareSize, pxY);
}
})
},
removeWalls: () => {
const walls = document.querySelector('board-wall-x').concat(document.querySelectorAll('board-wall-y'))
}
}
/////////////////////
window.addEventListener('load', Board.placeSquares)
var connection = new WebSocket('ws://localhost:8080/ricochet', ['soap', 'xmpp']);
connection.onopen = Controls.addPlayer;
connection.onerror = console.error;
connection.onmessage = function (msg) {
const data = JSON.parse(msg.data)
if (!data.head || !data.body) {
console.warn("Unprocessable entity: ", msg)
return;
}
console.log(msg)
switch(data.head.type) {
case 'connect':
break;
case 'disconnect':
break;
case 'players':
Controls.updatePlayers(data.body)
break;
case 'robots':
Board.placeRobots(data.body);
break;
case 'walls':
Board.placeWalls(data.body);
break;
default:
console.warn("Unhandled message: ", msg)
}
};
</script>
</body>
</html>