Skip to content

Instantly share code, notes, and snippets.

@hakatashi
Created November 16, 2016 13:48
Show Gist options
  • Save hakatashi/5e09112829299313aad6c466a1566b48 to your computer and use it in GitHub Desktop.
Save hakatashi/5e09112829299313aad6c466a1566b48 to your computer and use it in GitHub Desktop.
TSG 第12回Web分科会 参考実装
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Robot Fight</title>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.js"></script>
<style>
.field {
width: 500px;
height: 500px;
margin: 50px auto;
background: #ddd;
position: relative;
}
.robot {
position: absolute;
border-right: 20px solid transparent;
border-left: 20px solid transparent;
border-bottom: 40px solid red;
}
.robot.blue {
border-bottom-color: blue;
}
.robot.red {
border-bottom-color: red;
}
</style>
<script>
$(() => {
const socket = io();
const width = 500;
const height = 500;
const moves = {
37: {x: -1, y: 0},
38: {x: 0, y: -1},
39: {x: 1, y: 0},
40: {x: 0, y: 1},
};
const pressedKeys = new Map();
const createRobot = (id, team, x, y, direction) => {
$('.field').append($('<div/>', {
'class': `robot ${team}`,
attr: {
'data-id': id,
},
}));
moveTo(id, x, y, direction);
};
const destroyRobot = (id) => {
$(`.robot[data-id="${id}"]`).remove();
};
let x = Math.random() * width;
let y = Math.random() * height;
let direction = Math.floor(Math.random() * 4);
const selfID = Math.floor(Math.random() * 1000000);
const {team, speed} = (() => {
if (Math.random() < .5) {
return {team: 'red', speed: 4};
} else {
return {team: 'blue', speed: 8};
}
})();
let killed = false;
const moveTo = (id, x, y, direction) => {
const rotation = (direction - 1) * 90;
$(`.robot[data-id="${id}"]`).css({
transform: `translate(calc(${x}px - 50%), calc(${y}px - 50%)) rotate(${rotation }deg)`,
});
};
$('.robot.self').attr('data-id', selfID).addClass(team);
moveTo(selfID, x, y, direction);
// キー情報の記録
$(window).keydown((event) => {
pressedKeys.set(event.which, true);
});
$(window).keyup((event) => {
pressedKeys.set(event.which, false);
});
// 移動する
setInterval(() => {
[37, 38, 39, 40].forEach((keycode) => {
if (pressedKeys.get(keycode)) {
const move = moves[keycode];
x += move.x * speed;
y += move.y * speed;
x = Math.max(0, Math.min(x, width));
y = Math.max(0, Math.min(y, height));
direction = keycode - 37;
moveTo(selfID, x, y, direction);
}
});
}, 20);
// 位置データを送信する
setInterval(() => {
if (!killed) {
socket.emit('position', {selfID, x, y, direction, team});
}
}, 100);
let robotList = new Set();
// ロボットが増えたら何かする
socket.on('robots', (data) => {
const robots = new Map(data);
for (const [id, robot] of robots.entries()) {
if (id !== selfID) {
if (robotList.has(id)) {
moveTo(id, robot.x, robot.y, robot.direction);
} else {
createRobot(id, robot.team, robot.x, robot.y, robot.direction);
}
}
}
for (const id of robotList.values()) {
if (!robots.has(id)) {
destroyRobot(id);
if (id === selfID) {
killed = true;
}
}
}
robotList = new Set(robots.keys());
});
});
</script>
</head>
<body>
<div class="field">
<div class="robot self" direction="1"></div>
</div>
</body>
</html>
const fs = require('fs');
const http = require('http');
const socketIO = require('socket.io');
const app = http.createServer((req, res) => {
const stat = fs.statSync('robot.html');
res.writeHead(200, {
'Content-Type': 'text/html',
'Content-Length': stat.size,
});
fs.createReadStream('robot.html').pipe(res);
});
const currentRobotIDs = new Map();
const io = socketIO(app);
io.on('connection', (socket) => {
let id = null;
// 現在の位置が更新されたら
socket.on('position', ({selfID, x, y, direction, team}) => {
id = selfID;
currentRobotIDs.set(id, {x, y, direction, team});
});
// 接続が切断されたら
socket.on('disconnect', () => {
currentRobotIDs.delete(id);
});
});
const distance = (A, B) => (
(A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y)
);
// positionデータを全クライアントに送る
setInterval(() => {
// 衝突判定
for (const [idA, robotA] of currentRobotIDs.entries()) {
if (robotA.team === 'red') {
for (const [idB, robotB] of currentRobotIDs.entries()) {
if (robotB.team === 'blue' && distance(robotA, robotB) < 1600) {
currentRobotIDs.delete(idB);
}
}
}
}
io.emit('robots', Array.from(currentRobotIDs.entries()));
}, 100);
app.listen(8080, () => {
console.log('Listening localhost:8080...');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment