diff --git a/.gitignore b/.gitignore
index 1fe7a25..ae67e4d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
-node_modules/
-virtual/js/build/
+node_modules/
+virtual/js/build/
+npm-debug.log
diff --git a/package.json b/package.json
index d2238b9..99b4a1b 100755
--- a/package.json
+++ b/package.json
@@ -5,6 +5,7 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --progress --colors --optimize-minimize",
+ "build:watch": "webpack --progress --colors --optimize-minimize --watch",
"start": "babel-node test",
"lint": "eslint --fix --ignore-path ./.eslintignore js/ test/ gulpfile.js webpack.config.js"
},
diff --git a/test.js b/test.js
index 4aaec74..b7bedb5 100644
--- a/test.js
+++ b/test.js
@@ -2,6 +2,7 @@ import keypress from "keypress";
import VirtualSphero from "./main";
const virtualSphero = new VirtualSphero(8081, "*");
+let virtualSpheroSpeed = 100;
// キーにテストする内容を割り当てる
const testKeys = {
@@ -18,7 +19,7 @@ const testKeys = {
},
b: function() {
console.log("add sphero");
- virtualSphero.addSphero(`Sphero${new Date().getTime()}`);
+ virtualSphero.addSphero(`Sphero${+new Date() + Math.floor(Math.random() * 1000)}`);
},
d: function() {
console.log("remove sphero");
@@ -38,8 +39,11 @@ keypress(process.stdin);
process.stdin.on("keypress", function(ch, key) {
if (key && typeof testKeys[key.name] !== "undefined") {
- if (Array.isArray(testKeys[key.name])) {
- const args = testKeys[key.name];
+ if (key && key.shift && (key.name === "up" || key.name === "down")) {
+ addSpeed(key.name === "up" ? 1 : -1);
+ console.log(`${key.name} speed: ${virtualSpheroSpeed}`);
+ } else if (Array.isArray(testKeys[key.name])) {
+ const args = getArgs(testKeys[key.name], key.name);
console.log(`orb.${args[0]}(${args.slice(1).map(arg => "\"" + arg + "\"").join(", ")});`);
commandAll(args[0], args.slice(1));
} else if (typeof testKeys[key.name] === "function") {
@@ -59,5 +63,16 @@ function commandAll(commandName, args) {
});
}
+function addSpeed(speed) {
+ virtualSpheroSpeed = Math.max(0, Math.min(255, virtualSpheroSpeed + speed));
+}
+
+function getArgs(array, keyName) {
+ if (keyName !== "space") {
+ array.splice(1, 1, virtualSpheroSpeed);
+ }
+ return array;
+}
+
process.stdin.setRawMode(true);
process.stdin.resume();
diff --git a/virtual/index.html b/virtual/index.html
index 8bb9545..bf005dd 100644
--- a/virtual/index.html
+++ b/virtual/index.html
@@ -2,16 +2,11 @@
-
+ Virtual Sphero
- Virtual Sphero
-
-
- speed = speed *
-
+
diff --git a/virtual/js/canvasManager.js b/virtual/js/canvasManager.js
new file mode 100644
index 0000000..03f74d6
--- /dev/null
+++ b/virtual/js/canvasManager.js
@@ -0,0 +1,23 @@
+import eventPublisher from "./publisher";
+
+export default class CanvasManager {
+ constructor() {
+ this.canvas = document.getElementById("canvas");
+ this.ctx = this.canvas.getContext("2d");
+ this.canvas.width = window.innerWidth;
+ this.canvas.height = window.innerHeight;
+
+ eventPublisher.subscribe("clearCanvas", () => {
+ this.clearCanvas();
+ });
+ }
+
+ resizeCanvas() {
+ this.canvas.width = window.innerWidth;
+ this.canvas.height = window.innerHeight;
+ }
+
+ clearCanvas() {
+ this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+ }
+}
diff --git a/virtual/js/main.js b/virtual/js/main.js
index 084d512..83adf03 100644
--- a/virtual/js/main.js
+++ b/virtual/js/main.js
@@ -1,12 +1,15 @@
-import VirtualSpheroController from "./virtual-sphero-controller";
+import VirtualSpheroManager from "./virtual-sphero-manager";
+import CanvasManager from "./canvasManager";
+import SocketManager from "./socketManager";
import "../css/style.css";
document.addEventListener("DOMContentLoaded", function() {
- const sphero = new VirtualSpheroController();
+ const sphero = new VirtualSpheroManager();
+ const socket = new SocketManager();
+ const canvas = new CanvasManager();
window.addEventListener("resize", function() {
- sphero.resizeCanvas();
- sphero.clearCanvas();
- sphero.fixSpherosPosition();
+ canvas.resizeCanvas();
+ canvas.clearCanvas();
});
});
diff --git a/virtual/js/publisher.js b/virtual/js/publisher.js
new file mode 100644
index 0000000..44d884d
--- /dev/null
+++ b/virtual/js/publisher.js
@@ -0,0 +1,38 @@
+// Publisherは、データを保存せず、外部へ変更を知らせる機能に絞る。
+
+class Publisher {
+ constructor() {
+ this.modelObservers = {};
+ this.observers = {};
+ }
+ subscribe(type, observer) {
+ if (typeof this.observers[type] === "undefined") {
+ this.observers[type] = [];
+ }
+ this.observers[type].push(observer);
+ }
+ publish(type, ...nextDatas) {
+ if (type.indexOf(":") !== -1) {
+ throw new Error("publishのtypeに「:」を含むことはできません。");
+ }
+ if (typeof this.observers[type] === "undefined") {
+ this.observers[type] = [];
+ }
+ if (typeof this.modelObservers[type] === "undefined") {
+ this.modelObservers[type] = [];
+ }
+ this.modelObservers[type].forEach(observer => {
+ observer.apply(null, nextDatas);
+ });
+ this.observers[type].forEach(observer => {
+ observer.apply(null, nextDatas);
+ });
+ if (typeof this.observers[type + ":after"] !== "undefined") {
+ this.observers[type + ":after"].forEach(observer => {
+ observer.apply(null, nextDatas);
+ });
+ }
+ }
+}
+
+export default new Publisher();
diff --git a/virtual/js/socketManager.js b/virtual/js/socketManager.js
new file mode 100644
index 0000000..5b836ae
--- /dev/null
+++ b/virtual/js/socketManager.js
@@ -0,0 +1,29 @@
+import eventPublisher from "./publisher";
+
+export default class SocketManager {
+ constructor() {
+ this.socket = io();
+
+ this.socket.on("connect", () => {
+ eventPublisher.publish("needShowSpheros");
+ });
+
+ this.socket.on("addVirtualSphero", spheroName => {
+ eventPublisher.publish("addVirtualSphero", spheroName);
+ });
+
+ this.socket.on("removeVirtualSphero", spheroName => {
+ eventPublisher.publish("removeVirtualSphero", spheroName);
+ });
+
+ this.socket.on("command", (spheroName, commandName, args) => {
+ eventPublisher.publish("command", spheroName, commandName, args);
+ });
+
+ eventPublisher.subscribe("sendShowSpheros", showSpheros => {
+ this.socket.emit("request", {
+ showSpheros: showSpheros
+ });
+ });
+ }
+}
diff --git a/virtual/js/speed-controller.js b/virtual/js/speed-controller.js
deleted file mode 100755
index f0ccb63..0000000
--- a/virtual/js/speed-controller.js
+++ /dev/null
@@ -1,12 +0,0 @@
-export default class SpeedController {
- constructor() {
- this._element = document.getElementById("speed");
- this.speed = 0.2;
- this._element.value = this.speed;
- this._element.addEventListener("change", () => {
- if (this._element.value !== "" && !isNaN(this._element.value)) {
- this.speed = parseFloat(this._element.value);
- }
- });
- }
-}
diff --git a/virtual/js/virtual-sphero-controller.js b/virtual/js/virtual-sphero-manager.js
old mode 100755
new mode 100644
similarity index 75%
rename from virtual/js/virtual-sphero-controller.js
rename to virtual/js/virtual-sphero-manager.js
index 8b48e30..3b7e777
--- a/virtual/js/virtual-sphero-controller.js
+++ b/virtual/js/virtual-sphero-manager.js
@@ -1,28 +1,25 @@
-import VirtualSphero from "./virtual-sphero";
-import SpeedController from "./speed-controller";
+import virtualSphero from "./virtual-sphero";
+import eventPublisher from "./publisher";
import { Engine, Render, World, Body, Bodies } from "matter-js";
-export default class VirtualSpheroController {
+export default class VirtualSpheroManager {
constructor() {
const showParam = getParams().show;
this.showSpheros = typeof showParam === "undefined" ? null : showParam.split(",");
- this.socket = io();
- this.socket.on("connect", () => {
- this.socket.emit("request", {
- showSpheros: this.showSpheros
- });
+ eventPublisher.subscribe("needShowSpheros", () => {
+ eventPublisher.publish("sendShowSpheros", this.showSpheros);
});
- this.socket.on("addVirtualSphero", spheroName => {
+ eventPublisher.subscribe("addVirtualSphero", spheroName => {
this.addVirtualSphero(spheroName);
});
- this.socket.on("removeVirtualSphero", spheroName => {
+ eventPublisher.subscribe("removeVirtualSphero", spheroName => {
this.removeVirtualSphero(spheroName);
});
- this.socket.on("command", (spheroName, commandName, args) => {
+ eventPublisher.subscribe("command", (spheroName, commandName, args) => {
const virtualSphero = this.virtualSpheros[spheroName];
if (typeof virtualSphero !== "undefined" &&
typeof virtualSphero[commandName] !== "undefined") {
@@ -30,19 +27,14 @@ export default class VirtualSpheroController {
}
});
- this.speedController = new SpeedController();
-
this.engine = Engine.create();
this.engine.world.gravity.y = 0;
Engine.run(this.engine);
this.canvas = document.getElementById("canvas");
- this.ctx = this.canvas.getContext("2d");
- this.canvas.width = window.innerWidth;
- this.canvas.height = window.innerHeight;
const tick = () => {
- this.clearCanvas();
+ eventPublisher.publish("clearCanvas");
Object.keys(this.virtualSpheros).forEach(spheroName => {
this.virtualSpheros[spheroName].move();
this.virtualSpheros[spheroName].draw();
@@ -53,17 +45,8 @@ export default class VirtualSpheroController {
this.virtualSpheros = {};
}
- resizeCanvas() {
- this.canvas.width = window.innerWidth;
- this.canvas.height = window.innerHeight;
- }
-
- clearCanvas() {
- this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
- }
-
addVirtualSphero(spheroName) {
- this.virtualSpheros[spheroName] = new VirtualSphero(this.canvas, this.speedController, spheroName);
+ this.virtualSpheros[spheroName] = new virtualSphero(this.canvas, spheroName);
World.add(this.engine.world, this.virtualSpheros[spheroName].body);
}
@@ -74,7 +57,6 @@ export default class VirtualSpheroController {
}
const commands = [
-
/* sphero.js */
"setHeading",
"setStabilization",
@@ -133,7 +115,6 @@ const commands = [
"answerInput",
"commitToFlash",
"commitToFlashAlias",
-
/* custom.js */
"streamData",
"color",
diff --git a/virtual/js/virtual-sphero.js b/virtual/js/virtual-sphero.js
index 563e83d..99473fa 100755
--- a/virtual/js/virtual-sphero.js
+++ b/virtual/js/virtual-sphero.js
@@ -1,23 +1,18 @@
import { Body, Bodies } from "matter-js";
-export default class VirtualSphero {
- constructor(canvas, speedController, spheroName) {
- this.speedController = speedController;
+export default class virtualSphero {
+ constructor(canvas, spheroName) {
this.canvas = canvas;
this.spheroName = spheroName;
this.ex = 0;
this.ey = 0;
this.radius = 25;
- this.direction = 0;
+ this.degree = 0;
this.body = Bodies.circle(1, 1, this.radius, {
friction: 0.1
});
- this.body.restitution = 0;
-
- this.width = this.canvas.width;
- this.height = this.canvas.height;
this.ctx = this.canvas.getContext("2d");
this.fillColor = "white";
@@ -30,15 +25,15 @@ export default class VirtualSphero {
};
}
- roll(far, degree) {
+ roll(speed, degree) {
this.rotate(degree);
- const direction = (degree + 270) % 360;
- this.ex = Math.cos(direction * Math.PI / 180) * far * 0.1;
- this.ey = Math.sin(direction * Math.PI / 180) * far * 0.1;
+ const rollDegree = (this.degree + 270) % 360;
+ this.ex = Math.cos(rollDegree * Math.PI / 180) * speed * 0.1;
+ this.ey = Math.sin(rollDegree * Math.PI / 180) * speed * 0.1;
}
rotate(degree) {
- this.direction = degree;
+ this.degree = degree;
}
color(color) {
@@ -50,10 +45,7 @@ export default class VirtualSphero {
}
move() {
- Body.setPosition(this.body, {
- x: this.body.position.x + this.ex,
- y: this.body.position.y + this.ey
- });
+ this.setPosition(this.body.position.x + this.ex, this.body.position.y + this.ey);
this.fixPosition();
}
@@ -68,7 +60,7 @@ export default class VirtualSphero {
this.ctx.fill();
this.ctx.stroke();
- const rad = this.direction * Math.PI / 180;
+ const rad = this.degree * Math.PI / 180;
this.ctx.save();
this.ctx.setTransform(Math.cos(rad), Math.sin(rad), -Math.sin(rad), Math.cos(rad), this.body.position.x, this.body.position.y);
this.ctx.translate(-this.radius + 10, -this.radius + 10);
@@ -77,8 +69,8 @@ export default class VirtualSphero {
}
fixPosition() {
- this.setPosition(this.getValueInRange(this.width - this.radius, this.radius, this.body.position.x),
- this.getValueInRange(this.height - this.radius, this.radius, this.body.position.y));
+ this.setPosition(this.getValueInRange(this.canvas.width - this.radius, this.radius, this.body.position.x),
+ this.getValueInRange(this.canvas.height - this.radius, this.radius, this.body.position.y));
}
setPosition(x, y) {