Commits

Sachirou Inoue committed 55226ad

Publish SpinorNetwork2 and it's game.

  • Participants
  • Parent commits 9faa2b3

Comments (0)

Files changed (14)

 
 $HEADER_NAV = [:index, :working, :members, :works]
 
+
 helpers do
   def get_title contents_name
     $PAGES_INFO[contents_name][:title]
   end
 
+
   def gen_header_nav contents_name
     str = ''
     $HEADER_NAV.each do |item|
     str
   end
 
+
   def gen_audio_element source_url
     "<audio controls><source type=\"audio/ogg\" codecs=\"vorbis\" src=\"#{source_url}.ogg\" /><source type=\"audio/mpeg\" src=\"#{source_url}.mp3\" /></audio>"
   end
 end
 
 
-get %r{/([^.]+)(?:\.html?)?} do
+get %r{/game/(?:index(?:\.html?)?)?} do
+  send_file './public/game/Sp2game.html'
+end
+
+
+get %r{/([^./]+)(?:\.html?)?} do
   @contents_name = :"#{params[:captures][0]}"
   if !($PAGES_INFO.has_key? @contents_name)
     not_found

public/game/Sp2game.html

+<meta charset='utf-8' />
+<style>
+  html, body {
+    margin: 0;
+    padding: 0;
+  }
+
+  #game {
+    display: block;
+    height: 600px;
+    width: 800px;
+  }
+
+  #answer {
+    box-shadow: 0 0 1px black, 1px 1px 2px black;
+    display: none;
+    margin: 1em;
+    padding: 5px;
+  }
+
+  #footer {
+    background: rgba(255, 255, 255, 0.6);
+    bottom: 0;
+    font-size: smaller;
+    padding: 0.5em 0 0 0.5em;
+    position: fixed;
+    right: 0;
+  }
+</style>
+
+<canvas id="game">Use web browsers that can take Canvas API and HTML5 audio.</canvas>
+<div id="answer">
+  <p>download [<a rel="external" href="https://dl.dropbox.com/u/13307622/SpinorNetwork2/SpinorNetwork2.7z">SpinorNetwork2組立てkit (48kHz 43.2Mb)</a>].</p>
+  <p>内容:</p>
+  <ul>
+    <li>10曲 (OggVorbis形式)</li>
+    <li>アートワーク</li>
+    <li>CDケース (A4折り紙用PDF)</li>
+    <li>CD盤面 (bmp形式 + <a rel="external" href="http://cd.mks-jpn.com/">かんたんデザイン工房</a>形式)</li>
+  </ul>
+  <p>前編の<b>cpVine</b>はSpinorNetworkからダウンロードいただけます。</p>
+  <p>姉妹編の<b>虚</b>はSpinorNetworkからお買い求めいただけます。</p>
+  <p> return to <a href="/working?q=SpinorNetwork2">SpinorNetwork2 - SpinorNetwork : Crain</a>.</p>
+</div>
+<div id="footer">
+  return to <a href="/working?q=SpinorNetwork2">SpinorNetwork2 - SpinorNetwork : Crain</a>.
+</div>
+
+<script src="/game/UnitePlayer.min.js"></script>
+<script src="/game/Sp2game.min.js"></script>

public/game/Sp2game.js

+/**
+ * @fileOverview A game for downloading SpinorNetwork2.
+ * @author ne_Sachirou
+ * @version 2012/06/17
+ * @license MIT License
+ */
+
+(function (_document, _window) {
+
+/*========================================
+JavaScript Canvas like Processing.
+========================================*/
+var canvas = _document.getElementById('game'),
+    context = canvas.getContext('2d'),
+    width = 0,
+    height = 0,
+    fill = null, // {String} fillStyle color
+    stroke = null, // {String} strokeStyle color
+    alpha = 1, // {Number} globalAlpha
+    strokeWidth = 1, // {Number} lineWidth
+    strokeCap = 'butt', // {'butt'|'round'|'square'} lineCap
+    strokeJoin = 'miter', // {'round'|'bevel'|'miter'} lineJoin
+    mouseX = 0,
+    mouseY = 0,
+    pmouseX = 0, // previous mouseX
+    pmouseY = 0; // previous mouseY
+
+
+/**
+ * Set global mouseX, mouseY, pmouseX, pmouseY variable.
+ * @param {MouseEvent} evt MouseMoveEvent Object
+ */
+function _getMousePoint (evt) {
+  var rect;
+
+  pmouseX = mouseX;
+  pmouseY = mouseY;
+  if (evt.offsetX) {
+    mouseX = evt.offsetX;
+    mouseY = evt.offsetY;
+  } else if (evt.layerX) {
+    mouseX = evt.layerX;
+    mouseY = evt.layerY;
+  } else {
+    rect = evt.target.getBoundingClientRect();
+    mouseX = evt.clientX - rect.left;
+    mouseY = evt.clientY - rect.top;
+  }
+}
+canvas.addEventListener('mousemove', _getMousePoint, false);
+canvas.addEventListener('click', _getMousePoint, false);
+canvas.addEventListener('mouseout', function (evt) {
+  pmouseX = mouseX;
+  pmouseY = mouseY;
+}, false);
+
+
+/**
+ * Set Canvas context properties by global Processing like variables.
+ */
+function adjustEnvironment () {
+  if (fill) {context.fillStyle = fill;}
+  if (stroke) {context.strokeStyle = stroke;}
+  if (alpha < 0) {alpha = 0;}
+  context.globalAlpha = alpha - 0;
+  if (strokeWidth < 0) {strokeWidth = 0;}
+  context.lineWidth = strokeWidth - 0;
+  context.lineCap = strokeCap || 'butt';
+  context.lineJoin = strokeJoin || 'miter';
+}
+
+
+/**
+ * @param {Function} callbask
+ * @return {Function} Stop animation function.
+ */
+function animate (callback) {
+  var timerID, stop, requestAnimationFrame, cancelRequestAnimationFrame;
+
+  function animationFun () {
+    adjustEnvironment();
+    context.clearRect(0, 0, width, height);
+    callback();
+    if (requestAnimationFrame) {
+       requestAnimationFrame(animationFun);
+    }
+  }
+
+  if (_window.requestAnimationFrame && _window.cancelAnimationFrame) {
+    requestAnimationFrame = _window.requestAnimationFrame;
+    cancelAnimationFrame = _window.cancelAnimationFrame;
+  } else if (_window.mozRequestAnimationFrame && _window.mozCancelAnimationFrame) {
+    requestAnimationFrame = _window.mozRequestAnimationFrame;
+    cancelAnimationFrame = _window.mozCancelAnimationFrame;
+  } else if (_window.msRequestAnimationFrame && _window.msCancelAnimationFrame) {
+    requestAnimationFrame = _window.msRequestAnimationFrame;
+    cancelAnimationFrame = _window.msCancelAnimationFrame;
+  } else if (_window.webkitRequestAnimationFrame && _window.webkitCancelAnimationFrame) {
+    requestAnimationFrame = _window.webkitRequestAnimationFrame;
+    cancelAnimationFrame = _window.webkitCancelAnimationFrame;
+  } else if (_window.oRequestAnimationFrame && _window.oCancelAnimationFrame) {
+    requestAnimationFrame = _window.oRequestAnimationFrame;
+    cancelAnimationFrame = _window.oCancelAnimationFrame;
+  }
+
+  if (requestAnimationFrame) {
+    timerID = requestAnimationFrame(animationFun);
+    stop = function () {
+      cancelAnimationFrame(timerID);
+    };
+  } else {
+    timerID = setInterval(animationFun, 16);
+    stop = function () {
+      clearInterval(timerID);
+    };
+  }
+  return stop;
+}
+
+
+/**
+ * @param {Number} w
+ * @param {Number} h
+ */
+function size (w, h) {
+  canvas.width = w;
+  canvas.height = h;
+  width = w;
+  height = h;
+}
+
+
+/*========================================
+Game object like enchant.js.
+========================================*/
+/**
+ * @class Game
+ * @property {Array} preloadImages { get, set }
+ * @property {Hash} preloadAudios { get, set }
+ * @property {Array} images { get }
+ * @property {Array} audioPlayers { get }
+ * @property {Scene} currentScene { get }
+ * @property {Function} onload { get, set } Callback when the game was loaded.
+ */
+function Game () {
+  var _me = this;
+
+  if (!(_me instanceof Game)) { return new Game(); }
+  _me.preloadImages = [];
+  _me.preloadAudios = {};
+  _me.images = {};
+  _me.audioPlayers = [];
+}
+
+
+Game.prototype = {
+  start: function () {
+    var timerID, i = len = 0, tmp,
+        _me = this,
+        restNumberOfLoadedItems = 0;
+
+    function uniteCallback (evt, player, trackNumber, currentTime) {
+      switch (evt.type) {
+      case 'canplay': case 'abort':
+        --restNumberOfLoadedItems;
+        break;
+      default: break;
+      }
+    }
+
+    for (i = 0, len = _me.preloadImages.length; i < len; ++i) {
+      ++restNumberOfLoadedItems;
+      tmp = new Image();
+      tmp.src = _me.preloadImages[i];
+      tmp.onload = function () { --restNumberOfLoadedItems; };
+      _me.images[_me.preloadImages[i]] = tmp;
+    }
+    restNumberOfLoadedItems += 2;
+    _me.audioPlayers[0] = new UnitePlayer(_me.preloadAudios, 0, uniteCallback);
+    _me.audioPlayers[1] = new UnitePlayer(_me.preloadAudios, 1, uniteCallback);
+    timerID = setInterval(function () {
+      if (restNumberOfLoadedItems <= 0) {
+        clearInterval(timerID);
+        _me.onload();
+       }
+    }, 30);
+  },
+
+
+  /**
+   * @param {Scene} scene
+   */
+  loadScene: function (scene) {
+    var _me = this;
+
+    if (_me.currentScene) { _me.currentScene.exit(); }
+    _me.currentScene = scene;
+    scene.start();
+  },
+
+
+  exit: function () {
+    if (this.currentScene) { this.currentScene.exit(); }
+  }
+};
+
+
+/**
+ * @class Scene
+ * @property {Function} onload { get, set } Callback when the scene was loaded. This is the scene main procedure.
+ * @property {Function} after { get, set } Callback before the next scene was loaded.
+ */
+function Scene () {
+  if (!(this instanceof Scene)) { return new Scene(); }
+}
+
+
+Scene.prototype = {
+  start: function () {
+    this.onload();
+  },
+
+
+  exit: function () {
+    if (this.after) { this.after(); }
+  }
+};
+
+
+/**
+ * @class Sprite
+ * @param {Image} image
+ * @param {Number} startX
+ * @param {Number} startY
+ * @param {Number} spriteWidth
+ * @param {Number} spriteHeight
+ * @property {Image} image { get }
+ * @property {Array} startPoint { get } [startX, startY]
+ * @property {Array} splitSize { get } [spriteWidth, spriteHeight]
+ */
+function Sprite (image, startX, startY, spriteWidth, spriteHeight) {
+  var _me = this;
+
+  if (!(_me instanceof Sprite)) {
+    return new Sprite(image, startX, startY, spriteWidth, spriteHeight);
+  }
+  _me.image = image;
+  _me.startPoint = [startX, startY];
+  _me.spriteSize = [spriteWidth, spriteHeight];
+}
+
+
+Sprite.prototype = {
+  /**
+   * @param {CanvasContext} context
+   * @param {Number} drawX
+   * @param {Number} drawY
+   * @param {Number} drawWidth (=this.spriteSize[0])
+   * @param {Number} drawHeight (=this.spriteSize[1])
+   */
+  draw: function (context, drawX, drawY, drawWidth, drawHeight) {
+    var _me = this;
+
+    if (drawWidth === void 0) { drawWidth = _me.spriteSize[0]; }
+    if (drawHeight === void 0) { drawHeight = _me.spriteSize[1]; }
+    context.drawImage(_me.image,
+      _me.startPoint[0], _me.startPoint[1], _me.spriteSize[0], _me.spriteSize[1],
+      drawX, drawY, drawWidth, drawHeight);
+  }
+};
+
+
+/*========================================
+Main user code.
+========================================*/
+var game, firstScene, answerScene;
+
+
+firstScene = new Scene();
+firstScene.momongas = [];
+firstScene.stop = null;
+
+/**
+ * @class firstScene.Momonga
+ * @param {Sprite} spriteImage
+ * @param {Hash} param
+ * @property {Split} image { get }
+ * @property {Hash} param { get }
+ * @property {Function} before { get, set } Callback before drawing.
+ * @property {Function} after { get, set } Callback after drawing.
+ * @property {Function} onclick { get, set } Callback when the Momonga was clicked.
+ * @property {Hash} _cur
+ */
+firstScene.Momonga = function (spriteImage, param) {
+  var _me = this;
+
+  if (!(_me instanceof firstScene.Momonga)) {
+    return new firstScene.Momonga(spriteImage, param);
+  }
+  _me.image = spriteImage;
+  _me.param = param;
+  _me._cur = {x: param.x,
+               diff: param.amp / 2 / param.t};
+};
+
+
+firstScene.Momonga.prototype = {
+  draw: function () {
+    var _me = this, _param = _me.param, _cur = _me._cur;
+
+    if (_me.before) { _me.before(); }
+    _me.image.draw(context, _cur.x, _param.y, _param.w, _param.h);
+    if (_me.after) { _me.after(); }
+    if (_cur.x + _cur.diff > _param.x + _param.amp / 2 ||
+        _cur.x + _cur.diff < _param.x - _param.amp / 2) {
+      _cur.diff *= -1;
+    }
+    _cur.x += _cur.diff;
+  },
+
+
+  clicked: function () {
+    game.audioPlayers[1].preset('momongaCry');
+    if (this.onclick) { this.onclick(); }
+  },
+
+
+  blink: function () {
+    var _me = this, _param = _me.param, _cur = _me._cur;
+
+    _cur._a = 1;
+    _cur._diffA = -0.01;
+    _me.before = function () {
+      if (_cur._a <= 0.3) { _cur._diffA *= -1; }
+      _cur._a += _cur._diffA;
+      context.globalAlpha = _cur._a;
+      if (_cur._a >= 1) { _me.before = _me.after = void 0; }
+    };
+    _me.after = function () {
+      context.globalAlpha = 1;
+    };
+  },
+
+
+  bounce: function () {
+    var _me = this, _param = _me.param, _cur = _me._cur,
+        originalY = _param.y;
+
+    if (_cur._direction !== void 0) { return; }
+    _cur._direction = 1;
+    _me.before = function () {
+      switch (_cur._direction) {
+      case 1:
+        _param.y += 0.2;
+        if (_param.y >= originalY + 5) { _cur._direction = 2; }
+        break;
+      case 2:
+        _param.y -= 0.2;
+        if (_param.y <= originalY - 5) { _cur._direction = 3; }
+        break;
+      case 3:
+        _param.y += 0.2;
+        if (_param.y >= originalY) {
+          _param.y = originalY;
+          _cur._direction = void 0;
+          _me.before = void 0;
+        }
+        break;
+      default: break;
+      }
+    };
+  },
+
+
+  swing: function () {
+    /** @const */
+    var RAD = 3.141592653589793 / 100;
+
+    var _me = this, _param = _me.param, _cur = _me._cur,
+        rot = 0;
+
+    if (_cur._direction !== void 0) { return; }
+    _cur._direction = 1;
+    _me.before = function () {
+      switch (_cur._direction) {
+      case 1:
+        rot += 0.05 * RAD;
+        if (rot >= 1 * RAD) { _cur._direction = 2; }
+        break;
+      case 2:
+        rot -= 0.05 * RAD;
+        if (rot <= -1 * RAD) { _cur._direction = 3; }
+        break;
+      case 3:
+        rot += 0.05 * RAD;
+        if (rot >= 0) {
+          rot = 0;
+          _cur._direction = void 0;
+          _me.before = _me.after = void 0;
+        }
+        break;
+      default: break;
+      }
+      context.rotate(rot);
+    };
+    _me.after = function () {
+      context.rotate(-rot);
+    };
+  }
+};
+
+
+firstScene.detectClick = function (evt) {
+  var momonga,
+      i = -1;
+
+  while (momonga = firstScene.momongas[++i]) {
+    momongaImage = momonga.image;
+    if ((momonga._cur.x <= mouseX && mouseX <= momonga._cur.x + momongaImage.spriteSize[0]) &&
+        (momonga.param.y <= mouseY && mouseY <= momonga.param.y + momongaImage.spriteSize[1])) {
+      momonga.clicked();
+      break;
+    }
+  }
+};
+
+
+firstScene.onload = function () {
+  var momongaImages = [
+    new Sprite(game.images['/game/momonga.png'], 0, 0, 36, 74),
+    new Sprite(game.images['/game/momonga.png'], 36, 0, 36, 74),
+    new Sprite(game.images['/game/momonga.png'], 72, 0, 36, 74),
+    new Sprite(game.images['/game/momonga.png'], 108, 0, 36, 74)];
+
+  function resistMomonga(imageNum, param, onclickCallback) {
+    var momonga = new firstScene.Momonga(momongaImages[imageNum], param);
+
+    if (typeof onclickCallback === 'string') { momonga.onclick = momonga[onclickCallback]; }
+    else { momonga.onclick = onclickCallback; }
+    firstScene.momongas.push(momonga);
+  }
+
+  resistMomonga(0, { x: 10, y: 10, amp: 10, t: 50 }, 'blink');
+  resistMomonga(1, { x: 100, y: 60, amp: 20, t: 40 }, 'swing');
+  resistMomonga(2, { x: 50, y: 400, amp: 20, t: 100 },
+    function (evt) { game.loadScene(answerScene); });
+  resistMomonga(3, { x: 700, y: 100, amp: 30, t: 70 }, 'blink');
+  resistMomonga(0, { x: 500, y: 200, w: 24, h: 49, amp: 10, t: 40 }, 'bounce');
+  resistMomonga(1, { x: 400, y: 500, w: 24, h: 49, amp: 10, t: 50 }, 'blink');
+  resistMomonga(2, { x: 600, y: 300, w: 48, h: 99, amp: 20, t: 30 }, 'bounce');
+  resistMomonga(3, { x: 200, y: 160, w: 48, h: 99, amp: 30, t: 70 }, 'blink');
+  resistMomonga(0, { x: 560, y: 160, w: 48, h: 99, amp: 20, t: 50 }, 'bounce');
+  resistMomonga(1, { x: 300, y: 60, w: 48, h: 99, amp: 10, t: 100 }, 'blink');
+  resistMomonga(2, { x: 360, y: 260, w: 24, h: 49, amp: 20, t: 30 }, 'blink');
+  resistMomonga(3, { x: 560, y: 460, w: 24, h: 49, amp: 30, t: 70 }, 'bounce');
+  game.audioPlayers[0].preset(['KrmAKxlI', 'momongaBG'][Math.floor(Math.random() * 2)]);
+  firstScene.stop = animate(function () {
+    context.drawImage(game.images['/game/momongaBG.jpg'], 0, 0);
+    firstScene.momongas.forEach(function (momonga, idx) { momonga.draw(); });
+  });
+  canvas.addEventListener('click', firstScene.detectClick, false);
+};
+
+
+firstScene.after = function () {
+  firstScene.stop();
+  game.audioPlayers[0].pause();
+  canvas.removeEventListener('click', firstScene.detectClick);
+};
+
+
+answerScene = new Scene();
+answerScene.stop = null;
+
+
+answerScene.onload = function () {
+  var stop, imageData,
+      value = 0;
+
+  imageData = context.getImageData(0, 0, width, height);
+  answerScene.stop = animate(function () {
+    context.putImageData(imageData, 0, 0);
+    context.fillStyle = fill = 'rgba(255, 255, 255, $)'.replace('$', value);
+    context.fillRect(0, 0, width, height);
+    if (value >= 1) { game.exit(); }
+    value += 0.01;
+  });
+};
+
+
+answerScene.after = function () {
+  answerScene.stop();
+  canvas.style.display = 'none';
+  _document.getElementById('answer').style.display = 'block';
+};
+
+
+size(800, 600);
+game = new Game();
+game.preloadImages = ['/game/momonga.png', '/game/momongaBG.jpg'];
+game.preloadAudios = {
+  mp3: '/game/momonga.mp3',
+  ogg: '/game/momonga.ogg',
+  volume: 0.5,
+  offset: 0,
+  preset: {
+    KrmAKxlI: ['0:15', '3:27', true],
+    momongaBG: ['3:33', '3:48.238', true],
+    momongaCry: ['3:54', '3:57.806']
+  }
+};
+game.onload = function () { game.loadScene(firstScene); };
+game.start();
+
+}(document, window));
+/* vim:set fenc=utf-8 expandtab sw=2: */

public/game/Sp2game.min.js

+/*
+ MIT License
+*/
+(function(w,f){function x(a){var b;if(a.offsetX){m=a.offsetX;n=a.offsetY}else if(a.layerX){m=a.layerX;n=a.layerY}else{b=a.target.getBoundingClientRect();m=a.clientX-b.left;n=a.clientY-b.top}}function y(a){function b(){if(t)h.fillStyle=t;if(z)h.strokeStyle=z;if(u<0)u=0;h.globalAlpha=u-0;if(v<0)v=0;h.lineWidth=v-0;h.lineCap=A||"butt";h.lineJoin=B||"miter";h.clearRect(0,0,q,r);a();d&&d(b)}var c,e,d;if(f.RequestAnimationFrame&&f.cancelAnimationFrame){d=f.requestAnimationFrame;cancelAnimationFrame=f.cancelAnimationFrame}else if(f.mozRequestAnimationFrame&&
+f.mozCancelAnimationFrame){d=f.mozRequestAnimationFrame;cancelAnimationFrame=f.mozCancelAnimationFrame}else if(f.msRequestAnimationFrame&&f.msCancelAnimationFrame){d=f.msRequestAnimationFrame;cancelAnimationFrame=f.msCancelAnimationFrame}else if(f.webkitRequestAnimationFrame&&f.webkitCancelAnimationFrame){d=f.webkitRequestAnimationFrame;cancelAnimationFrame=f.webkitCancelAnimationFrame}else if(f.oRequestAnimationFrame&&f.oCancelAnimationFrame){d=f.oRequestAnimationFrame;cancelAnimationFrame=f.oCancelAnimationFrame}if(d){c=
+d(b);e=function(){cancelAnimationFrame(c)}}else{c=setInterval(b,16);e=function(){clearInterval(c)}}return e}function s(){if(!(this instanceof s))return new s;this.preloadImages=[];this.preloadAudios={};this.images={};this.audioPlayers=[]}function o(){if(!(this instanceof o))return new o}function k(a,b,c,e,d){if(!(this instanceof k))return new k(a,b,c,e,d);this.image=a;this.startPoint=[b,c];this.spliteSize=[e,d]}var j=w.getElementById("game"),h=j.getContext("2d"),q=0,r=0,t=null,z=null,u=1,v=1,A="butt",
+B="miter",m=0,n=0;j.addEventListener("mousemove",x,false);j.addEventListener("click",x,false);j.addEventListener("mouseout",function(){},false);s.prototype={start:function(){function a(C){switch(C.type){case "canplay":case "abort":--p}}var b,c=len=0,e,d=this,p=0;c=0;for(len=d.preloadImages.length;c<len;++c){++p;e=new Image;e.src=d.preloadImages[c];e.onload=function(){--p};d.images[d.preloadImages[c]]=e}p+=2;d.audioPlayers[0]=new UnitePlayer(d.preloadAudios,0,a);d.audioPlayers[1]=new UnitePlayer(d.preloadAudios,
+1,a);b=setInterval(function(){if(p<=0){clearInterval(b);d.onload()}},30)},loadScene:function(a){this.currentScene&&this.currentScene.exit();this.currentScene=a;a.start()},exit:function(){this.currentScene&&this.currentScene.exit()}};o.prototype={start:function(){this.onload()},exit:function(){this.after&&this.after()}};k.prototype={draw:function(a,b,c,e,d){if(e===void 0)e=this.spliteSize[0];if(d===void 0)d=this.spliteSize[1];a.drawImage(this.image,this.startPoint[0],this.startPoint[1],this.spliteSize[0],
+this.spliteSize[1],b,c,e,d)}};var i,g,l;g=new o;g.momongas=[];g.stop=null;g.Momonga=function(a,b){if(!(this instanceof g.Momonga))return new g.Momonga(a,b);this.image=a;this.param=b;this._cur={x:b.x,diff:b.amp/2/b.t}};g.Momonga.prototype={draw:function(){var a=this.param,b=this._cur;this.before&&this.before();this.image.draw(h,b.x,a.y,a.w,a.h);this.after&&this.after();if(b.x+b.diff>a.x+a.amp/2||b.x+b.diff<a.x-a.amp/2)b.diff*=-1;b.x+=b.diff},clicked:function(){i.audioPlayers[1].preset("momongaCry");
+this.onclick&&this.onclick()},blink:function(){var a=this,b=a._cur;b._a=1;b._diffA=-0.01;a.before=function(){if(b._a<=0.3)b._diffA*=-1;b._a+=b._diffA;h.globalAlpha=b._a;if(b._a>=1)a.before=a.after=void 0};a.after=function(){h.globalAlpha=1}},bounce:function(){var a=this,b=a.param,c=a._cur,e=b.y;if(c._direction===void 0){c._direction=1;a.before=function(){switch(c._direction){case 1:b.y+=0.2;if(b.y>=e+5)c._direction=2;break;case 2:b.y-=0.2;if(b.y<=e-5)c._direction=3;break;case 3:b.y+=0.2;if(b.y>=e){b.y=
+e;c._direction=void 0;a.before=void 0}}}}},swing:function(){var a=this,b=a._cur,c=0;if(b._direction===void 0){b._direction=1;a.before=function(){switch(b._direction){case 1:c+=0.0015707963267948969;if(c>=0.031415926535897934)b._direction=2;break;case 2:c-=0.0015707963267948969;if(c<=-0.031415926535897934)b._direction=3;break;case 3:c+=0.0015707963267948969;if(c>=0){c=0;b._direction=void 0;a.before=a.after=void 0}}h.rotate(c)};a.after=function(){h.rotate(-c)}}}};g.detectClick=function(){for(var a,
+b=-1;a=g.momongas[++b];){momongaImage=a.image;if(a._cur.x<=m&&m<=a._cur.x+momongaImage.spliteSize[0]&&a.param.y<=n&&n<=a.param.y+momongaImage.spliteSize[1]){a.clicked();break}}};g.onload=function(){function a(c,e,d){c=new g.Momonga(b[c],e);c.onclick=typeof d==="string"?c[d]:d;g.momongas.push(c)}var b=[new k(i.images["/game/momonga.png"],0,0,36,74),new k(i.images["/game/momonga.png"],36,0,36,74),new k(i.images["/game/momonga.png"],72,0,36,74),new k(i.images["/game/momonga.png"],108,0,36,74)];a(0,{x:10,
+y:10,amp:10,t:50},"blink");a(1,{x:100,y:60,amp:20,t:40},"swing");a(2,{x:50,y:400,amp:20,t:100},function(){i.loadScene(l)});a(3,{x:700,y:100,amp:30,t:70},"blink");a(0,{x:500,y:200,w:24,h:49,amp:10,t:40},"bounce");a(1,{x:400,y:500,w:24,h:49,amp:10,t:50},"blink");a(2,{x:600,y:300,w:48,h:99,amp:20,t:30},"bounce");a(3,{x:200,y:160,w:48,h:99,amp:30,t:70},"blink");a(0,{x:560,y:160,w:48,h:99,amp:20,t:50},"bounce");a(1,{x:300,y:60,w:48,h:99,amp:10,t:100},"blink");a(2,{x:360,y:260,w:24,h:49,amp:20,t:30},"blink");
+a(3,{x:560,y:460,w:24,h:49,amp:30,t:70},"bounce");i.audioPlayers[0].preset(["KrmAKxlI","momongaBG"][Math.floor(Math.random()*2)]);g.stop=y(function(){h.drawImage(i.images["/game/momongaBG.jpg"],0,0);g.momongas.forEach(function(c){c.draw()})});j.addEventListener("click",g.detectClick,false)};g.after=function(){g.stop();i.audioPlayers[0].pause();j.removeEventListener("click",g.detectClick)};l=new o;l.stop=null;l.onload=function(){var a,b=0;a=h.getImageData(0,0,q,r);l.stop=y(function(){h.putImageData(a,
+0,0);h.fillStyle=t="rgba(255, 255, 255, $)".replace("$",b);h.fillRect(0,0,q,r);b>=1&&i.exit();b+=0.01})};l.after=function(){l.stop();j.style.display="none";w.getElementById("answer").style.display="block"};j.width=800;j.height=600;q=800;r=600;i=new s;i.preloadImages=["/game/momonga.png","/game/momongaBG.jpg"];i.preloadAudios={mp3:"/game/momonga.mp3",ogg:"/game/momonga.ogg",volume:0.5,offset:0,preset:{KrmAKxlI:["0:15","3:27",true],momongaBG:["3:33","3:48.238",true],momongaCry:["3:54","3:57.806"]}};
+i.onload=function(){i.loadScene(g)};i.start()})(document,window);

public/game/UnitePlayer.min.js

+// http://uupaa.hatenablog.com/entry/2011/12/12/213233
+// http://code.google.com/p/uupaa-js-spinoff/wiki/UnitePlayer_API
+(function(y,k,n,o){function f(a,d,i){var b=this,e=new Audio,g=a[l],f=a.offset,r=a.preset,k={loadstart:z,canplay:s,load:A,abort:t,error:t,playing:u,pause:B,ended:v};b[j]=e;b.d=d;b.h="";b.g={};b.a=[0,0,0,0];b.e=v;b.f=C;b.b=[0,0,0,0,0];r&&(b.g=D(r,f||0));"loadstart,canplay,load,abort,error,durationchange,playing,pause,ended".split(",").forEach(function(a){e[w](a,function(d){var g=k[a];g&&(g&16?b.e=g:b.f=g);i(d,b,b.d,e[h]||0,e[m]||0)})});e[w]("timeupdate",function(a){var d=b.b,g=e[h];d[0]?g>=d[1]&&(d[2]?
+e[h]=d[3]+(Date.now()-d[4])/1E3:e.pause(),d[0]=0):b.a[2]?g>=b.a[1]&&(e[h]=b.a[3]?b.a[3]:b.a[0]):g>=b.a[1]&&e.pause();i(a,b,b.d,e[h],e[m])});if(e[p])if(a.mp3&&e[p]("audio/mpeg"))e.src=a.mp3;else if(a.ogg&&e[p]("audio/ogg"))e.src=a.ogg;else return;b.volume(g===o?0.5:g);e.play()}function q(a){var d=0,a=(""+a).split(":");switch(a.length){case 3:d+=3600*a.shift();case 2:d+=60*a.shift();case 1:d+=+a[0]}return d}function D(a,d){var i={},b,e,g,h,f;for(b in a)if(e=q(a[b][0]),g=q(a[b][1]),h=a[b][2]||!1,f=a[b][3]?
+q(a[b][3])||0:0,x&&(g&&(g+=0.2),1>g-e&&(g+=0.4)),e<g)i[b]=[d+e,d+g,h,f];else throw Error("BAD_ARG");return i}var k=/iPhone|iP[ao]d/.test(n)?parseFloat(n.split(/OS /)[1].replace("_","."))||4:0,x=/Android/.test(n)?parseFloat(n.split("Android")[1])||2.3:0,C=0,t=1,z=2,s=3,A=4,v=16,B=17,u=18,j="audio",l="volume",m="duration",h="currentTime",p="canPlayType",w="addEventListener";f.ready=!0;f.version=2;f.ios=k;f.android=x;f.needTouchFirst=!!k;f.enableMultiTrack=!!k;f.prototype={preset:function(a){return(a=
+this.g[a])?this.play(a[0],a[1],a[2],a[3]):o},play:function(a,d,i,b){var e=this[j],g=this.f,f=this.e===u;return a<d&&(i&&(this.a=[a,d,1,b]),g>=s)?(i?this.b[0]=0:(this.b[1]=d,this.b[0]++||(this.b[2]=this.d?!1:f,this.b[3]=e[h],this.b[4]=Date.now())),e[h]=a,f||e.play(),!0):!1},pause:function(){var a=this[j];a.paused?a.play():a.pause()},seek:function(a,d){var f=this[j],b=f[h],e=f[m];if(a===o)return b;b="+"===d?b+a:"-"===d?b-a:a;return f[h]=b>e?e:0>b?0:b},mute:function(){var a=this[j];return a.muted=!a.muted},
+info:function(){var a=this[j],d={track:this.d,state:this.e<<8|this.f};d.muted=a.muted;d.paused=a.paused;d[l]=a[l];d[m]=a[m]||0;d[h]=a[h]||0;return d},volume:function(a,d){var f=this[j],b=f[l];if(a===o)return b;b="+"===d?b+a:"-"===d?b-a:a;return f[l]=1<b?1:0>b?0:b}};y.UnitePlayer=f})(this,this.HTMLAudioElement,this.navigator.userAgent);

public/game/momonga.mp3

Binary file added.

public/game/momonga.ogg

Binary file added.

public/game/momonga.png

Added
New image

public/game/momongaBG.jpg

Added
New image

public/images/kyo_front_228x200.png

Added
New image
 <h2>Index</h2>
+<p><a href="/working?q=SpinorNetwork2">第二曲集SpinorNetwork2の配布を開始しました。此れにてSpinorNetworkは完結です。</a></p>
 <p><a href="/working#c100_bunfree14">COMITIA100と第十四回文学フリマの情報を記載しました。</a></p>
 <p><a href="/working?q=SpinorNetwork2">第二曲集SpinorNetwork2の情報を記載し始めました。</a></p>
 <p><a href="/working#m3spring2012">M3春の情報を記載しました。</a></p>

views/_working_SpinorNetwork2.erb

 <h2>SpinorNetwork2</h2>
 <p>第二生成基底:SpinorNetwork2</p>
-<p><img src="/images/SpinorNetwork2_front_227x200.png" alt="SpinorNetwork2 front" /></p>
-<p></p>
+<p><img src="/images/SpinorNetwork2_front_227x200.png" alt="SpinorNetwork2 front" height="200" width="227" /><img src="images/kyo_front_228x200.png" alt="虚 front" height="200" width="228" /></p>
+<p><a href="working?q=cpVine">第一生成基底:cpVine</a>を送り出しSpinorNetworkの深層へと潜っていたCrainは、奇妙な<b>カス</b>を発見した。KrmAKxlI2という名のその<b>カス</b>は、わたしたちと同じ形をしていた。似た姿ではない。<b>同じ</b>だったのだ。KrmAkxlI2はわたしたちがSpinorNetworkへ放った音響楽譜が反射して集まり、像を成したものである。</p>
+<p>「ホットミルク、ミルク無しで。」</p>
+<p>KrmAkxlI2は、それにしては奇妙な注文をした。わたしたちは右手から注文通りのものをだしてやったが、とても美味そうにはみえない。ちくしょう、草乳くらい入れやがれ。</p>
+<p>「それで、わたしは層を見付けたのか。」</p>
+<p>「ああ。しかしgggichを見ろ。層が断裂して了っている。」</p>
+<p>「はは…。」</p>
+<p>KrmAkxlI2は指をなぞらせた。</p>
+<p>「聞きなさい。この断裂。これを層にしてみなさい。そうすれば別のものが見えてくる。」</p>
+<p>→<a href="/game/">Sp2組み立てキットを入手する</a>。</p>
 
-<h3>収録楽曲</h3>
-<p></p>
+<h3>SpinorNetwork2 収録楽曲</h3>
+<iframe width="420" height="315" src="http://www.youtube.com/embed/EvHpJdJZyWk" frameborder="0" allowfullscreen></iframe>
+<p>track 09: gggich</p>
 <ol>
   <li>PROGRESS</li>
   <li>yriplik</li>
 </ol>
 <p>License: CC by <a rel="external" href="http://creativecommons.org/licenses/by-sa/3.0/"><img src="images/cc_by.png" /></a></p>
 
-<h3>How to Buy?</h3>
-<p>price: 300yen</p>
+<h3>虚 収録楽曲</h3>
+<p>計58曲 FLAC形式。</p>
+<p><a rel="external" href="http://c4se.tk/ku_a2.5_hukyoka.html">不許可</a>の続編です。なんらかの事情で公開を思いとどまった曲や、公開のタイミングを失い未公開になっていた楽曲を、発掘しました。</p>
+<h4>Copyleft1700 another (FuniSaya)</h4>
 <p></p>
+<ol>
+  <li>hidden-Lotus (色化2)</li>
+  <li>mp2</li>
+  <li>rideru mife</li>
+  <li>Ginare Ixis</li>
+  <li>Malus halliana</li>
+  <li>回転する橋梁 2</li>
+  <li>摂動法</li>
+  <li>krMDtm_slwrv</li>
+  <li>Star Tail</li>
+</ol>
+<h4>kjth (FuniSaya)</h4>
+<p></p>
+<ol>
+  <li>kjth1_0</li>
+  <li>kjth1_1</li>
+  <li>kjth1_2</li>
+  <li>kjth2_0</li>
+  <li>kjth2_2</li>
+  <li>kjth2_3</li>
+  <li>kjth3_1</li>
+</ol>
+<h4>verzerrte Zynismus (D-moire Type-1)</h4>
+<p></p>
+<ol>
+  <li>ユアンドルフの聖堂</li>
+  <li>Kling-Klang (Stone Age mix)</li>
+  <li>Distorted fakt</li>
+  <li>二重ヶ丘にて</li>
+</ol>
+<h4>Type-1 Reset (D-moire Type-1)</h4>
+<p></p>
+<ol>
+  <li>Kling-Klang F</li>
+  <li>TRK 03</li>
+  <li>モノクローム・アンドロイド</li>
+  <li>酩酊(collage#2)</li>
+  <li>TRK 07</li>
+</ol>
+<h4>nothing (FuniSaya)</h4>
+<p></p>
+<ol>
+  <li>kvn</li>
+  <li>FFtsur</li>
+  <li>fine_sss</li>
+  <li>water</li>
+  <li>yunyun</li>
+  <li>pikcjas</li>
+</ol>
+<h4>虚1 (FuniSaya)</h4>
+<p></p>
+<ol>
+  <li>tempot</li>
+  <li>eggroc</li>
+  <li>getegete</li>
+  <li>KrmAKxlI</li>
+  <li>辛くなる実</li>
+  <li>Point</li>
+  <li>Entsu Tita</li>
+  <li>phKbgja</li>
+  <li>wertPo2</li>
+  <li>純粋な嫉妬</li>
+  <li>lapToKatirf</li>
+  <li>初心</li>
+</ol>
+<h4>虚2</h4>
+<p></p>
+<ol>
+  <li>プリズムは妖怪変化</li>
+  <li>flow</li>
+  <li>lll :Crain Default</li>
+  <li>itswa</li>
+  <li>げろくすん</li>
+  <li>rulottokisiko</li>
+  <li>プリズムは妖怪変化 (default)</li>
+  <li>東国附子</li>
+  <li>Ykpaku</li>
+</ol>
+
+<h3>How to Buy?</h3>
+<p>名称: <b>SpinorNetwork2</b></p>
+<p>内容: SpinorNetwork2 (CD) + 虚 (DVD)</p>
+<p>price: <b>1000yen</b></p>
+<p>注文は<a rel="external" href="http://c4se.tk/fu_lg.html">*Lotus Gate</a>にて受け付けております。</p>
+<p>SpinorNetwork2のデータは無料です→<a href="/game/">Sp2組み立てキットを入手する</a>。</p>
+<p><a href="working?q=cpVine">cpVine (SpinotNetwork1)</a>も無料で提供しております。</p>

views/_working_cpVine.erb

   <li>[<a rel="extrenal" href="http://dl.dropbox.com/u/13307622/cpVine/cpVine.mp3.zip">mp3.zip</a> (44.1kHz 31.8Mb)]</li>
   <li>[<a rel="external" href="http://dl.dropbox.com/u/13307622/cpVine/cpVine.ogg.7z">OggVorbis.7z</a> (48kHz 33.4Mb)]</li>
 </ul>
+<p>Next→<a href="working/?q=SpinorNetwork2">第二生成基底:SpinorNetwork2</a></p>

views/_working_sikiholm.erb

 <div style=""><embed type="application/x-shockwave-flash" src="http://tmbox.net/flash/FMP3.swf?mp3=http://tmbox.net/output/sound/65236&amp;vol=80&amp;action=stop&amp;title=界ツアー ニュースハウンド demo1&amp;color=330000&amp;textcolor=FFFFFF&amp;loop=no&amp;lma=yes" width="260" height="60" id="FMP3" name="FMP3" bgcolor="#000000" quality="high"></div><div><a href="http://tmbox.net/pl/65236" title="界ツアー ニュースハウンド demo1">ふにさやノ゙♪ももんが戦隊グレー:界ツアー ニュースハウンド demo1</a></div>
 <div style=""><embed type="application/x-shockwave-flash" src="http://tmbox.net/flash/FMP3.swf?mp3=http://tmbox.net/output/sound/65248&amp;vol=80&amp;action=stop&amp;title=界ツアー ニュースハウンド demo2&amp;color=330000&amp;textcolor=FFFFFF&amp;loop=no&amp;lma=yes" width="260" height="60" id="FMP3" name="FMP3" bgcolor="#000000" quality="high"></div><div><a href="http://tmbox.net/pl/65248" title="界ツアー ニュースハウンド demo2">ふにさやノ゙♪ももんが戦隊グレー:界ツアー ニュースハウンド demo2</a></div>
 <p><img src="/images/kaiT_newshound.bmx.webp" alt="Screenshot of JeskolaBuzz prohect file." width="480" /></p>
-
-
-<h2><a name="hifuMizumizu"></a>秘封アレンジ合同倶楽部</h2>
-<p></p>