186 lines
No EOL
7.5 KiB
HTML
186 lines
No EOL
7.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>WebSocket Chat</title>
|
|
<style type="text/css">
|
|
.hidden {
|
|
display:none;
|
|
}
|
|
#log {
|
|
display:inline-block; width:500px; height:500px; box-sizing: border-box;
|
|
vertical-align:top;
|
|
}
|
|
#arena {
|
|
display:inline-block; width: 1000px; height: 1000px; border:1px solid #000;
|
|
position:relative;
|
|
overflow: hidden;
|
|
}
|
|
#input {
|
|
display:block; width:600px; box-sizing: border-box;
|
|
}
|
|
#arena .robot {
|
|
position:absolute;
|
|
width: 8px;
|
|
height: 20px;
|
|
}
|
|
#arena .robot .model {
|
|
width: 8px;
|
|
height: 20px;
|
|
}
|
|
#arena .robot .cannon {
|
|
width:2px;
|
|
left:3px;
|
|
top: -31px;
|
|
height:15px;
|
|
background:#f00;
|
|
display:block;
|
|
position:relative;
|
|
transform-origin: bottom center;
|
|
}
|
|
#arena .robot .radar {
|
|
transform-origin: bottom left;
|
|
left: 4px;
|
|
top: -433px;
|
|
position: relative;
|
|
}
|
|
#arena .bullet {
|
|
position: absolute;
|
|
background: #f00;
|
|
width:4px;
|
|
height:4px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="arena"></div>
|
|
<textarea id="log" cols="30" rows="10"></textarea>
|
|
<button id="clear" type="button">Clear Watch</button><br />
|
|
|
|
<script>
|
|
window.robotLookup = {};
|
|
function getRobot(uuid) {
|
|
if (!window.robotLookup[uuid]) {
|
|
const div = document.createElement("div");
|
|
div.setAttribute("id", uuid);
|
|
div.setAttribute("class", "robot");
|
|
const img = document.createElement("img");
|
|
img.setAttribute("src", "tank.png");
|
|
img.setAttribute("class", "model");
|
|
div.appendChild(img);
|
|
const span = document.createElement("span");
|
|
span.setAttribute("class", "cannon");
|
|
div.appendChild(span);
|
|
const radar = document.createElement("img");
|
|
radar.setAttribute("src", "radar.png");
|
|
radar.setAttribute("class", "radar");
|
|
div.appendChild(radar);
|
|
const arena = document.getElementById('arena');
|
|
arena.appendChild(div);
|
|
|
|
window.robotLookup[uuid] = {
|
|
"cannonElem": span,
|
|
'imgElem': img,
|
|
'modelElem': div,
|
|
'radarElem': radar,
|
|
'lastRadar': 0,
|
|
};
|
|
}
|
|
return window.robotLookup[uuid];
|
|
}
|
|
const textarea = document.getElementById("log");
|
|
const clear = document.getElementById('clear');
|
|
const arena = document.getElementById('arena');
|
|
const bullets = [];
|
|
for(let i = 0; i < 10; ++i) {
|
|
const bullet = document.createElement('div');
|
|
bullet.setAttribute("class", "bullet hidden");
|
|
bullets.push(bullet);
|
|
arena.appendChild(bullet);
|
|
}
|
|
function openWebSocket() {
|
|
const websocket = new WebSocket("ws://localhost:3000/monitor");
|
|
websocket.onopen = function() {
|
|
console.log("connection opened");
|
|
}
|
|
websocket.onclose = function() {
|
|
console.log("connection closed");
|
|
for (uuid in window.robotLookup) {
|
|
window.robotLookup[uuid]['modelElem'].remove();
|
|
};
|
|
window.robotLookup = [];
|
|
setTimeout(function(){
|
|
openWebSocket();
|
|
}, 10000);
|
|
}
|
|
|
|
websocket.onmessage = handleMessage;
|
|
}
|
|
function handleMessage(e) {
|
|
const tokens = e.data.split(" ");
|
|
let robot;
|
|
switch (tokens[0]) {
|
|
case 'ready':
|
|
case 'connected':
|
|
break;
|
|
case 'disconnected':
|
|
robot = getRobot(tokens[1]);
|
|
robot['modelElem'].remove();
|
|
delete window.robotLookup[tokens[1]]
|
|
break;
|
|
case 'name':
|
|
robot = getRobot(tokens[1]);
|
|
robot["name"] = tokens[2];
|
|
break;
|
|
case 'model':
|
|
robot = getRobot(tokens[1]);
|
|
robot["model"] = tokens[2];
|
|
break;
|
|
case 'bullet':
|
|
const activeBullets = JSON.parse(tokens[1]);
|
|
for (let i = 0; i < 10; ++i) {
|
|
if (i >= activeBullets.length) {
|
|
bullets[i].classList.add("hidden");
|
|
} else {
|
|
bullets[i].classList.remove("hidden");
|
|
bullets[i].style.left = (2*activeBullets[i][0]-2) + 'px';
|
|
bullets[i].style.top = (2*activeBullets[i][1]-2) + 'px';
|
|
}
|
|
}
|
|
break;
|
|
case 'status':
|
|
robot = getRobot(tokens[1]);
|
|
const status = JSON.parse(tokens[2]);
|
|
robot["status"] = status;
|
|
const model = robot['modelElem'];
|
|
model.style.left = (Math.floor(status["posX"]*2) - 5) + 'px';
|
|
model.style.top = (Math.floor(status["posY"]*2) - 12.5) + 'px';
|
|
model.style.transform = "rotate(" + Math.floor(status["orientation"])+ "deg)";
|
|
const cannon = robot['cannonElem'];
|
|
cannon.style.transform = "rotate(" + Math.floor(status["gunOrient"])+ "deg)";
|
|
const radar = robot['radarElem'];
|
|
let pos = Math.floor(status["radarPos"]);
|
|
let diff = (pos - robot['lastRadar']);
|
|
if (diff < -180) diff +=360;
|
|
if (diff > 180) diff -=360;
|
|
// pos = 0;
|
|
//console.log(diff);
|
|
if (diff < 0) { // swiping clock wise
|
|
radar.style.transform = "rotate(" + pos + "deg)";
|
|
} else {
|
|
radar.style.transform = "rotate(" + pos + "deg) scaleX(-1)";
|
|
}
|
|
robot['lastRadar'] = Math.floor(status["radarPos"]);
|
|
break;
|
|
default:
|
|
console.log("received message:", tokens);
|
|
textarea.value += e.data+"\r\n";
|
|
}
|
|
}
|
|
openWebSocket();
|
|
clear.addEventListener('click', function() {
|
|
textarea.value = '';
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |