[
  {
    "path": "README.md",
    "content": "# toho-like-js\n\nThis is a touhou style danmaku shooter game which runs on your chrome.\n\n## Demo\n[Demo](http://takahirox.github.io/toho-like-js/index.html)\n\n[Demo(online Co-op play)](http://takahirox.github.io/toho-like-js/index2.html)\n\n## Online co-op play tutorial\n\nhttp://d.hatena.ne.jp/takahirox/20140920/1411190305\n\n## Screenshot\n\n![Screen shot](https://github.com/takahirox/assets/blob/master/toho-like-js/screenshot.gif)\n\n![Screen shot1](http://f.st-hatena.com/images/fotolife/t/takahirox/20140608/20140608210348.png)\n\n![Screen shot2](http://f.st-hatena.com/images/fotolife/t/takahirox/20140919/20140919225039.png)\n\n## Features\n\n- fast rendering and many bullets with WebGL\n- online co-op play with WebRTC\n- watch other players real-time status with WebSocket\n- register your replay and watch other players replays\n\n## Benchmarks\n[WebGL benchmark](http://takahirox.github.io/toho-like-js/webgl_test.html)\n\n[WebRTC performance test](http://takahirox.github.io/toho-like-js/webrtc_test.html)\n\n[WebRTC Simple test](http://takahirox.github.io/toho-like-js/webrtc_trial.html)\n\n## Dependencies\n\n- [glMatrix](https://github.com/toji/gl-matrix)\n\nNo any WebGL 3D libraries, yeah!\n\n## Link\n\n[Touhou Project official site](http://www16.big.or.jp/~zun/)\n"
  },
  {
    "path": "TODO.txt",
    "content": "stage2\n  - bgm\n  - bg\nboss finish bonus\nboss time limit\nspell card finish bonus\nvanish bullet\n\nenemy variation\nBoss effect\nGame pad API\n\nseparate count up from run step?\n\nenemy beam collision\nmulti power items\n\ndivide area\nsin, cos, tan cache\n\nnetwork\n"
  },
  {
    "path": "data/bosses_params.js",
    "content": "var __stage1BossParams = [ ] ;\n\n__stage1BossParams.push(\n  {\n    'count': 2100,\n    'character': 'rumia',\n    'width': 128,\n    'height': 128,\n    'collisionWidth': 50,\n    'collisionHeight': 50,\n    'appearedTalk': false,\n    'vanishedTalk': false,\n    'dead': 'escape',\n    'x': 240,\n    'y': 0,\n    'animation': 3,\n    'powerItem': 1,\n    'score': 1000,\n    'params':\n    [\n      {\n        'spellCard': false,\n        'x': 400,\n        'y': 150,\n        'vital': 200,\n        's': [\n          { 'bullet': 2, 'type':  5, 'r': 20, 'shotCount': [  10,  20,  30, 280, 290, 300 ], 'baseCount': 600 },\n          { 'bullet': 3, 'type':  2,          'shotCount': [ 120, 420 ],                     'baseCount': 600 },\n          { 'bullet': 4, 'type':  7, 'r': 20, 'shotCount': [ 310, 320, 330 ],                'baseCount': 600 },\n          { 'bullet':20, 'type':  6,          'shotCount': [ 130, 430 ],                     'baseCount': 600 },\n        ],\n        'v': [\n          { 'count':   0, 'v': { 'r':  0, 'theta':180, 'w': 0, 'ra':    0, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count':  50, 'v': { 'r':  4, 'theta':200, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count': 200, 'v': { 'r':  4, 'theta':160, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count': 350, 'v': { 'r':  4, 'theta':340, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count': 500, 'v': { 'r':  4, 'theta': 20, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count': 600, 'v': 2 }\n        ],\n      },\n    ]\n  }\n) ;\n\n\n__stage1BossParams.push(\n  {\n    'count': 3200,\n//    'count': 0,\n    'character': 'rumia',\n    'width': 128,\n    'height': 128,\n    'collisionWidth': 50,\n    'collisionHeight': 50,\n    'appearedTalk': true,\n    'vanishedTalk': true,\n    'x': 240,\n    'y': 0,\n    'animation': 3,\n    'powerItem': 1,\n    'score': 5000,\n    'params':\n    [\n      {\n        'x': 240,\n        'y': 150,\n        'vital': 200,\n        's': [\n          { 'bullet': 2, 'type': 3, 'shotCount': [ 250, 260, 270, 280, 290 ],                'baseCount': 400 },\n          { 'bullet': 3, 'type': 3, 'shotCount': [ 340, 360 ],                               'baseCount': 400 },\n          { 'bullet': 4, 'type': 3, 'shotCount': [ 255, 265, 275, 285, 295 ],                'baseCount': 400 },\n          { 'bullet': 5, 'type': 4, 'shotCount': [ 35, 37, 39, 41, 43, 45, 47, 49, 51, 53 ], 'baseCount': 400 },\n          { 'bullet': 6, 'type': 4, 'shotCount': [ 37, 39, 41, 43, 45, 47, 49, 51, 53, 55 ], 'baseCount': 400 },\n          { 'bullet': 7, 'type': 4, 'shotCount': [ 39, 41, 43, 45, 47, 49, 51, 53, 55, 57 ], 'baseCount': 400 },\n          { 'bullet': 8, 'type': 1, 'shotCount': [ 135 ],                                    'baseCount': 400 },\n        ],\n        'v': [\n          { 'count':   0,   'v': { 'r':  0, 'theta': 90, 'w': 0, 'ra':    0, 'wa': 0, 'raa':  0 } },\n          { 'count':  30,   'v': { 'r':  3, 'theta':290, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count': 130,   'v': { 'r':  3, 'theta': 70, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count': 230,   'v': { 'r':  3, 'theta':250, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count': 330,   'v': { 'r':  3, 'theta':110, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count': 400,   'v': 2 }\n        ]\n      },\n      {\n        'spellCard': 'Rumia\\'s Spell 1',\n        'x': 240,\n        'y': 100,\n        'vital': 300,\n        's': [\n          { 'bullet': 9, 'type': 2, 'r': 20, 'shotCount': [ 50, 100, 150, 200 ], 'baseCount': 250 },\n          { 'bullet':10, 'type': 4, 'r': 20, 'shotCount': [ 25,  75, 125, 170 ], 'baseCount': 250 },\n          { 'bullet':11,                     'shotCount': [ 50 ],                'baseCount': 250 },\n        ],\n        'v': [\n          { 'count':   0,   'v': { 'r':  0, 'theta': 90, 'w': 0, 'ra':   0, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count': 250,   'v': { 'r':  3, 'theta': 80, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count': 500,   'v': { 'r':  3, 'theta':240, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count': 750,   'v': { 'r':  3, 'theta':110, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count':1000,   'v': { 'r':  3, 'theta':310 , 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count':1250,   'v': 2 }\n        ]\n      },\n      {\n        'spellCard': 'Rumia\\'s Spell 2',\n        'x': 240,\n        'y': 100,\n        'vital': 300,\n        's': [\n          { 'bullet':12, 'type': 5, 'r': 20, 'shotCount': [ 0 ], 'baseCount': 1 },\n          { 'bullet':12, 'type': 6, 'r': 20, 'shotCount': [ 0 ], 'baseCount': 1 },\n        ],\n        'v': [\n          { 'count':   0,   'v': { 'r':  0, 'theta': 90, 'w': 0, 'ra':   0, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n        ]\n      },\n    ]\n  }\n) ;\n\n\nvar __stage2BossParams = [ ] ;\n\n__stage2BossParams.push(\n  {\n    'count': 2100,\n    'character': 'daiyousei',\n    'width': 128,\n    'height': 128,\n    'collisionWidth': 50,\n    'collisionHeight': 50,\n    'appearedTalk': false,\n    'vanishedTalk': false,\n    'x': 240,\n    'y': 0,\n    'animation': 3,\n    'powerItem': 1,\n    'score': 1000,\n    'params':\n    [\n      {\n        'spellCard': false,\n        'x': 240,\n        'y': 150,\n        'vital': 250,\n        's': [\n          { 'bullet': 14, 'type': 8, 'shotCount': [  10,  20,  30,  40 ], 'baseCount': 300 },\n          { 'bullet': 15, 'type': 9, 'shotCount': [ 160, 170, 180, 190 ], 'baseCount': 300 },\n        ],\n        'v': [\n          { 'count':   0, 'v': { 'r':  0, 'theta': 90 } },\n          { 'count': 149, 'v': { 'target': { 'x': { 'min':  50, 'max': 240 }, 'y': { 'min':100, 'max': 200 }, 'count': 1 } } },\n          { 'count': 150, 'v': { 'r':  0, 'theta': 90 } },\n          { 'count': 299, 'v': { 'target': { 'x': { 'min': 240, 'max': 430 }, 'y': { 'min':100, 'max': 200 }, 'count': 1 } } },\n          { 'count': 300, 'v': { 'r':  0, 'theta': 90 } },\n          { 'count': 449, 'v': { 'target': { 'x': { 'min': 190, 'max': 290 }, 'y': { 'min': 50, 'max': 150 }, 'count': 1 } } },\n          { 'count': 450, 'v': 2 }\n        ],\n        'e': {\n          'vanish': { 'count': 100, 'length': 50, 'baseCount': 150 }\n        }\n      },\n    ]\n  }\n) ;\n\n\n__stage2BossParams.push(\n  {\n    'count': 3200,\n//    'count': 0,\n    'character': 'chilno',\n    'width': 128,\n    'height': 128,\n    'collisionWidth': 50,\n    'collisionHeight': 50,\n    'appearedTalk': true,\n    'vanishedTalk': true,\n    'x': 240,\n    'y': 0,\n    'animation': 3,\n    'powerItem': 1,\n    'score': 5000,\n    'params':\n    [\n      {\n        'spellCard': 'The star of Chilno',\n        'x': 240,\n        'y': 150,\n        'vital': 300,\n        's': [\n          { 'bullet':16, 'type': 4, 'shotCount': [ 20 ], 'baseCount': 100 },\n        ],\n        'v': [\n          { 'count':   0,   'v': { 'r':  0, 'theta': 90, 'w': 0, 'ra':    0, 'wa': 0, 'raa':  0 } },\n        ]\n      },\n      {\n        'spellCard': 'Something freeze',\n        'x': 240,\n        'y': 100,\n        'vital': 300,\n        's': [\n          { 'bullet': 18, 'type': 2, 'r': 20, 'shotCount': [ 0 ],                                 'baseCount': 500 },\n          { 'bullet': 19, 'type': 3, 'r': 20, 'shotCount': [ 350, 355, 360, 365, 370, 375, 380 ], 'baseCount': 500 },\n        ],\n        'v': [ \n          { 'count':   0, 'v': { 'r':   0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n          { 'count':  10,   'v': { 'target': { 'x': { 'min': 100, 'max': 340 }, 'y': { 'min': 80, 'max': 120 }, 'count':100 } } },\n          { 'count': 110, 'v': { 'r':   0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n          { 'count': 335,   'v': { 'target': { 'x': { 'min': 200, 'max': 280 }, 'y': { 'min': 80, 'max': 120 }, 'count': 35 } } },\n          { 'count': 370, 'v': { 'r':   0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n          { 'count': 500, 'v': 2 }\n        ],\n        'e': {\n          'shockwave': [\n            { 'count': 175, 'baseCount': 500, 'params': { 'w': 10, 'g': 5, 'b': 7, 'a': 0.5, 'endCount': 100 } },\n            { 'count': 375, 'baseCount': 500, 'params': { 'w': 10, 'g': 5, 'b': 7, 'a': 0.5, 'endCount': 100 } }\n          ]\n        }\n      },\n      {\n        'spellCard': 'Falling icicle',\n        'x': 240,\n        'y': 100,\n        'vital': 300,\n        's': [\n          { 'bullet':17, 'type': 7, 'r': 20, 'shotCount': [ 0 ], 'baseCount': 1 },\n        ],\n        'v': [\n          { 'count':   0,   'v': { 'r':  0, 'theta': 90, 'w': 0, 'ra':   0, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },\n          { 'count':  50,   'v': { 'target': { 'x': { 'min': 190, 'max': 290 }, 'y': { 'min': 80, 'max': 120 }, 'count': 100 } } },\n          { 'count': 150,   'v': 2 },\n        ]\n      },\n    ]\n  }\n) ;\n\n\nvar __bossesParams = [ ] ;\n__bossesParams.push( __stage1BossParams ) ;\n__bossesParams.push( __stage2BossParams ) ;\n\n\n"
  },
  {
    "path": "data/bullets_params.js",
    "content": "var __danmakuHelper = new DanmakuHelper( ) ;\n\nvar __bulletTypes = [\n  {\n    'image':            0,\n    'indexX':           3,\n    'indexY':           4,\n    'width':           16,\n    'height':          32,\n    'collisionWidth':  16,\n    'collisionHeight': 32,\n    'rotate':          true\n  },\n  {\n    'image':            0,\n    'indexX':           3,\n    'indexY':           3,\n    'width':           16,\n    'height':          32,\n    'collisionWidth':  16,\n    'collisionHeight': 32,\n    'rotate':          true\n  },\n  {\n    'image':            0,\n    'indexX':           1,\n    'indexY':          15,\n    'width':           16,\n    'height':          16,\n    'collisionWidth':  16,\n    'collisionHeight': 16,\n    'rotate':          true\n  },\n  {\n    'image':            0,\n    'indexX':           5,\n    'indexY':           0,\n    'width':           16,\n//    'height':          32,\n    'height':          256,\n    'collisionWidth':  16,\n    'collisionHeight': 32,\n    'rotate':          true\n  },\n] ;\n\n\nvar __bulletsParams = [\n  [\n    [\n      [\n        {\n          'power': 1,\n          'x':   0,\n          'y': -20,\n          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n      ],\n      [\n        {\n          'power': 0.6,\n          'x':  -1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 266, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.6,\n          'x':   1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 274, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.50,\n          'option': 0,\n          'homing': true,\n          'nextCount': 50,\n          'v': { 'r':12, 'theta':210, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },\n        },\n        {\n          'power': 0.50,\n          'option': 1,\n          'homing': true,\n          'nextCount': 50,\n          'v': { 'r':12, 'theta':330, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },\n        },\n      ],\n      [\n        {\n          'power': 0.46,\n          'x':  -1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 262, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.46,\n          'x':   0,\n          'y': -20,\n          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.46,\n          'x':   1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 278, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.40,\n          'option': 0,\n          'homing': true,\n          'nextCount': 20,\n          'v': { 'r':12, 'theta':210, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },\n        },\n        {\n          'power': 0.40,\n          'option': 1,\n          'homing': true,\n          'nextCount': 20,\n          'v': { 'r':12, 'theta':330, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },\n        },\n      ],\n      [\n        {\n          'power': 0.4,\n          'x':  -3,\n          'y': -20,\n          'v': { 'r':12, 'theta': 258, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.4,\n          'x':  -1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 266, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.4,\n          'x':   1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 274, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.4,\n          'x':   3,\n          'y': -20,\n          'v': { 'r':12, 'theta': 282, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.30,\n          'option': 0,\n          'homing': true,\n          'nextCount': 10,\n          'v': { 'r':12, 'theta':210, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },\n        },\n        {\n          'power': 0.30,\n          'option': 1,\n          'homing': true,\n          'nextCount': 10,\n          'v': { 'r':12, 'theta':330, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },\n        },\n      ],\n    ],\n    [\n      [\n        {\n          'power': 1,\n          'x':   0,\n          'y': -20,\n          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n      ],\n      [\n        {\n          'power': 0.6,\n          'x':  -1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 269, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.6,\n          'x':   1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 271, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.5,\n          'option': 0,\n          'homing': true,\n          'nextCount': 50,\n          'v': { 'r':12, 'theta':260, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },\n        },\n        {\n          'power': 0.5,\n          'option': 1,\n          'homing': true,\n          'nextCount': 50,\n          'v': { 'r':12, 'theta':280, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },\n        },\n      ],\n      [\n        {\n          'power': 0.46,\n          'x':  -1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 268, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.46,\n          'x':   0,\n          'y': -20,\n          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.46,\n          'x':   1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 272, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.4,\n          'option': 0,\n          'homing': true,\n          'nextCount': 20,\n          'v': { 'r':12, 'theta':260, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },\n        },\n        {\n          'power': 0.4,\n          'option': 1,\n          'homing': true,\n          'nextCount': 20,\n          'v': { 'r':12, 'theta':280, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },\n        },\n      ],\n      [\n        {\n          'power': 0.4,\n          'x':  -3,\n          'y': -20,\n          'v': { 'r':12, 'theta': 267, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.4,\n          'x':  -1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 269, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.4,\n          'x':   1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 271, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.4,\n          'x':   3,\n          'y': -20,\n          'v': { 'r':12, 'theta': 273, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.3,\n          'option': 0,\n          'homing': true,\n          'nextCount': 10,\n          'v': { 'r':12, 'theta':260, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },\n        },\n        {\n          'power': 0.3,\n          'option': 1,\n          'homing': true,\n          'nextCount': 10,\n          'v': { 'r':12, 'theta':280, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },\n        },\n      ]\n    ]\n  ],\n  [\n    [\n      [\n        {\n          'power': 1,\n          'x':   0,\n          'y': -20,\n          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n      ],\n      [\n        {\n          'power': 0.6,\n          'x':  -1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 266, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.6,\n          'x':   1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 274, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 1,\n          'laser': true,\n          'option': 0,\n          'keep': 80,\n          'waitCount': 50,\n          'nextCount': 220,\n          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 1,\n          'laser': true,\n          'option': 1,\n          'keep': 80,\n          'waitCount': 50,\n          'nextCount': 220,\n          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n      ],\n      [\n        {\n          'power': 0.46,\n          'x':  -1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 262, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.46,\n          'x':   0,\n          'y': -20,\n          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.46,\n          'x':   1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 278, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 1,\n          'option': 0,\n          'laser': true,\n          'keep': 80,\n          'waitCount': 40,\n          'nextCount': 210,\n          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 1,\n          'option': 1,\n          'laser': true,\n          'keep': 80,\n          'waitCount': 40,\n          'nextCount': 210,\n          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n      ],\n      [\n        {\n          'power': 0.4,\n          'x':  -3,\n          'y': -20,\n          'v': { 'r':12, 'theta': 258, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.4,\n          'x':  -1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 266, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.4,\n          'x':   1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 274, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.4,\n          'x':   3,\n          'y': -20,\n          'v': { 'r':12, 'theta': 282, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 1,\n          'option': 0,\n          'laser': true,\n          'keep': 80,\n          'waitCount': 30,\n          'nextCount': 200,\n          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 1,\n          'option': 1,\n          'laser': true,\n          'keep': 80,\n          'waitCount': 30,\n          'nextCount': 200,\n          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n      ],\n    ],\n    [\n      [\n        {\n          'power': 1,\n          'x':   0,\n          'y': -20,\n          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n      ],\n      [\n        {\n          'power': 0.6,\n          'x':  -1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 269, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.6,\n          'x':   1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 271, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 1,\n          'option': 0,\n          'laser': true,\n          'keep': 80,\n          'waitCount': 50,\n          'nextCount': 120,\n          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 1,\n          'option': 1,\n          'laser': true,\n          'keep': 80,\n          'waitCount': 50,\n          'nextCount': 120,\n          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n      ],\n      [\n        {\n          'power': 0.46,\n          'x':  -1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 268, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.46,\n          'x':   0,\n          'y': -20,\n          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.46,\n          'x':   1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 272, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 1,\n          'option': 0,\n          'laser': true,\n          'keep': 80,\n          'waitCount': 40,\n          'nextCount': 110,\n          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 1,\n          'option': 1,\n          'laser': true,\n          'keep': 80,\n          'waitCount': 40,\n          'nextCount': 110,\n          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n      ],\n      [\n        {\n          'power': 0.4,\n          'x':  -3,\n          'y': -20,\n          'v': { 'r':12, 'theta': 267, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.4,\n          'x':  -1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 269, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.4,\n          'x':   1,\n          'y': -20,\n          'v': { 'r':12, 'theta': 271, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 0.4,\n          'x':   3,\n          'y': -20,\n          'v': { 'r':12, 'theta': 273, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 1,\n          'option': 0,\n          'laser': true,\n          'keep': 80,\n          'waitCount': 30,\n          'nextCount': 100,\n          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n        {\n          'power': 1,\n          'option': 1,\n          'laser': true,\n          'keep': 80,\n          'waitCount': 30,\n          'nextCount': 100,\n          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },\n        },\n      ]\n    ],\n  ]\n] ;\n\n\nvar __enemyBulletsParams = [\n  [\n    {\n      'v': { 'r': 5, 'theta': 165, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 135, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 105, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta':  75, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta':  45, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta':  15, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n  ],\n  [\n    {\n      'v': { 'aimed': true, 'r': 5, 'theta':  0, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 3 } },\n    },\n  ],\n  [\n    {\n      'v': { 'r': 5, 'theta':   0, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta':  23, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta':  45, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta':  68, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta':  90, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 113, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 135, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 158, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 180, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 203, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 225, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 248, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 270, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 293, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 315, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 338, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n  ],\n  // TODO: simplify\n  [\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':   0, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':   5, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  10, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  15, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  20, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  45, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  50, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  55, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  60, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  65, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  90, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  95, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 100, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 105, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 110, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 135, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 140, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 145, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 150, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 155, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 180, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 185, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 190, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 195, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 200, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 225, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 230, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 235, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 240, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 245, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 275, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 280, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 285, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 290, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 315, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 320, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 325, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 330, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 335, 'w': 0, 'ra':  0, 'wa': 0 } },\n        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },\n      ]\n    },\n  ],\n  [\n    {\n      'v': { 'r': 5, 'theta':  12, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta':  35, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta':  57, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta':  80, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 102, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 125, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 147, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 170, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 192, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 215, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 237, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 260, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 282, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 305, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 327, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n    {\n      'v': { 'r': 5, 'theta': 350, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },\n    },\n  ],\n  [\n    {\n      'v': { 'aimed': true, 'r': 5, 'theta':-10, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 3 } },\n    },\n  ],\n  [\n    {\n      'v': { 'aimed': true, 'r': 5, 'theta':  0, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 3 } },\n    },\n  ],\n  [\n    {\n      'v': { 'aimed': true, 'r': 5, 'theta': 10, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 3 } },\n    },\n  ],\n  [\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  30, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  35, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.1 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  40, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.2 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  45, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  50, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.4 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  55, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.5 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  60, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.6 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  65, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.7 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  70, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.8 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  75, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.9 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  80, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.0 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  85, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.1 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  90, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.2 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  95, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 100, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.4 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 105, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.5 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 110, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.6 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 115, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.7 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 120, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.8 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 125, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.9 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 130, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.0 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 135, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.1 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 140, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.2 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 145, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 150, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.4 } } },\n      ]\n    },\n  ],\n  [\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':   0, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  10, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.2 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  20, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.4 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  30, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.6 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  40, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.8 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  50, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.0 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  60, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.2 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  70, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.4 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  80, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.6 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  90, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.8 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 100, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.0 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 110, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.2 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 120, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.4 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 130, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.6 } } },\n      ]\n    },\n  ],\n  [\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 175, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.1 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 165, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 155, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.5 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 145, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.7 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 135, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.9 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 125, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.1 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 115, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta': 105, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.5 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  95, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.7 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  85, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.9 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  75, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.1 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  65, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.3 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  55, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.5 } } },\n      ]\n    },\n    {\n      'v': [\n        { 'count':  0, 'v': { 'r': 0, 'theta':  45, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.7 } } },\n      ]\n    },\n  ],\n  [\n    {\n      'laser': true,\n      'waitCount': 40,\n      'keep': 150,\n      'v': { 'r': 0, 'theta': 180, 'w': -0.01, 'ra':0, 'wa': -0.01, 'trange': { 'min': 110 } },\n    },\n    {\n      'laser': true,\n      'waitCount': 40,\n      'keep': 150,\n      'v': { 'r': 0, 'theta':   0, 'w':  0.01, 'ra':0, 'wa':  0.01, 'trange': { 'max':  70 } },\n    },\n  ],\n  [\n    {\n      'v': { 'r': 5, 'theta':   0, 'w': 0, 'ra': 0, 'wa': 0, 'rrandom': { 'min': 4, 'max': 5 }, 'trandom': { 'min': 0, 'max': 360 } },\n    },\n  ],\n  [\n    {\n      'v': { 'r': 3, 'theta':  45, 'w': 0, 'ra': 0, 'wa': 0, 'raa': 0 },\n    },\n    {\n      'v': { 'r': 3, 'theta': 135, 'w': 0, 'ra': 0, 'wa': 0, 'raa': 0 },\n    },\n    {\n      'v': { 'r': 3, 'theta': 225, 'w': 0, 'ra': 0, 'wa': 0, 'raa': 0 },\n    },\n    {\n      'v': { 'r': 3, 'theta': 315, 'w': 0, 'ra': 0, 'wa': 0, 'raa': 0 },\n    },\n  ],\n  __danmakuHelper.daiYousei1( ),\n  __danmakuHelper.daiYousei2( ),\n  __danmakuHelper.chilno1( ),\n  [\n    {\n      'v': { 'r': 2, 'theta':   0, 'w': 0, 'ra': 0, 'wa': 0, 'rrandom': { 'min': 2, 'max': 3 }, 'trandom': { 'min': 0, 'max': 360 },\n             'g': { 'r': 0, 'theta': 90, 'ra': 0.05 }\n           },\n    },\n  ],\n  __danmakuHelper.chilno2( ),\n  [\n    {\n      'v': { 'aimed': true, 'r': 5, 'theta':-15, 'w': 0 },\n    },\n    {\n      'v': { 'aimed': true, 'r': 5, 'theta': -5, 'w': 0 },\n    },\n    {\n      'v': { 'aimed': true, 'r': 5, 'theta':  5, 'w': 0 },\n    },\n    {\n      'v': { 'aimed': true, 'r': 5, 'theta': 15, 'w': 0 },\n    },\n  ],\n  [\n    {\n      'beam': true,\n      'v': { 'rrandom': { 'min': 4, 'max': 6 }, 'trandom': { 'min': 180, 'max': 200 },\n             'g': { 'r': 0, 'theta': 90, 'ra': 0.3 }\n           },\n    },\n    {\n      'beam': true,\n      'v': { 'rrandom': { 'min': 4, 'max': 6 }, 'trandom': { 'min': 225, 'max': 245 },\n             'g': { 'r': 0, 'theta': 90, 'ra': 0.3 }\n           },\n    },\n    {\n      'beam': true,\n      'v': { 'rrandom': { 'min': 4, 'max': 6 }, 'trandom': { 'min': 270, 'max': 290 },\n             'g': { 'r': 0, 'theta': 90, 'ra': 0.3 }\n           },\n    },\n    {\n      'beam': true,\n      'v': { 'rrandom': { 'min': 4, 'max': 6 }, 'trandom': { 'min': 340, 'max': 360 },\n             'g': { 'r': 0, 'theta': 90, 'ra': 0.3 }\n           },\n    },\n  ],\n] ;\n\n\nvar __enemyBulletTypes = [\n  {\n    'indexX':          15,\n    'indexY':           3,\n    'width':           16,\n    'height':          16,\n    'collisionWidth':  10,\n    'collisionHeight': 10\n  },\n  {\n    'indexX':           2,\n    'indexY':           3,\n    'width':           16,\n    'height':          16,\n    'collisionWidth':  10,\n    'collisionHeight': 10\n  },\n  {\n    'indexX':           8,\n    'indexY':           3,\n    'width':           16,\n    'height':          16,\n    'collisionWidth':  10,\n    'collisionHeight': 10\n  },\n  {\n    'indexX':           6,\n    'indexY':           3,\n    'width':           16,\n    'height':          16,\n    'collisionWidth':  10,\n    'collisionHeight': 10\n  },\n  {\n    'indexX':           7,\n    'indexY':           3,\n    'width':           16,\n    'height':          16,\n    'collisionWidth':  10,\n    'collisionHeight': 10\n  },\n  {\n    'indexX':          13,\n    'indexY':           4,\n    'width':           16,\n    'height':          16,\n    'collisionWidth':   5,\n    'collisionHeight':  5,\n    'rotate':        true,\n  },\n  {\n    'indexX':          10,\n    'indexY':           4,\n    'width':           16,\n    'height':          16,\n    'collisionWidth':   5,\n    'collisionHeight':  5,\n    'rotate':        true,\n  },\n  {\n    'indexX':           7,\n    'indexY':           4,\n    'width':           16,\n    'height':          16,\n    'collisionWidth':   5,\n    'collisionHeight':  5,\n    'rotate':        true,\n  },\n  {\n    'indexX':           1,\n    'indexY':           5,\n    'width':           16,\n    'height':          16,\n    'collisionWidth':   5,\n    'collisionHeight':  5,\n    'rotate':        true,\n  },\n  {\n    'indexX':           9,\n    'indexY':           5,\n    'width':           16,\n    'height':          16,\n    'collisionWidth':   5,\n    'collisionHeight':  5,\n    'rotate':        true,\n  },\n] ;\n"
  },
  {
    "path": "data/danmaku_helper.js",
    "content": "function DanmakuHelper( ) {\n\n}\n\nDanmakuHelper.prototype._calculateRadian = function( theta ) {\n  return theta * Math.PI / 180 ;\n} ;\n\n\nDanmakuHelper.prototype._calculateTheta = function( radian ) {\n  return parseInt( radian * 180 / Math.PI ) ;\n} ;\n\n\nDanmakuHelper.prototype.daiYousei1 = function( ) {\n  var array = [ ] ;\n  var r = 30 ;\n  for( var i = 0; i < 36; i++ ) {\n    var count = i * 1 ;\n    var t = ( ( i * 10 ) + 90 ) % 360 ;\n    var v = { 'x': r * Math.cos( this._calculateRadian( t ) ),\n              'y': r * Math.sin( this._calculateRadian( t ) ),\n              'count': i * 1,\n              'v': { 'r': 2 + ( i / 50 ), 'theta': t }\n            } ;\n    array.push( v ) ;\n  }\n  return array ;\n} ;\n\n\nDanmakuHelper.prototype.daiYousei2 = function( ) {\n  var array = [ ] ;\n  var r = 30 ;\n  for( var i = 0; i < 36; i++ ) {\n    var count = i * 1 ;\n    var t = ( ( i * -10 ) + 450 ) % 360 ;\n    var v = { 'x': r * Math.cos( this._calculateRadian( t ) ),\n              'y': r * Math.sin( this._calculateRadian( t ) ),\n              'count': count,\n              'v': { 'r': 2 + ( i / 50 ), 'theta': t }\n            } ;\n    array.push( v ) ;\n  }\n  return array ;\n} ;\n\n\nDanmakuHelper.prototype.chilno1 = function( ) {\n  var array = [ ] ;\n  var r = 50 ;\n  var r2 = 100 ;\n  var points = [ ] ;\n  var span = 10 ;\n  for( var i = 0; i < 5; i++ ) {\n    points[ i ] = ( 126 + 144 * i ) % 360 ;\n  }\n  for( var i = 0; i < 5; i++ ) {\n    var t1 = points[ i ] ;\n    var t2 = points[ ( i + 1 ) % 5 ] ;\n    var x1 = r * Math.cos( this._calculateRadian( t1 ) ) ;\n    var y1 = r * Math.sin( this._calculateRadian( t1 ) ) ;\n    var x2 = r * Math.cos( this._calculateRadian( t2 ) ) ;\n    var y2 = r * Math.sin( this._calculateRadian( t2 ) ) ;\n    for( var j = 0; j < span; j++ ) {\n      var count = ( j + i * span ) ;\n      var x = x1 + ( x2 - x1 ) / span * j ;\n      var y = y1 + ( y2 - y1 ) / span * j ;\n      var t = this._calculateTheta( Math.atan2( y, x ) ) ;\n      for( var k = 0; k < 5; k++ ) {\n        var at = points[ k ] ;\n        var ax = x + r2 * Math.cos( this._calculateRadian( at ) ) ;\n        var ay = y + r2 * Math.sin( this._calculateRadian( at ) ) ;\n        var v = { 'x': ax,\n                  'y': ay,\n                  'count': count,\n                  'v': [\n                    { 'count': 0,            'v': { 'r': 0, 'theta': t, } },\n                    { 'count': span*6-count, 'v': { 'r': 2, 'w': 0 } }\n                  ]\n                } ;\n        array.push( v ) ;\n      }\n    }\n  }\n  return array ;\n} ;\n\n\nDanmakuHelper.prototype.chilno2 = function( ) {\n  var array = [ ] ;\n  for( var i = 0; i < 200; i++ ) {\n    var count = i * 1 ;\n    var v = {\n              'count': count,\n              'v': [\n                { 'count': 0,\n                  'v': { 'r': 5, 'theta':   0, 'w': 0, 'ra': -0.01, 'wa': 0, 'rrandom': { 'min': 4, 'max': 5 }, 'rrange': { 'min': 2 }, 'trandom': { 'min': 0, 'max': 360 } },\n                },\n                { 'count': 200 - count,\n                  'v': { 'r': 0 },\n                },\n                { 'count': 400 - count,\n                  'v': { 'r': 1, 'theta':   0, 'w': 0, 'ra': 0.02, 'wa': 0, 'trandom': { 'min': 0, 'max': 360 } },\n                },\n              ]\n            } ;\n    array.push( v ) ;\n  }\n  return array ;\n} ;\n"
  },
  {
    "path": "data/enemies_params.js",
    "content": "var __stage1EnemiesParams = [ ] ;\n\n\n/*\n__stage1EnemiesParams.push(\n  { 'count': 100,\n    'x': 240,\n    'y': 100,\n    'vital': 3,\n    's': [\n      { 'bullet': 20, 'type': 6, 'shotCount': [ 10 ], 'loop': true },\n//      { 'bullet': 11, 'type': 6, 'shotCount': [ 100 ], 'loop': true },\n//      { 'bullet': 8, 'type': 7, 'shotCount': [ 0 ], 'loop': true, 'r': 20 },\n    ],\n    'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 },\n  }\n) ;\n*/\n\nfor( var i = 0; i < 6 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 100 + i * 15,\n      'x': 50 + i * 20,\n      'vital': 1,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },\n        { 'count':  50,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 135 }, 'wrange': { 'max': 0.5 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 6 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 300 + i * 15,\n      'x': 380 - i * 20,\n      'vital': 1,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  50,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': 45 }, 'wrange': { 'min': -0.5 } } },\n      ]\n    }\n  ) ;\n}\n\n\nfor( var i = 0; i < 6 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 500 + i * 15,\n      'x': 50 + i * 20,\n      'vital': 1,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },\n        { 'count':  50,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 135 }, 'wrange': { 'max': 0.5 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 6 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 700 + i * 15,\n      'x': 380 - i * 20,\n      'vital': 1,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  50,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': 45 }, 'wrange': { 'min': -0.5 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 900 + i * ( 80 - i * 5 ),\n      'x': 25 + (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 950 + i * ( 80 - i * 5 ),\n      'x': 455 - (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 4 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 1400 + i * 20,\n      'x': 50 + i * 50,\n      'vital': 1,\n      'powerItem': i % 4 == 0 ? 1 : 0,\n      'scoreItem': i % 4 == 2 ? 1 : 0,\n      's': { 'bullet': 1, 'shotCount': [ 40 ] },\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },\n        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': -30 }, 'wrange': { 'min': -1 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 4 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 1410 + i * 10,\n      'x': 25 + i * 50,\n      'vital': 1,\n      'powerItem': i % 4 == 0 ? 1 : 0,\n      'scoreItem': i % 4 == 2 ? 1 : 0,\n      's': { 'bullet': 1, 'shotCount': [ 40 ] },\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },\n        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': -30 }, 'wrange': { 'min': -1 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 4 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 1420 + i * 20,\n      'x': 430 - i * 50,\n      'vital': 1,\n      'powerItem': i % 4 == 0 ? 1 : 0,\n      'scoreItem': i % 4 == 2 ? 1 : 0,\n      's': { 'bullet': 1, 'shotCount': [ 40 ] },\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 210 }, 'wrange': { 'max': 1 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 4 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 1430 + i * 10,\n      'x': 455 - i * 50,\n      'vital': 1,\n      'powerItem': i % 4 == 0 ? 1 : 0,\n      'scoreItem': i % 4 == 2 ? 1 : 0,\n      's': { 'bullet': 1, 'shotCount': [ 40 ] },\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 210 }, 'wrange': { 'max': 1 } } },\n      ]\n    }\n  ) ;\n}\n\n\nfor( var i = 0; i < 20 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count':1700 + parseInt( i/2 ) * 10,\n      'x': ( i%2 == 0 ? 50 : 80 ) + i * 10,\n      'vital': 1,\n      'powerItem': i % 4 == 0 ? 1 : 0,\n      'scoreItem': i % 4 == 2 ? 1 : 0,\n      'v': [\n        { 'count':   0,  'v': { 'r': 3,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },\n        { 'count':  30,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa':-0.02, 'trange': { 'min': -45 }, 'wrange': { 'min': -1 } } },\n        { 'count': 180,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa': 0.02, 'trange': { 'max':  45 }, 'wrange': { 'max':  1 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 20 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 1900 + parseInt( i/2 ) * 10,\n      'x': ( i%2 == 0 ? 430 : 400 ) - i * 10,\n      'vital': 1,\n      'powerItem': i % 4 == 0 ? 1 : 0,\n      'scoreItem': i % 4 == 2 ? 1 : 0,\n      'v': [\n        { 'count':   0,  'v': { 'r': 3,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },\n        { 'count':  30,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa': 0.02, 'trange': { 'max': 225 }, 'wrange': { 'max':  1 } } },\n        { 'count': 180,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa':-0.02, 'trange': { 'min': 135 }, 'wrange': { 'min': -1 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 2300 + i * ( 80 - i * 5 ),\n      'x': 25 + (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 2350 + i * ( 80 - i * 5 ),\n      'x': 455 - (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 2500 + i * ( 80 - i * 5 ),\n      'x': 25 + (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 2550 + i * ( 80 - i * 5 ),\n      'x': 455 - (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 2700 + i * ( 80 - i * 5 ),\n      'x': 25 + (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage1EnemiesParams.push(\n    { 'count': 2750 + i * ( 80 - i * 5 ),\n      'x': 455 - (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },\n      ]\n    }\n  ) ;\n}\n\n\nvar __stage2EnemiesParams = [ ] ;\n\nfor( var i = 0; i < 100 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 100 + i * 5,\n      'x': parseInt(__randomizer.random() * 480),\n      'vital': 1,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      's': { 'bullet': 13, 'shotCount': [ 10 ] },\n      'v': [\n        { 'count':   0,  'v': { 'r': 3,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 6 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 500 + i * 15,\n      'x': 50 + i * 20,\n      'vital': 1,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },\n        { 'count':  50,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 135 }, 'wrange': { 'max': 0.5 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 6 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 700 + i * 15,\n      'x': 380 - i * 20,\n      'vital': 1,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  50,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': 45 }, 'wrange': { 'min': -0.5 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 900 + i * ( 80 - i * 5 ),\n      'x': 25 + (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 950 + i * ( 80 - i * 5 ),\n      'x': 455 - (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 4 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 1400 + i * 20,\n      'x': 50 + i * 50,\n      'vital': 1,\n      'powerItem': i % 4 == 0 ? 1 : 0,\n      'scoreItem': i % 4 == 2 ? 1 : 0,\n      's': { 'bullet': 1, 'shotCount': [ 40 ] },\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },\n        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': -30 }, 'wrange': { 'min': -1 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 4 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 1410 + i * 10,\n      'x': 25 + i * 50,\n      'vital': 1,\n      'powerItem': i % 4 == 0 ? 1 : 0,\n      'scoreItem': i % 4 == 2 ? 1 : 0,\n      's': { 'bullet': 1, 'shotCount': [ 40 ] },\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },\n        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': -30 }, 'wrange': { 'min': -1 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 4 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 1420 + i * 20,\n      'x': 430 - i * 50,\n      'vital': 1,\n      'powerItem': i % 4 == 0 ? 1 : 0,\n      'scoreItem': i % 4 == 2 ? 1 : 0,\n      's': { 'bullet': 1, 'shotCount': [ 40 ] },\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 210 }, 'wrange': { 'max': 1 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 4 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 1430 + i * 10,\n      'x': 455 - i * 50,\n      'vital': 1,\n      'powerItem': i % 4 == 0 ? 1 : 0,\n      'scoreItem': i % 4 == 2 ? 1 : 0,\n      's': { 'bullet': 1, 'shotCount': [ 40 ] },\n      'v': [\n        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 210 }, 'wrange': { 'max': 1 } } },\n      ]\n    }\n  ) ;\n}\n\n\nfor( var i = 0; i < 20 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count':1700 + parseInt( i/2 ) * 10,\n      'x': ( i%2 == 0 ? 50 : 80 ) + i * 10,\n      'vital': 1,\n      'powerItem': i % 4 == 0 ? 1 : 0,\n      'scoreItem': i % 4 == 2 ? 1 : 0,\n      'v': [\n        { 'count':   0,  'v': { 'r': 3,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },\n        { 'count':  30,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa':-0.02, 'trange': { 'min': -45 }, 'wrange': { 'min': -1 } } },\n        { 'count': 180,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa': 0.02, 'trange': { 'max':  45 }, 'wrange': { 'max':  1 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 20 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 1900 + parseInt( i/2 ) * 10,\n      'x': ( i%2 == 0 ? 430 : 400 ) - i * 10,\n      'vital': 1,\n      'powerItem': i % 4 == 0 ? 1 : 0,\n      'scoreItem': i % 4 == 2 ? 1 : 0,\n      'v': [\n        { 'count':   0,  'v': { 'r': 3,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },\n        { 'count':  30,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa': 0.02, 'trange': { 'max': 225 }, 'wrange': { 'max':  1 } } },\n        { 'count': 180,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa':-0.02, 'trange': { 'min': 135 }, 'wrange': { 'min': -1 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 2300 + i * ( 80 - i * 5 ),\n      'x': 25 + (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 2350 + i * ( 80 - i * 5 ),\n      'x': 455 - (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 2500 + i * ( 80 - i * 5 ),\n      'x': 25 + (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 2550 + i * ( 80 - i * 5 ),\n      'x': 455 - (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 2700 + i * ( 80 - i * 5 ),\n      'x': 25 + (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },\n      ]\n    }\n  ) ;\n}\n\nfor( var i = 0; i < 8 ; i++ ) {\n  __stage2EnemiesParams.push(\n    { 'count': 2750 + i * ( 80 - i * 5 ),\n      'x': 455 - (i%4) * 50,\n      'vital': 3,\n      'powerItem': i % 2 == 0 ? 1 : 0,\n      'scoreItem': i % 2 == 1 ? 1 : 0,\n      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },\n      'v': [\n        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },\n        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },\n      ]\n    }\n  ) ;\n}\n\n\nvar __enemiesParams = [ ] ;\n__enemiesParams.push( __stage1EnemiesParams ) ;\n__enemiesParams.push( __stage2EnemiesParams ) ;\n\n"
  },
  {
    "path": "data/stage_params.js",
    "content": "var __stage1Params = {\n  'title': 'Nothing Special',\n  'bgScale': [\n    { 'beginCount':    0, 'endCount':    1, 'a': 0.5 },\n    { 'beginCount':  500, 'endCount': 1500, 'd': 0.0002 },\n    { 'beginCount': 2500, 'endCount': 3000, 'd': -0.0004 },\n  ]\n} ;\n\nvar __stage2Params = {\n  'title': 'Something Special',\n  'bgScale': [\n    { 'beginCount':    0, 'endCount':    1, 'a': 1.0 },\n    { 'beginCount':  500, 'endCount': 1500, 'd': -0.0001 },\n    { 'beginCount': 2500, 'endCount': 3000, 'd': -0.0006 },\n  ]\n} ;\n\nvar __stageParams = [ ] ;\n__stageParams.push( __stage1Params ) ;\n__stageParams.push( __stage2Params ) ;\n\n"
  },
  {
    "path": "data/talk_params.js",
    "content": "var __reimuBossTalkParams = [ ] ;\nvar __marisaBossTalkParams = [ ] ;\n\n__reimuBossTalkParams.push(\n  { 'serif': 'Hi, how\\'re you doing, Rumia?',\n    'left':  { 'character': 'reimu', 'active': true },\n    'right': { 'character': 'rumia' },\n  }\n) ;\n\n__reimuBossTalkParams.push(\n  { 'serif': 'Good. But hungry. Can I eat you?',\n    'left':  { 'character': 'reimu' },\n    'right': { 'character': 'rumia', 'active': true },\n  }\n) ;\n\n__reimuBossTalkParams.push(\n  { 'serif': 'Sorry, I\\'m busy now.\\nI can play with you after I solve the Ihen.',\n    'left':  { 'character': 'reimu', 'active': true },\n    'right': { 'character': 'rumia' },\n  }\n) ;\n\n\n__marisaBossTalkParams.push(\n  { 'serif': 'Hi, Marisa. What are you doing now?',\n    'left':  { 'character': 'marisa' },\n    'right': { 'character': 'rumia', 'active': true },\n  }\n) ;\n\n__marisaBossTalkParams.push(\n  { 'serif': 'Ah? I just enjoy flying now.',\n    'left':  { 'character': 'marisa', 'active': true},\n    'right': { 'character': 'rumia' },\n  }\n) ;\n\n__marisaBossTalkParams.push(\n  { 'serif': 'So-nano-ka-?',\n    'left':  { 'character': 'marisa' },\n    'right': { 'character': 'rumia',  'active': true },\n  }\n) ;\n\nvar __stage1BossTalkParams = [ ] ;\n__stage1BossTalkParams.push( __reimuBossTalkParams ) ;\n__stage1BossTalkParams.push( __marisaBossTalkParams ) ;\n\nvar __reimuClearTalkParams = [ ] ;\n\n__reimuClearTalkParams.push(\n  { 'serif': 'Got tired.',\n    'left':  { 'character': 'reimu', 'active': true },\n  }\n) ;\n\nvar __marisaClearTalkParams = [ ] ;\n\n__marisaClearTalkParams.push(\n  { 'serif': 'I\\'ve done it.',\n    'left':  { 'character': 'marisa', 'active': true },\n  }\n) ;\n\nvar __stage1ClearTalkParams = [ ] ;\n__stage1ClearTalkParams.push( __reimuClearTalkParams ) ;\n__stage1ClearTalkParams.push( __marisaClearTalkParams ) ;\n\nvar __stage1TalksParams = [ ] ;\n__stage1TalksParams.push( __stage1BossTalkParams ) ;\n__stage1TalksParams.push( __stage1ClearTalkParams ) ;\n\n\nvar __reimuBossTalk2Params = [ ] ;\n__reimuBossTalk2Params.push(\n  { 'serif': 'Sorry, I have no topics.',\n    'left':  { 'character': 'reimu', 'active': true },\n    'right': { 'character': 'chilno' },\n  }\n) ;\n\n__reimuBossTalk2Params.push(\n  { 'serif': 'W-What\\'s!?',\n    'left':  { 'character': 'reimu' },\n    'right': { 'character': 'chilno', 'active': true },\n  }\n) ;\n\n\nvar __marisaBossTalk2Params = [ ] ;\n__marisaBossTalk2Params.push(\n  { 'serif': 'Sorry, I have no topics.',\n    'left':  { 'character': 'marisa', 'active': true },\n    'right': { 'character': 'chilno' },\n  }\n) ;\n\n__marisaBossTalk2Params.push(\n  { 'serif': 'W-What\\'s!?',\n    'left':  { 'character': 'marisa' },\n    'right': { 'character': 'chilno', 'active': true },\n  }\n) ;\n\n\nvar __stage2BossTalkParams = [ ] ;\n__stage2BossTalkParams.push( __reimuBossTalk2Params ) ;\n__stage2BossTalkParams.push( __marisaBossTalk2Params ) ;\n\n\nvar __stage2TalksParams = [ ] ;\n__stage2TalksParams.push( __stage2BossTalkParams ) ;\n__stage2TalksParams.push( __stage1ClearTalkParams ) ; // TODO: temporal\n\n\nvar __talkParams = [ ] ;\n__talkParams.push( __stage1TalksParams ) ;\n__talkParams.push( __stage2TalksParams ) ;\n\n"
  },
  {
    "path": "index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<title>Toho like shooting with JavaScript</title>\n<script type=\"text/javascript\" src=\"lib/glMatrix-0.9.5.min.js\"></script>\n<script type=\"text/javascript\" src=\"utility/Inherit.js\"></script>\n<script type=\"text/javascript\" src=\"utility/Draw.js\"></script>\n<script type=\"text/javascript\" src=\"utility/Random.js\"></script>\n<script type=\"text/javascript\" src=\"utility/FreeList.js\"></script>\n<script type=\"text/javascript\" src=\"utility/WebGL.js\"></script>\n<script type=\"text/javascript\" src=\"utility/Peer.js\"></script>\n<script type=\"text/javascript\" src=\"data/danmaku_helper.js\"></script>\n<script type=\"text/javascript\" src=\"data/bullets_params.js\"></script>\n<script type=\"text/javascript\" src=\"data/enemies_params.js\"></script>\n<script type=\"text/javascript\" src=\"data/bosses_params.js\"></script>\n<script type=\"text/javascript\" src=\"data/talk_params.js\"></script>\n<script type=\"text/javascript\" src=\"data/stage_params.js\"></script>\n<script type=\"text/javascript\" src=\"source/GameSocket.js\"></script>\n<script type=\"text/javascript\" src=\"source/Game.js\"></script>\n<script type=\"text/javascript\" src=\"source/MoveVector.js\"></script>\n<script type=\"text/javascript\" src=\"source/Element.js\"></script>\n<script type=\"text/javascript\" src=\"source/Background.js\"></script>\n<script type=\"text/javascript\" src=\"source/Fighter.js\"></script>\n<script type=\"text/javascript\" src=\"source/FighterOption.js\"></script>\n<script type=\"text/javascript\" src=\"source/Enemy.js\"></script>\n<script type=\"text/javascript\" src=\"source/Boss.js\"></script>\n<script type=\"text/javascript\" src=\"source/Effect.js\"></script>\n<script type=\"text/javascript\" src=\"source/Bullet.js\"></script>\n<script type=\"text/javascript\" src=\"source/Bomb.js\"></script>\n<script type=\"text/javascript\" src=\"source/EnemyBullet.js\"></script>\n<script type=\"text/javascript\" src=\"source/Item.js\"></script>\n<script type=\"text/javascript\" src=\"source/SpellCard.js\"></script>\n<script type=\"text/javascript\" src=\"source/GameState.js\"></script>\n<script type=\"text/javascript\" src=\"source/LoadingState.js\"></script>\n<script type=\"text/javascript\" src=\"source/OpeningState.js\"></script>\n<script type=\"text/javascript\" src=\"source/CharacterSelectState.js\"></script>\n<script type=\"text/javascript\" src=\"source/ReplaySelectState.js\"></script>\n<script type=\"text/javascript\" src=\"source/PostReplayState.js\"></script>\n<script type=\"text/javascript\" src=\"source/StageState.js\"></script>\n<script type=\"text/javascript\" src=\"source/EndingState.js\"></script>\n<script type=\"text/javascript\" src=\"source/StaffRollState.js\"></script>\n<script type=\"text/javascript\">\n\nvar __game ;\n\nvar init = function( ) {\n  var mainCanvas = document.getElementById( 'mainCanvas' ) ;\n  var bgCanvas = document.getElementById('bgCanvas');\n  var game = new Game(mainCanvas, bgCanvas);\n  __game = game ;\n  window.onkeydown = function(event) { game.handleKeyDown(event); };\n  window.onkeyup = function(event) { game.handleKeyUp(event); };\n  game.run( ) ;\n} ;\n\n</script>\n</head>\n\n<body onLoad=\"init( )\">\n\n<div id=\"canvasdiv\" style=\"position:relative; width:640px; height:480px\">\n<canvas id=\"mainCanvas\" width=\"640\" height=\"480\"\n style=\"z-index: 2; position:absolute;left0px;top0px;\"></canvas>\n<canvas id=\"bgCanvas\" width=\"480\" height=\"480\"\n style=\"z-index: 1; position:absolute;left0px;top0px;\"></canvas>\n</div>\n\n<p>\nHow to play\n</p>\n<ul>\n<li>Cursor key: move / character select</li>\n<li>Z:          shot / ok</li>\n<li>X:          bomb / cancel</li>\n<li>Shift:      slow</li>\n<li>Space:      character change(for debug)</li>\n<li>Y:          viewpoint change</li>\n</ul>\n\n<p>\nTurn your hardware acceleration on to fully enjoy this game.<br />\nSee &quot;chrome://gpu&quot; and &quot;chrome://flags&quot; on your chrome to check if your hardware acceleration is enabled.\n</p>\n\n<p>\nThanks for all the images and musics.\n</p>\n<ul>\n<li>SE, etc  <a href=\"http://www.danmakufu.net/?%E5%88%B6%E4%BD%9C%2F%E3%83%AA%E3%83%B3%E3%82%AF\">http://www.danmakufu.net/?%E5%88%B6%E4%BD%9C%2F%E3%83%AA%E3%83%B3%E3%82%AF</a></li>\n<li>SE       <a href=\"http://commons.nicovideo.jp/material/nc1456\">http://commons.nicovideo.jp/material/nc1456</a></li>\n<li>Face     <a href=\"http://kinginsan.blog60.fc2.com/\">http://kinginsan.blog60.fc2.com/</a></li>\n<li>Standup  <a href=\"http://gensoukyou.1000.tv/\">http://gensoukyou.1000.tv/</a></li>\n<li>Marisa   <a href=\"http://commons.nicovideo.jp/material/nc71167\">http://commons.nicovideo.jp/material/nc71167</a></li>\n<li>Reimu    <a href=\"http://commons.nicovideo.jp/material/nc70557\">http://commons.nicovideo.jp/material/nc70557</a></li>\n<li>Bullet   <a href=\"http://commons.nicovideo.jp/material/nc74535\">http://commons.nicovideo.jp/material/nc74535</a></li>\n<li>BG       <a href=\"http://subtlepatterns.com/hixs-evolution/\">http://subtlepatterns.com/hixs-evolution/</a></li>\n<li>BG       <a href=\"http://gi0.net/\">http://gi0.net/</a></li>\n<li>BG       <a href=\"http://commons.nicovideo.jp/material/nc21291\">http://commons.nicovideo.jp/material/nc21291</a></li>\n<li>BGM      <a href=\"http://commons.nicovideo.jp/material/nc25738\">http://commons.nicovideo.jp/material/nc25738</a></li>\n<li>BGM      <a href=\"http://commons.nicovideo.jp/material/nc13447\">http://commons.nicovideo.jp/material/nc13447</a></li>\n<li>BGM      <a href=\"http://commons.nicovideo.jp/material/nc22928\">http://commons.nicovideo.jp/material/nc22928</a></li>\n</ul>\n\n<p>\nThis game is made by <a href=\"http://twitter.com/superhoge\">@suprehoge</a>\n</p>\n\n<p>\n<a href=\"https://github.com/takahirox/toho-like-js\">Source code</a>\n</p>\n\n</body>\n</html>\n"
  },
  {
    "path": "index2.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<title>Toho like shooting with JavaScript</title>\n<script type=\"text/javascript\" src=\"lib/glMatrix-0.9.5.min.js\"></script>\n<script type=\"text/javascript\" src=\"utility/Inherit.js\"></script>\n<script type=\"text/javascript\" src=\"utility/Draw.js\"></script>\n<script type=\"text/javascript\" src=\"utility/Random.js\"></script>\n<script type=\"text/javascript\" src=\"utility/FreeList.js\"></script>\n<script type=\"text/javascript\" src=\"utility/WebGL.js\"></script>\n<script type=\"text/javascript\" src=\"utility/Peer.js\"></script>\n<script type=\"text/javascript\" src=\"data/danmaku_helper.js\"></script>\n<script type=\"text/javascript\" src=\"data/bullets_params.js\"></script>\n<script type=\"text/javascript\" src=\"data/enemies_params.js\"></script>\n<script type=\"text/javascript\" src=\"data/bosses_params.js\"></script>\n<script type=\"text/javascript\" src=\"data/talk_params.js\"></script>\n<script type=\"text/javascript\" src=\"data/stage_params.js\"></script>\n<script type=\"text/javascript\" src=\"source/GameSocket.js\"></script>\n<script type=\"text/javascript\" src=\"source/Game.js\"></script>\n<script type=\"text/javascript\" src=\"source/MoveVector.js\"></script>\n<script type=\"text/javascript\" src=\"source/Element.js\"></script>\n<script type=\"text/javascript\" src=\"source/Background.js\"></script>\n<script type=\"text/javascript\" src=\"source/Fighter.js\"></script>\n<script type=\"text/javascript\" src=\"source/FighterOption.js\"></script>\n<script type=\"text/javascript\" src=\"source/Enemy.js\"></script>\n<script type=\"text/javascript\" src=\"source/Boss.js\"></script>\n<script type=\"text/javascript\" src=\"source/Effect.js\"></script>\n<script type=\"text/javascript\" src=\"source/Bullet.js\"></script>\n<script type=\"text/javascript\" src=\"source/Bomb.js\"></script>\n<script type=\"text/javascript\" src=\"source/EnemyBullet.js\"></script>\n<script type=\"text/javascript\" src=\"source/Item.js\"></script>\n<script type=\"text/javascript\" src=\"source/SpellCard.js\"></script>\n<script type=\"text/javascript\" src=\"source/GameState.js\"></script>\n<script type=\"text/javascript\" src=\"source/LoadingState.js\"></script>\n<script type=\"text/javascript\" src=\"source/OpeningState.js\"></script>\n<script type=\"text/javascript\" src=\"source/CharacterSelectState.js\"></script>\n<script type=\"text/javascript\" src=\"source/ReplaySelectState.js\"></script>\n<script type=\"text/javascript\" src=\"source/PostReplayState.js\"></script>\n<script type=\"text/javascript\" src=\"source/StageState.js\"></script>\n<script type=\"text/javascript\" src=\"source/EndingState.js\"></script>\n<script type=\"text/javascript\" src=\"source/StaffRollState.js\"></script>\n<script type=\"text/javascript\">\n\n// for console\nvar __game;\nvar __connectButton, __statusSpan;\nvar __alreadyConnected = false;\n\n\n// TODO: temporal\nvar __reloadWithRandomRoomNo = function(baseURL, params) {\n  var args = '';\n  if(params.lag !== null)\n    args = '&l=' + params.lag;\n\n  location.href = baseURL + '?' + (Math.random() * 10000 | 0) + args;\n};\n\n\n// TODO: temporal\nvar __validateURL = function(params) {\n  var array = location.href.split('?');\n  var baseURL = array[0];\n\n  if(array.length <= 1) {\n    __reloadWithRandomRoomNo(baseURL, params);\n    return false;\n  }\n\n  var args = array[1].split('&');\n\n  if(args.length > 1) {\n    for(var i = 1; i < args.length; i++) {\n      var p = args[i].split('=');\n      if(p[0] === 'l' && ! isNaN(p[1])) {\n        params.lag = parseInt(p[1]);\n        if(params.lag < 1)\n          params.lag = 1;\n        if(params.lag > 20)\n          params.lag = 20;\n      }\n    }\n  }\n\n  var room = args[0];\n  if(room === '' || isNaN(room)) {\n    __reloadWithRandomRoomNo(baseURL, params);\n    return false;\n  }\n  params.room = parseInt(room);\n  return true;\n};\n\n\nvar __init = function( ) {\n  // TODO: temporal\n  var params = {room: null, lag: null};\n  if(! __validateURL(params)) {\n    return -1;\n  }\n\n  var room = params.room;\n  document.getElementById('room').innerText = room;\n\n  __statusSpan = document.getElementById('status');\n  __connectButton = document.getElementById('connectButton');\n\n  __statusSpan.innerText = '0 in the room.';\n  __connectButton.disabled = true;\n\n  var mainCanvas = document.getElementById( 'mainCanvas' ) ;\n  var bgCanvas = document.getElementById('bgCanvas');\n  var game = new Game(mainCanvas, bgCanvas);\n  game.setRoom(room);\n  if(params.lag !== null)\n    game.setLag(params.lag);\n\n  __game = game ;\n\n  game.onWsReady = function(event) { __wsReady(event); };\n  game.onRoomUpdate = function(num) { __updatedRoom(num); };\n  game.onConnected = function(event) { __connected(event); };\n  game.onSentParams = function() { __waitingForOther(); };\n  game.onRan = function() { __ranTheGame(); };\n\n  window.onkeydown = function(event) { game.handleKeyDown(event); };\n  window.onkeyup = function(event) { game.handleKeyUp(event); };\n\n  __game.run();\n} ;\n\n\nvar __wsReady = function(event) {\n//  __connectButton.disabled = false;\n};\n\n\nvar __connect = function() {\n  __connectButton.disabled = true;\n  __statusSpan.innerText = 'connecting.';\n  __game.connect();\n};\n\n\nvar __updatedRoom = function(num) {\n  if(! __alreadyConnected) {\n    __statusSpan.innerText = num + ' in the room.';\n    if(num < 2) {\n      __connectButton.disabled = true;\n      __statusSpan.innerText += ' (need one more person)';\n    } else if(num == 2) {\n      __connectButton.disabled = false;\n      __statusSpan.innerText += ' (ready to push connect button)';\n    } else {\n      __connectButton.disabled = true;\n      __statusSpan.innerText += ' (over capacity)';\n    }\n  }\n};\n\n\nvar __connected = function() {\n  __alreadyConnected = true;\n  __connectButton.disabled = true;\n  __statusSpan.innerText = 'connected.';\n};\n\n\nvar __waitingForOther = function() {\n  __statusSpan.innerText = 'waiting for other\\'s character select.';\n};\n\n\nvar __ranTheGame = function() {\n  __statusSpan.innerText = 'ran.';\n};\n\n\n</script>\n</head>\n\n<body onLoad=\"__init()\">\n\nRoom No. <span id=\"room\"></span>\n<button id=\"connectButton\" onclick=\"__connect()\">connect</button>\n<span id=\"status\"></span>\n\n<div id=\"canvasdiv\" style=\"position:relative; width:640px; height:480px\">\n<canvas id=\"mainCanvas\" width=\"640\" height=\"480\"\n style=\"z-index: 2; position:absolute;left0px;top0px;\"></canvas>\n<canvas id=\"bgCanvas\" width=\"480\" height=\"480\"\n style=\"z-index: 1; position:absolute;left0px;top0px;\"></canvas>\n</div>\n\n<p>\nHow to play\n</p>\n<ul>\n<li>Cursor key: move / character select</li>\n<li>Z:          shot / ok</li>\n<li>X:          bomb / cancel</li>\n<li>Shift:      slow</li>\n<li>Space:      character change(for debug)</li>\n<li>Y:          viewpoint change</li>\n</ul>\n\n<p>\nTurn your hardware acceleration on to fully enjoy this game.<br />\nSee &quot;chrome://gpu&quot; and &quot;chrome://flags&quot; on your chrome to check if your hardware acceleration is enabled.\n</p>\n\n<p>\nThanks for all the images and musics.\n</p>\n<ul>\n<li>SE, etc  <a href=\"http://www.danmakufu.net/?%E5%88%B6%E4%BD%9C%2F%E3%83%AA%E3%83%B3%E3%82%AF\">http://www.danmakufu.net/?%E5%88%B6%E4%BD%9C%2F%E3%83%AA%E3%83%B3%E3%82%AF</a></li>\n<li>SE       <a href=\"http://commons.nicovideo.jp/material/nc1456\">http://commons.nicovideo.jp/material/nc1456</a></li>\n<li>Face     <a href=\"http://kinginsan.blog60.fc2.com/\">http://kinginsan.blog60.fc2.com/</a></li>\n<li>Standup  <a href=\"http://gensoukyou.1000.tv/\">http://gensoukyou.1000.tv/</a></li>\n<li>Marisa   <a href=\"http://commons.nicovideo.jp/material/nc71167\">http://commons.nicovideo.jp/material/nc71167</a></li>\n<li>Reimu    <a href=\"http://commons.nicovideo.jp/material/nc70557\">http://commons.nicovideo.jp/material/nc70557</a></li>\n<li>Bullet   <a href=\"http://commons.nicovideo.jp/material/nc74535\">http://commons.nicovideo.jp/material/nc74535</a></li>\n<li>BG       <a href=\"http://subtlepatterns.com/hixs-evolution/\">http://subtlepatterns.com/hixs-evolution/</a></li>\n<li>BG       <a href=\"http://gi0.net/\">http://gi0.net/</a></li>\n<li>BG       <a href=\"http://commons.nicovideo.jp/material/nc21291\">http://commons.nicovideo.jp/material/nc21291</a></li>\n<li>BGM      <a href=\"http://commons.nicovideo.jp/material/nc25738\">http://commons.nicovideo.jp/material/nc25738</a></li>\n<li>BGM      <a href=\"http://commons.nicovideo.jp/material/nc13447\">http://commons.nicovideo.jp/material/nc13447</a></li>\n<li>BGM      <a href=\"http://commons.nicovideo.jp/material/nc22928\">http://commons.nicovideo.jp/material/nc22928</a></li>\n</ul>\n\n<p>\nThis game is made by <a href=\"http://twitter.com/superhoge\">@suprehoge</a>\n</p>\n\n<p>\n<a href=\"https://github.com/takahirox/toho-like-js\">Source code</a>\n</p>\n\n</body>\n</html>\n"
  },
  {
    "path": "replay/replay1.txt",
    "content": "{\n  user: 'takahirox',\n  characterIndex: 0,\n  seed: 57914,\n  params: [\n    {count: 34, z: true},\n    {count: 46, l: true},\n    {count: 46, z: false},\n    {count: 80, u: true},\n    {count: 81, l: false},\n    {count: 102, l: true},\n    {count: 104, u: false},\n    {count: 111, l: false},\n    {count: 130, z: true},\n    {count: 136, r: true},\n    {count: 168, l: true},\n    {count: 168, r: false},\n    {count: 203, z: false},\n    {count: 205, u: true},\n    {count: 205, l: false},\n    {count: 235, r: true},\n    {count: 240, u: false},\n    {count: 250, r: false},\n    {count: 261, r: true},\n    {count: 263, r: false},\n    {count: 268, r: true},\n    {count: 271, r: false},\n    {count: 278, r: true},\n    {count: 282, r: false},\n    {count: 288, r: true},\n    {count: 295, d: true},\n    {count: 310, d: false},\n    {count: 350, z: true},\n    {count: 352, l: true},\n    {count: 353, r: false},\n    {count: 390, r: true},\n    {count: 391, l: false},\n    {count: 424, u: true},\n    {count: 425, z: false},\n    {count: 428, r: false},\n    {count: 443, l: true},\n    {count: 447, u: false},\n    {count: 461, l: false},\n    {count: 473, l: true},\n    {count: 477, l: false},\n    {count: 481, l: true},\n    {count: 493, l: false},\n    {count: 493, d: true},\n    {count: 522, l: true},\n    {count: 526, d: false},\n    {count: 574, z: true},\n    {count: 574, r: true},\n    {count: 574, l: false},\n    {count: 610, l: true},\n    {count: 611, r: false},\n    {count: 611, z: false},\n    {count: 648, u: true},\n    {count: 651, l: false},\n    {count: 667, r: true},\n    {count: 670, u: false},\n    {count: 687, r: false},\n    {count: 697, r: true},\n    {count: 702, r: false},\n    {count: 705, r: true},\n    {count: 714, d: true},\n    {count: 740, d: false},\n    {count: 764, z: true},\n    {count: 769, r: false},\n    {count: 772, l: true},\n    {count: 780, s: true},\n    {count: 812, s: false},\n    {count: 813, r: true},\n    {count: 814, l: false},\n    {count: 844, u: true},\n    {count: 846, r: false},\n    {count: 868, l: true},\n    {count: 869, u: false},\n    {count: 884, l: false},\n    {count: 892, l: true},\n    {count: 903, d: true},\n    {count: 904, l: false},\n    {count: 955, l: true},\n    {count: 956, d: false},\n    {count: 961, s: true},\n    {count: 987, s: false},\n    {count: 1025, u: true},\n    {count: 1026, l: false},\n    {count: 1041, r: true},\n    {count: 1043, u: false},\n    {count: 1055, d: true},\n    {count: 1062, d: false},\n    {count: 1076, d: true},\n    {count: 1090, d: false},\n    {count: 1091, l: true},\n    {count: 1091, r: false},\n    {count: 1137, l: false},\n    {count: 1137, u: true},\n    {count: 1165, u: false},\n    {count: 1166, r: true},\n    {count: 1177, d: true},\n    {count: 1188, d: false},\n    {count: 1191, r: false},\n    {count: 1216, l: true},\n    {count: 1248, l: false},\n    {count: 1254, u: true},\n    {count: 1264, u: false},\n    {count: 1272, r: true},\n    {count: 1277, r: false},\n    {count: 1297, r: true},\n    {count: 1324, r: false},\n    {count: 1329, d: true},\n    {count: 1367, d: false},\n    {count: 1385, r: true},\n    {count: 1399, u: true},\n    {count: 1400, r: false},\n    {count: 1429, u: false},\n    {count: 1439, l: true},\n    {count: 1473, l: false},\n    {count: 1481, u: true},\n    {count: 1538, l: true},\n    {count: 1539, u: false},\n    {count: 1545, l: false},\n    {count: 1549, r: true},\n    {count: 1562, d: true},\n    {count: 1571, r: false},\n    {count: 1633, r: true},\n    {count: 1636, d: false},\n    {count: 1652, r: false},\n    {count: 1660, r: true},\n    {count: 1678, u: true},\n    {count: 1679, r: false},\n    {count: 1693, l: true},\n    {count: 1695, u: false},\n    {count: 1710, u: true},\n    {count: 1712, l: false},\n    {count: 1738, r: true},\n    {count: 1738, u: false},\n    {count: 1742, d: true},\n    {count: 1747, r: false},\n    {count: 1806, l: true},\n    {count: 1807, d: false},\n    {count: 1823, r: true},\n    {count: 1824, l: false},\n    {count: 1848, r: false},\n    {count: 1849, l: true},\n    {count: 1873, u: true},\n    {count: 1874, l: false},\n    {count: 1906, r: true},\n    {count: 1907, u: false},\n    {count: 1916, r: false},\n    {count: 1936, r: true},\n    {count: 1944, d: true},\n    {count: 1960, d: false},\n    {count: 1985, r: false},\n    {count: 1986, l: true},\n    {count: 1999, l: false},\n    {count: 2002, l: true},\n    {count: 2033, l: false},\n    {count: 2035, r: true},\n    {count: 2079, u: true},\n    {count: 2082, r: false},\n    {count: 2095, l: true},\n    {count: 2096, u: false},\n    {count: 2121, l: false},\n    {count: 2130, l: true},\n    {count: 2132, l: false},\n    {count: 2136, l: true},\n    {count: 2152, l: false},\n    {count: 2156, r: true},\n    {count: 2192, s: true},\n    {count: 2199, d: true},\n    {count: 2200, r: false},\n    {count: 2214, d: false},\n    {count: 2272, d: true},\n    {count: 2292, d: false},\n    {count: 2293, l: true},\n    {count: 2335, u: true},\n    {count: 2337, l: false},\n    {count: 2379, l: true},\n    {count: 2380, u: false},\n    {count: 2385, l: false},\n    {count: 2395, d: true},\n    {count: 2428, d: false},\n    {count: 2430, l: true},\n    {count: 2446, l: false},\n    {count: 2451, l: true},\n    {count: 2456, l: false},\n    {count: 2461, l: true},\n    {count: 2465, l: false},\n    {count: 2469, l: true},\n    {count: 2473, l: false},\n    {count: 2475, l: true},\n    {count: 2490, u: true},\n    {count: 2491, l: false},\n    {count: 2511, u: false},\n    {count: 2516, l: true},\n    {count: 2521, l: false},\n    {count: 2539, d: true},\n    {count: 2576, d: false},\n    {count: 2580, r: true},\n    {count: 2602, r: false},\n    {count: 2607, r: true},\n    {count: 2610, r: false},\n    {count: 2620, u: true},\n    {count: 2649, u: false},\n    {count: 2651, r: true},\n    {count: 2677, r: false},\n    {count: 2682, d: true},\n    {count: 2703, d: false},\n    {count: 2708, r: true},\n    {count: 2713, r: false},\n    {count: 2717, r: true},\n    {count: 2720, r: false},\n    {count: 2723, r: true},\n    {count: 2724, r: false},\n    {count: 2728, r: true},\n    {count: 2729, r: false},\n    {count: 2733, r: true},\n    {count: 2735, r: false},\n    {count: 2737, r: true},\n    {count: 2740, r: false},\n    {count: 2744, r: true},\n    {count: 2746, r: false},\n    {count: 2749, r: true},\n    {count: 2752, r: false},\n    {count: 2756, r: true},\n    {count: 2757, r: false},\n    {count: 2760, r: true},\n    {count: 2785, s: false},\n    {count: 2792, r: false},\n    {count: 2799, d: true},\n    {count: 2814, l: true},\n    {count: 2814, d: false},\n    {count: 2831, l: false},\n    {count: 2832, u: true},\n    {count: 2846, u: false},\n    {count: 2847, r: true},\n    {count: 2853, d: true},\n    {count: 2858, r: false},\n    {count: 2864, d: false},\n    {count: 2868, l: true},\n    {count: 2895, l: false},\n    {count: 2896, u: true},\n    {count: 2903, u: false},\n    {count: 2904, l: true},\n    {count: 2959, l: false},\n    {count: 2960, r: true},\n    {count: 3025, r: false},\n    {count: 3025, l: true},\n    {count: 3068, d: true},\n    {count: 3069, l: false},\n    {count: 3076, l: true},\n    {count: 3077, d: false},\n    {count: 3102, u: true},\n    {count: 3104, l: false},\n    {count: 3120, u: false},\n    {count: 3121, r: true},\n    {count: 3130, d: true},\n    {count: 3134, r: false},\n    {count: 3139, d: false},\n    {count: 3176, d: true},\n    {count: 3182, d: false},\n    {count: 3196, d: true},\n    {count: 3201, d: false},\n    {count: 3212, r: true},\n    {count: 3221, r: false},\n    {count: 3241, u: true},\n    {count: 3248, u: false},\n    {count: 3249, l: true},\n    {count: 3276, u: true},\n    {count: 3276, l: false},\n    {count: 3285, u: false},\n    {count: 3298, d: true},\n    {count: 3304, d: false},\n    {count: 3314, r: true},\n    {count: 3319, r: false},\n    {count: 3324, r: true},\n    {count: 3327, r: false},\n    {count: 3331, r: true},\n    {count: 3337, r: false},\n    {count: 3338, r: true},\n    {count: 3344, r: false},\n    {count: 3372, d: true},\n    {count: 3375, r: true},\n    {count: 3376, d: false},\n    {count: 3380, r: false},\n    {count: 3393, r: true},\n    {count: 3397, r: false},\n    {count: 3400, r: true},\n    {count: 3408, r: false},\n    {count: 3422, l: true},\n    {count: 3426, l: false},\n    {count: 3437, l: true},\n    {count: 3440, l: false},\n    {count: 3459, r: true},\n    {count: 3464, u: true},\n    {count: 3468, r: false},\n    {count: 3471, l: true},\n    {count: 3471, u: false},\n    {count: 3477, l: false},\n    {count: 3484, l: true},\n    {count: 3488, l: false},\n    {count: 3493, l: true},\n    {count: 3519, l: false},\n    {count: 3520, r: true},\n    {count: 3540, r: false},\n    {count: 3566, r: true},\n    {count: 3570, r: false},\n    {count: 3576, d: true},\n    {count: 3581, d: false},\n    {count: 3592, r: true},\n    {count: 3604, r: false},\n    {count: 3612, l: true},\n    {count: 3620, l: false},\n    {count: 3621, d: true},\n    {count: 3628, d: false},\n    {count: 3639, r: true},\n    {count: 3645, u: true},\n    {count: 3647, r: false},\n    {count: 3666, u: false},\n    {count: 3667, r: true},\n    {count: 3674, r: false},\n    {count: 3677, d: true},\n    {count: 3684, d: false},\n    {count: 3691, l: true},\n    {count: 3711, l: false},\n    {count: 3724, r: true},\n    {count: 3730, r: false},\n    {count: 3735, u: true},\n    {count: 3742, u: false},\n    {count: 3755, l: true},\n    {count: 3760, l: false},\n    {count: 3783, d: true},\n    {count: 3791, d: false},\n    {count: 3795, r: true},\n    {count: 3809, u: true},\n    {count: 3813, r: false},\n    {count: 3829, r: true},\n    {count: 3831, u: false},\n    {count: 3839, d: true},\n    {count: 3856, d: false},\n    {count: 3867, r: false},\n    {count: 3891, z: false},\n    {count: 3907, l: true},\n    {count: 3912, u: true},\n    {count: 3914, l: false},\n    {count: 3921, u: false},\n    {count: 3987, z: true},\n    {count: 4034, z: true},\n    {count: 4050, z: true},\n    {count: 4066, z: true},\n    {count: 4077, l: true},\n    {count: 4087, s: true},\n    {count: 4097, l: false},\n    {count: 4098, d: true},\n    {count: 4105, r: true},\n    {count: 4106, d: false},\n    {count: 4114, d: true},\n    {count: 4116, r: false},\n    {count: 4121, d: false},\n    {count: 4131, l: true},\n    {count: 4136, l: false},\n    {count: 4147, l: true},\n    {count: 4150, l: false},\n    {count: 4159, l: true},\n    {count: 4163, l: false},\n    {count: 4169, l: true},\n    {count: 4173, l: false},\n    {count: 4176, l: true},\n    {count: 4182, l: false},\n    {count: 4193, r: true},\n    {count: 4217, d: true},\n    {count: 4219, r: false},\n    {count: 4230, d: false},\n    {count: 4285, l: true},\n    {count: 4288, l: false},\n    {count: 4312, u: true},\n    {count: 4316, u: false},\n    {count: 4320, l: true},\n    {count: 4324, l: false},\n    {count: 4329, l: true},\n    {count: 4334, l: false},\n    {count: 4346, u: true},\n    {count: 4349, u: false},\n    {count: 4365, u: true},\n    {count: 4367, u: false},\n    {count: 4372, u: true},\n    {count: 4377, u: false},\n    {count: 4421, l: true},\n    {count: 4427, l: false},\n    {count: 4491, r: true},\n    {count: 4502, r: false},\n    {count: 4575, r: true},\n    {count: 4584, r: false},\n    {count: 4597, d: true},\n    {count: 4603, d: false},\n    {count: 4605, r: true},\n    {count: 4617, d: true},\n    {count: 4623, r: false},\n    {count: 4627, d: false},\n    {count: 4666, l: true},\n    {count: 4674, l: false},\n    {count: 4707, s: false},\n    {count: 4709, l: true},\n    {count: 4720, l: false},\n    {count: 4721, u: true},\n    {count: 4757, s: true},\n    {count: 4765, u: false},\n    {count: 4774, d: true},\n    {count: 4828, d: false},\n    {count: 4831, l: true},\n    {count: 4837, l: false},\n    {count: 4859, r: true},\n    {count: 4865, r: false},\n    {count: 5126, r: true},\n    {count: 5142, d: true},\n    {count: 5149, d: false},\n    {count: 5155, r: false},\n    {count: 5163, r: true},\n    {count: 5171, r: false},\n    {count: 5185, r: true},\n    {count: 5189, r: false},\n    {count: 5208, r: true},\n    {count: 5215, r: false},\n    {count: 5225, r: true},\n    {count: 5239, r: false},\n    {count: 5268, d: true},\n    {count: 5284, r: true},\n    {count: 5285, d: false},\n    {count: 5290, r: false},\n    {count: 5305, l: true},\n    {count: 5317, l: false},\n    {count: 5325, d: true},\n    {count: 5334, d: false},\n    {count: 5336, l: true},\n    {count: 5341, l: false},\n    {count: 5353, l: true},\n    {count: 5358, l: false},\n    {count: 5387, l: true},\n    {count: 5392, l: false},\n    {count: 5410, r: true},\n    {count: 5420, r: false},\n    {count: 5433, l: true},\n    {count: 5443, l: false},\n    {count: 5450, l: true},\n    {count: 5453, l: false},\n    {count: 5466, r: true},\n    {count: 5474, r: false},\n    {count: 5482, u: true},\n    {count: 5490, u: false},\n    {count: 5492, l: true},\n    {count: 5500, l: false},\n    {count: 5515, r: true},\n    {count: 5519, r: false},\n    {count: 5543, l: true},\n    {count: 5548, l: false},\n    {count: 5564, r: true},\n    {count: 5573, r: false},\n    {count: 5582, l: true},\n    {count: 5598, l: false},\n    {count: 5628, d: true},\n    {count: 5635, d: false},\n    {count: 5637, r: true},\n    {count: 5643, r: false},\n    {count: 5674, r: true},\n    {count: 5679, r: false},\n    {count: 5692, r: true},\n    {count: 5699, r: false},\n    {count: 5710, r: true},\n    {count: 5712, r: false},\n    {count: 5725, r: true},\n    {count: 5729, r: false},\n    {count: 5747, s: false},\n    {count: 5749, u: true},\n    {count: 5821, s: true},\n    {count: 5823, u: false},\n    {count: 5826, r: true},\n    {count: 5831, r: false},\n    {count: 5856, l: true},\n    {count: 5860, l: false},\n    {count: 5874, d: true},\n    {count: 5885, d: false},\n    {count: 5900, d: true},\n    {count: 5906, d: false},\n    {count: 5930, r: true},\n    {count: 5934, r: false},\n    {count: 5959, l: true},\n    {count: 5963, l: false},\n    {count: 5997, l: true},\n    {count: 5999, u: true},\n    {count: 6000, l: false},\n    {count: 6014, u: false},\n    {count: 6018, r: true},\n    {count: 6021, r: false},\n    {count: 6050, r: true},\n    {count: 6055, r: false},\n    {count: 6058, u: true},\n    {count: 6075, l: true},\n    {count: 6075, u: false},\n    {count: 6080, u: true},\n    {count: 6080, l: false},\n    {count: 6084, u: false},\n    {count: 6086, r: true},\n    {count: 6093, r: false},\n    {count: 6115, l: true},\n    {count: 6123, l: false},\n    {count: 6128, u: true},\n    {count: 6132, u: false},\n    {count: 6144, l: true},\n    {count: 6147, l: false},\n    {count: 6163, r: true},\n    {count: 6166, r: false},\n    {count: 6175, u: true},\n    {count: 6179, u: false},\n    {count: 6184, r: true},\n    {count: 6187, r: false},\n    {count: 6200, r: true},\n    {count: 6203, r: false},\n    {count: 6209, l: true},\n    {count: 6211, l: false},\n    {count: 6215, l: true},\n    {count: 6219, l: false},\n    {count: 6224, r: true},\n    {count: 6231, r: false},\n    {count: 6235, l: true},\n    {count: 6244, l: false},\n    {count: 6258, u: true},\n    {count: 6261, u: false},\n    {count: 6264, r: true},\n    {count: 6268, r: false},\n  ]\n}"
  },
  {
    "path": "replay/replay2.txt",
    "content": "{\n  user: 'takahirox',\n  characterIndex: 1,\n  seed: 11249,\n  params: [\n    {count: 26, d: true},\n    {count: 33, d: false},\n    {count: 40, z: true},\n    {count: 46, l: true},\n    {count: 91, r: true},\n    {count: 92, l: false},\n    {count: 131, r: false},\n    {count: 131, l: true},\n    {count: 163, l: false},\n    {count: 164, r: true},\n    {count: 194, l: true},\n    {count: 194, r: false},\n    {count: 224, l: false},\n    {count: 225, u: true},\n    {count: 243, u: false},\n    {count: 244, r: true},\n    {count: 249, z: false},\n    {count: 253, r: false},\n    {count: 272, r: true},\n    {count: 277, r: false},\n    {count: 314, r: true},\n    {count: 319, r: false},\n    {count: 330, r: true},\n    {count: 380, l: true},\n    {count: 381, r: false},\n    {count: 382, z: true},\n    {count: 412, r: true},\n    {count: 412, l: false},\n    {count: 439, z: false},\n    {count: 440, u: true},\n    {count: 441, r: false},\n    {count: 470, l: true},\n    {count: 473, u: false},\n    {count: 480, l: false},\n    {count: 490, l: true},\n    {count: 495, l: false},\n    {count: 501, l: true},\n    {count: 506, l: false},\n    {count: 513, l: true},\n    {count: 516, l: false},\n    {count: 519, d: true},\n    {count: 547, l: true},\n    {count: 549, d: false},\n    {count: 588, z: true},\n    {count: 594, r: true},\n    {count: 595, l: false},\n    {count: 626, l: true},\n    {count: 626, r: false},\n    {count: 650, u: true},\n    {count: 651, l: false},\n    {count: 653, z: false},\n    {count: 682, r: true},\n    {count: 683, u: false},\n    {count: 693, r: false},\n    {count: 701, r: true},\n    {count: 706, r: false},\n    {count: 718, r: true},\n    {count: 724, d: true},\n    {count: 765, l: true},\n    {count: 766, z: true},\n    {count: 766, d: false},\n    {count: 767, r: false},\n    {count: 793, r: true},\n    {count: 794, l: false},\n    {count: 825, u: true},\n    {count: 826, r: false},\n    {count: 829, z: false},\n    {count: 865, l: true},\n    {count: 867, u: false},\n    {count: 880, l: false},\n    {count: 887, l: true},\n    {count: 892, l: false},\n    {count: 902, d: true},\n    {count: 911, z: true},\n    {count: 939, s: true},\n    {count: 945, l: true},\n    {count: 946, d: false},\n    {count: 990, d: true},\n    {count: 991, l: false},\n    {count: 1002, l: true},\n    {count: 1002, d: false},\n    {count: 1032, u: true},\n    {count: 1032, l: false},\n    {count: 1052, r: true},\n    {count: 1052, u: false},\n    {count: 1076, d: true},\n    {count: 1079, r: false},\n    {count: 1088, d: false},\n    {count: 1114, l: true},\n    {count: 1138, u: true},\n    {count: 1140, l: false},\n    {count: 1161, u: false},\n    {count: 1172, r: true},\n    {count: 1181, d: true},\n    {count: 1185, r: false},\n    {count: 1196, d: false},\n    {count: 1200, d: true},\n    {count: 1210, r: true},\n    {count: 1212, d: false},\n    {count: 1215, d: true},\n    {count: 1217, r: false},\n    {count: 1223, r: true},\n    {count: 1224, d: false},\n    {count: 1234, r: false},\n    {count: 1249, r: true},\n    {count: 1256, r: false},\n    {count: 1259, u: true},\n    {count: 1263, l: true},\n    {count: 1264, u: false},\n    {count: 1302, r: true},\n    {count: 1302, s: false},\n    {count: 1303, l: false},\n    {count: 1327, r: false},\n    {count: 1378, r: true},\n    {count: 1388, r: false},\n    {count: 1466, l: true},\n    {count: 1493, l: false},\n    {count: 1523, u: true},\n    {count: 1571, u: false},\n    {count: 1575, r: true},\n    {count: 1582, d: true},\n    {count: 1592, d: false},\n    {count: 1594, r: false},\n    {count: 1600, d: true},\n    {count: 1605, r: true},\n    {count: 1610, r: false},\n    {count: 1627, d: false},\n    {count: 1684, u: true},\n    {count: 1726, u: false},\n    {count: 1732, d: true},\n    {count: 1781, l: true},\n    {count: 1782, d: false},\n    {count: 1793, l: false},\n    {count: 1793, r: true},\n    {count: 1827, l: true},\n    {count: 1828, r: false},\n    {count: 1862, u: true},\n    {count: 1864, l: false},\n    {count: 1882, u: false},\n    {count: 1883, r: true},\n    {count: 1901, r: false},\n    {count: 1918, r: true},\n    {count: 1922, r: false},\n    {count: 1932, r: true},\n    {count: 1936, r: false},\n    {count: 1944, r: true},\n    {count: 1956, d: true},\n    {count: 1970, s: true},\n    {count: 1976, d: false},\n    {count: 1977, r: false},\n    {count: 1978, l: true},\n    {count: 2012, r: true},\n    {count: 2012, s: false},\n    {count: 2013, l: false},\n    {count: 2050, r: false},\n    {count: 2050, u: true},\n    {count: 2069, l: true},\n    {count: 2070, u: false},\n    {count: 2091, l: false},\n    {count: 2097, l: true},\n    {count: 2101, l: false},\n    {count: 2105, l: true},\n    {count: 2110, l: false},\n    {count: 2115, l: true},\n    {count: 2121, l: false},\n    {count: 2123, l: true},\n    {count: 2128, l: false},\n    {count: 2131, r: true},\n    {count: 2153, s: true},\n    {count: 2156, d: true},\n    {count: 2158, r: false},\n    {count: 2186, d: false},\n    {count: 2192, r: true},\n    {count: 2196, r: false},\n    {count: 2207, r: true},\n    {count: 2212, r: false},\n    {count: 2217, r: true},\n    {count: 2221, r: false},\n    {count: 2226, r: true},\n    {count: 2230, r: false},\n    {count: 2242, d: true},\n    {count: 2247, d: false},\n    {count: 2261, l: true},\n    {count: 2265, l: false},\n    {count: 2270, l: true},\n    {count: 2273, l: false},\n    {count: 2279, l: true},\n    {count: 2283, l: false},\n    {count: 2286, l: true},\n    {count: 2315, l: false},\n    {count: 2317, u: true},\n    {count: 2322, u: false},\n    {count: 2345, u: true},\n    {count: 2348, u: false},\n    {count: 2353, u: true},\n    {count: 2355, u: false},\n    {count: 2359, u: true},\n    {count: 2363, u: false},\n    {count: 2367, l: true},\n    {count: 2371, l: false},\n    {count: 2375, l: true},\n    {count: 2379, l: false},\n    {count: 2406, d: true},\n    {count: 2413, d: false},\n    {count: 2440, l: true},\n    {count: 2442, l: false},\n    {count: 2447, l: true},\n    {count: 2473, l: false},\n    {count: 2475, u: true},\n    {count: 2477, s: false},\n    {count: 2503, u: false},\n    {count: 2504, s: true},\n    {count: 2513, d: true},\n    {count: 2542, l: true},\n    {count: 2543, d: false},\n    {count: 2548, d: true},\n    {count: 2549, l: false},\n    {count: 2557, r: true},\n    {count: 2559, d: false},\n    {count: 2563, r: false},\n    {count: 2576, r: true},\n    {count: 2580, r: false},\n    {count: 2584, r: true},\n    {count: 2588, r: false},\n    {count: 2601, r: true},\n    {count: 2606, r: false},\n    {count: 2610, r: true},\n    {count: 2613, r: false},\n    {count: 2624, u: true},\n    {count: 2624, s: false},\n    {count: 2647, u: false},\n    {count: 2647, r: true},\n    {count: 2659, s: true},\n    {count: 2665, d: true},\n    {count: 2666, r: false},\n    {count: 2679, d: false},\n    {count: 2706, d: true},\n    {count: 2712, d: false},\n    {count: 2716, r: true},\n    {count: 2744, r: false},\n    {count: 2753, d: true},\n    {count: 2758, d: false},\n    {count: 2765, r: true},\n    {count: 2770, r: false},\n    {count: 2772, d: true},\n    {count: 2784, d: false},\n    {count: 2818, l: true},\n    {count: 2821, l: false},\n    {count: 2840, r: true},\n    {count: 2843, r: false},\n    {count: 2880, l: true},\n    {count: 2915, l: false},\n    {count: 2919, u: true},\n    {count: 2960, u: false},\n    {count: 2968, d: true},\n    {count: 2993, d: false},\n    {count: 3007, l: true},\n    {count: 3024, l: false},\n    {count: 3062, l: true},\n    {count: 3066, l: false},\n    {count: 3074, l: true},\n    {count: 3078, l: false},\n    {count: 3082, l: true},\n    {count: 3099, l: false},\n    {count: 3105, s: false},\n    {count: 3108, r: true},\n    {count: 3149, r: false},\n    {count: 3150, l: true},\n    {count: 3205, r: true},\n    {count: 3206, l: false},\n    {count: 3235, d: true},\n    {count: 3238, r: false},\n    {count: 3249, l: true},\n    {count: 3250, d: false},\n    {count: 3279, u: true},\n    {count: 3280, l: false},\n    {count: 3308, r: true},\n    {count: 3308, u: false},\n    {count: 3327, d: true},\n    {count: 3331, r: false},\n    {count: 3341, l: true},\n    {count: 3342, d: false},\n    {count: 3366, r: true},\n    {count: 3368, l: false},\n    {count: 3378, d: true},\n    {count: 3390, d: false},\n    {count: 3399, r: false},\n    {count: 3412, l: true},\n    {count: 3416, l: false},\n    {count: 3457, l: true},\n    {count: 3475, l: false},\n    {count: 3478, u: true},\n    {count: 3485, u: false},\n    {count: 3492, l: true},\n    {count: 3497, l: false},\n    {count: 3505, u: true},\n    {count: 3511, u: false},\n    {count: 3525, d: true},\n    {count: 3534, d: false},\n    {count: 3539, r: true},\n    {count: 3548, r: false},\n    {count: 3595, r: true},\n    {count: 3607, d: true},\n    {count: 3608, r: false},\n    {count: 3614, d: false},\n    {count: 3629, r: true},\n    {count: 3634, r: false},\n    {count: 3641, l: true},\n    {count: 3653, l: false},\n    {count: 3659, r: true},\n    {count: 3667, r: false},\n    {count: 3670, u: true},\n    {count: 3686, u: false},\n    {count: 3696, d: true},\n    {count: 3703, d: false},\n    {count: 3718, l: true},\n    {count: 3743, l: false},\n    {count: 3745, r: true},\n    {count: 3753, r: false},\n    {count: 3762, r: true},\n    {count: 3766, r: false},\n    {count: 3793, r: true},\n    {count: 3804, r: false},\n    {count: 3810, d: true},\n    {count: 3816, d: false},\n    {count: 3842, r: true},\n    {count: 3848, r: false},\n    {count: 3861, u: true},\n    {count: 3879, u: false},\n    {count: 3891, d: true},\n    {count: 3903, d: false},\n    {count: 3920, l: true},\n    {count: 3924, l: false},\n    {count: 3961, u: true},\n    {count: 3970, u: false},\n    {count: 3973, l: true},\n    {count: 3979, l: false},\n    {count: 3991, r: true},\n    {count: 3998, r: false},\n    {count: 4002, r: true},\n    {count: 4012, r: false},\n    {count: 4037, u: true},\n    {count: 4050, u: false},\n    {count: 4050, r: true},\n    {count: 4069, d: true},\n    {count: 4091, l: true},\n    {count: 4092, r: false},\n    {count: 4092, d: false},\n    {count: 4122, z: false},\n    {count: 4128, l: false},\n    {count: 4147, r: true},\n    {count: 4163, r: false},\n    {count: 4213, z: true},\n    {count: 4236, z: true},\n    {count: 4250, z: true},\n    {count: 4270, z: true},\n    {count: 4282, l: true},\n    {count: 4292, s: true},\n    {count: 4295, l: false},\n    {count: 4302, r: true},\n    {count: 4310, r: false},\n    {count: 4321, d: true},\n    {count: 4328, d: false},\n    {count: 4330, r: true},\n    {count: 4335, r: false},\n    {count: 4357, r: true},\n    {count: 4361, r: false},\n    {count: 4381, l: true},\n    {count: 4387, l: false},\n    {count: 4392, l: true},\n    {count: 4394, l: false},\n    {count: 4414, r: true},\n    {count: 4419, r: false},\n    {count: 4442, d: true},\n    {count: 4448, d: false},\n    {count: 4458, u: true},\n    {count: 4463, u: false},\n    {count: 4495, l: true},\n    {count: 4499, l: false},\n    {count: 4514, l: true},\n    {count: 4516, l: false},\n    {count: 4529, u: true},\n    {count: 4532, u: false},\n    {count: 4540, l: true},\n    {count: 4544, l: false},\n    {count: 4596, l: true},\n    {count: 4597, l: false},\n    {count: 4623, l: true},\n    {count: 4626, l: false},\n    {count: 4694, r: true},\n    {count: 4697, r: false},\n    {count: 4702, r: true},\n    {count: 4705, r: false},\n    {count: 4710, r: true},\n    {count: 4713, r: false},\n    {count: 4715, r: true},\n    {count: 4719, r: false},\n    {count: 4739, l: true},\n    {count: 4741, l: false},\n    {count: 4747, l: true},\n    {count: 4752, l: false},\n    {count: 4774, r: true},\n    {count: 4778, r: false},\n    {count: 4795, r: true},\n    {count: 4798, r: false},\n    {count: 4831, d: true},\n    {count: 4836, d: false},\n    {count: 4847, r: true},\n    {count: 4849, r: false},\n    {count: 4874, l: true},\n    {count: 4878, l: false},\n    {count: 4909, l: true},\n    {count: 4913, l: false},\n    {count: 4925, u: true},\n    {count: 4928, u: false},\n    {count: 4932, u: true},\n    {count: 4936, u: false},\n    {count: 4941, u: true},\n    {count: 4945, u: false},\n    {count: 4961, l: true},\n    {count: 4963, l: false},\n    {count: 5000, d: true},\n    {count: 5002, d: false},\n    {count: 5013, l: true},\n    {count: 5016, l: false},\n    {count: 5032, r: true},\n    {count: 5034, r: false},\n    {count: 5051, l: true},\n    {count: 5055, l: false},\n    {count: 5075, r: true},\n    {count: 5077, r: false},\n    {count: 5094, l: true},\n    {count: 5097, l: false},\n    {count: 5137, l: true},\n    {count: 5147, l: false},\n    {count: 5157, r: true},\n    {count: 5171, r: false},\n    {count: 5179, l: true},\n    {count: 5185, l: false},\n    {count: 5205, r: true},\n    {count: 5208, r: false},\n    {count: 5239, l: true},\n    {count: 5245, l: false},\n    {count: 5264, r: true},\n    {count: 5266, r: false},\n    {count: 5295, l: true},\n    {count: 5299, l: false},\n    {count: 5314, r: true},\n    {count: 5318, r: false},\n    {count: 5346, l: true},\n    {count: 5350, l: false},\n    {count: 5361, r: true},\n    {count: 5369, r: false},\n    {count: 5383, l: true},\n    {count: 5390, l: false},\n    {count: 5413, r: true},\n    {count: 5421, d: true},\n    {count: 5421, r: false},\n    {count: 5430, d: false},\n    {count: 5481, r: true},\n    {count: 5488, r: false},\n    {count: 5511, l: true},\n    {count: 5516, l: false},\n    {count: 5528, r: true},\n    {count: 5536, r: false},\n    {count: 5548, l: true},\n    {count: 5556, l: false},\n    {count: 5578, l: true},\n    {count: 5587, l: false},\n    {count: 5608, l: true},\n    {count: 5614, l: false},\n    {count: 5628, r: true},\n    {count: 5632, r: false},\n    {count: 5638, r: true},\n    {count: 5643, r: false},\n    {count: 5651, l: true},\n    {count: 5657, l: false},\n    {count: 5663, l: true},\n    {count: 5665, l: false},\n    {count: 5669, u: true},\n    {count: 5675, u: false},\n    {count: 5691, d: true},\n    {count: 5696, d: false},\n    {count: 5706, r: true},\n    {count: 5710, r: false},\n    {count: 5740, l: true},\n    {count: 5749, l: false},\n    {count: 5760, r: true},\n    {count: 5767, r: false},\n    {count: 5794, l: true},\n    {count: 5803, l: false},\n    {count: 5818, r: true},\n    {count: 5828, r: false},\n    {count: 5846, l: true},\n    {count: 5852, l: false},\n    {count: 5874, r: true},\n    {count: 5882, r: false},\n    {count: 5894, l: true},\n    {count: 5905, l: false},\n    {count: 5961, r: true},\n    {count: 5966, r: false},\n    {count: 5981, l: true},\n    {count: 5991, l: false},\n    {count: 6003, r: true},\n    {count: 6010, r: false},\n    {count: 6029, l: true},\n    {count: 6036, l: false},\n    {count: 6051, r: true},\n    {count: 6057, r: false},\n    {count: 6080, l: true},\n    {count: 6086, l: false},\n    {count: 6102, r: true},\n    {count: 6108, r: false},\n    {count: 6127, r: true},\n    {count: 6135, r: false},\n    {count: 6165, u: true},\n    {count: 6169, u: false},\n    {count: 6173, r: true},\n    {count: 6182, r: false},\n    {count: 6203, d: true},\n    {count: 6207, d: false},\n    {count: 6214, r: true},\n    {count: 6219, r: false},\n    {count: 6242, l: true},\n    {count: 6242, s: false},\n    {count: 6247, u: true},\n    {count: 6247, l: false},\n    {count: 6280, s: true},\n    {count: 6281, u: false},\n    {count: 6289, d: true},\n    {count: 6295, d: false},\n    {count: 6316, d: true},\n    {count: 6320, d: false},\n    {count: 6326, d: true},\n    {count: 6330, d: false},\n    {count: 6334, d: true},\n    {count: 6339, d: false},\n    {count: 6395, d: true},\n    {count: 6400, d: false},\n    {count: 6461, l: true},\n    {count: 6464, l: false},\n    {count: 6481, l: true},\n    {count: 6484, l: false},\n    {count: 6493, r: true},\n    {count: 6496, r: false},\n    {count: 6500, d: true},\n    {count: 6503, d: false},\n    {count: 6588, d: true},\n    {count: 6593, d: false},\n    {count: 6599, l: true},\n    {count: 6602, l: false},\n    {count: 6645, l: true},\n    {count: 6649, l: false},\n    {count: 6663, r: true},\n    {count: 6667, r: false},\n    {count: 6725, r: true},\n    {count: 6729, r: false},\n    {count: 6738, r: true},\n    {count: 6741, r: false},\n    {count: 6754, r: true},\n    {count: 6759, r: false},\n    {count: 6770, l: true},\n    {count: 6785, l: false},\n    {count: 6810, l: true},\n    {count: 6812, l: false},\n    {count: 6819, r: true},\n    {count: 6826, r: false},\n    {count: 6838, u: true},\n    {count: 6841, u: false},\n    {count: 6844, r: true},\n    {count: 6849, r: false},\n    {count: 6865, d: true},\n    {count: 6870, d: false},\n    {count: 6874, r: true},\n    {count: 6878, r: false},\n    {count: 6894, r: true},\n    {count: 6897, r: false},\n    {count: 6918, u: true},\n    {count: 6924, u: false},\n    {count: 6926, l: true},\n    {count: 6932, l: false},\n    {count: 6992, l: true},\n    {count: 6997, l: false},\n    {count: 7058, r: true},\n    {count: 7064, r: false},\n    {count: 7067, r: true},\n    {count: 7070, r: false},\n    {count: 7090, l: true},\n    {count: 7095, l: false},\n    {count: 7123, l: true},\n    {count: 7127, l: false},\n    {count: 7157, r: true},\n    {count: 7161, r: false},\n    {count: 7180, l: true},\n    {count: 7190, l: false},\n    {count: 7218, d: true},\n    {count: 7220, d: false},\n    {count: 7240, l: true},\n    {count: 7243, l: false},\n    {count: 7283, u: true},\n    {count: 7289, u: false},\n    {count: 7295, r: true},\n    {count: 7303, d: true},\n    {count: 7305, r: false},\n    {count: 7311, d: false},\n    {count: 7314, r: true},\n    {count: 7321, r: false},\n    {count: 7345, r: true},\n    {count: 7348, r: false},\n    {count: 7363, u: true},\n    {count: 7370, u: false},\n    {count: 7371, l: true},\n    {count: 7379, l: false},\n    {count: 7424, d: true},\n    {count: 7427, d: false},\n    {count: 7431, l: true},\n    {count: 7435, l: false},\n    {count: 7471, l: true},\n    {count: 7474, l: false},\n    {count: 7477, l: true},\n    {count: 7482, l: false},\n    {count: 7501, r: true},\n    {count: 7510, s: false},\n    {count: 7511, r: false},\n    {count: 7512, z: false},\n    {count: 7513, u: true},\n    {count: 7531, u: false},\n    {count: 7566, r: true},\n    {count: 7583, r: false},\n    {count: 7635, z: true},\n    {count: 7698, z: true},\n    {count: 7716, z: true},\n    {count: 7720, d: true},\n    {count: 7734, d: false},\n    {count: 7734, l: true},\n    {count: 7789, r: true},\n    {count: 7790, l: false},\n    {count: 7835, l: true},\n    {count: 7835, r: false},\n    {count: 7880, r: true},\n    {count: 7881, l: false},\n    {count: 7910, r: false},\n    {count: 7915, l: true},\n    {count: 7923, l: false},\n    {count: 7939, l: true},\n    {count: 7950, l: false},\n    {count: 7953, r: true},\n    {count: 7961, d: true},\n    {count: 7964, r: false},\n    {count: 7968, l: true},\n    {count: 7969, d: false},\n    {count: 7985, l: false},\n    {count: 7990, d: true},\n    {count: 7996, d: false},\n    {count: 8005, r: true},\n    {count: 8022, r: false},\n    {count: 8041, u: true},\n    {count: 8051, u: false},\n    {count: 8056, x: true},\n    {count: 8070, u: true},\n    {count: 8088, u: false},\n    {count: 8089, r: true},\n    {count: 8095, d: true},\n    {count: 8097, r: false},\n    {count: 8110, l: true},\n    {count: 8110, d: false},\n    {count: 8132, l: false},\n    {count: 8135, r: true},\n    {count: 8182, l: true},\n    {count: 8182, r: false},\n    {count: 8238, r: true},\n    {count: 8239, l: false},\n    {count: 8280, r: false},\n    {count: 8281, l: true},\n    {count: 8303, l: false},\n    {count: 8309, r: true},\n    {count: 8322, r: false},\n    {count: 8328, x: true},\n    {count: 8337, u: true},\n    {count: 8362, u: false},\n    {count: 8413, d: true},\n    {count: 8441, d: false},\n    {count: 8441, l: true},\n    {count: 8471, r: true},\n    {count: 8471, l: false},\n    {count: 8528, r: false},\n    {count: 8536, u: true},\n    {count: 8596, l: true},\n    {count: 8597, u: false},\n    {count: 8609, d: true},\n    {count: 8610, l: false},\n    {count: 8660, s: true},\n    {count: 8672, l: true},\n    {count: 8672, d: false},\n    {count: 8727, u: true},\n    {count: 8728, l: false},\n    {count: 8749, r: true},\n    {count: 8750, u: false},\n    {count: 8759, d: true},\n    {count: 8766, r: false},\n    {count: 8768, r: true},\n    {count: 8781, d: false},\n    {count: 8783, r: false},\n    {count: 8785, d: true},\n    {count: 8791, d: false},\n    {count: 8795, l: true},\n    {count: 8826, u: true},\n    {count: 8827, l: false},\n    {count: 8858, r: true},\n    {count: 8859, u: false},\n    {count: 8876, d: true},\n    {count: 8877, r: false},\n    {count: 8885, d: false},\n    {count: 8893, d: true},\n    {count: 8902, d: false},\n    {count: 8907, l: true},\n    {count: 8916, l: false},\n    {count: 8929, u: true},\n    {count: 8935, u: false},\n    {count: 8943, d: true},\n    {count: 8955, l: true},\n    {count: 8955, d: false},\n    {count: 8972, l: false},\n    {count: 8985, d: true},\n    {count: 8991, r: true},\n    {count: 8992, d: false},\n    {count: 9023, r: false},\n    {count: 9054, r: true},\n    {count: 9062, d: true},\n    {count: 9063, r: false},\n    {count: 9070, d: false},\n    {count: 9085, r: true},\n    {count: 9091, r: false},\n    {count: 9098, u: true},\n    {count: 9133, u: false},\n    {count: 9135, l: true},\n    {count: 9161, l: false},\n    {count: 9166, d: true},\n    {count: 9174, l: true},\n    {count: 9175, d: false},\n    {count: 9191, l: false},\n    {count: 9195, u: true},\n    {count: 9248, u: false},\n    {count: 9251, r: true},\n    {count: 9251, s: false},\n    {count: 9258, r: false},\n    {count: 9271, r: true},\n    {count: 9278, d: true},\n    {count: 9283, r: false},\n    {count: 9326, r: true},\n    {count: 9331, d: false},\n    {count: 9337, r: false},\n    {count: 9354, u: true},\n    {count: 9371, u: false},\n    {count: 9380, u: true},\n    {count: 9416, u: false},\n    {count: 9421, d: true},\n    {count: 9475, l: true},\n    {count: 9476, d: false},\n    {count: 9490, r: true},\n    {count: 9491, l: false},\n    {count: 9526, l: true},\n    {count: 9527, r: false},\n    {count: 9557, u: true},\n    {count: 9558, l: false},\n    {count: 9573, u: false},\n    {count: 9575, l: true},\n    {count: 9584, l: false},\n    {count: 9587, r: true},\n    {count: 9615, r: false},\n    {count: 9639, r: true},\n    {count: 9647, d: true},\n    {count: 9650, s: true},\n    {count: 9675, d: false},\n    {count: 9679, l: true},\n    {count: 9679, r: false},\n    {count: 9686, s: false},\n    {count: 9718, r: true},\n    {count: 9718, l: false},\n    {count: 9757, u: true},\n    {count: 9759, r: false},\n    {count: 9779, l: true},\n    {count: 9781, u: false},\n    {count: 9802, l: false},\n    {count: 9816, l: true},\n    {count: 9819, l: false},\n    {count: 9824, l: true},\n    {count: 9828, l: false},\n    {count: 9838, s: true},\n    {count: 9851, l: true},\n    {count: 9856, l: false},\n    {count: 9861, d: true},\n    {count: 9866, d: false},\n    {count: 9875, r: true},\n    {count: 9880, r: false},\n    {count: 9883, d: true},\n    {count: 9888, d: false},\n    {count: 9897, l: true},\n    {count: 9901, l: false},\n    {count: 9910, d: true},\n    {count: 9913, d: false},\n    {count: 9937, d: true},\n    {count: 9940, d: false},\n    {count: 9983, r: true},\n    {count: 9986, r: false},\n    {count: 9997, d: true},\n    {count: 9999, d: false},\n    {count: 10004, d: true},\n    {count: 10009, d: false},\n    {count: 10031, d: true},\n    {count: 10035, d: false},\n    {count: 10039, d: true},\n    {count: 10041, d: false},\n    {count: 10048, r: true},\n    {count: 10051, r: false},\n    {count: 10066, u: true},\n    {count: 10069, u: false},\n    {count: 10073, u: true},\n    {count: 10075, u: false},\n    {count: 10081, u: true},\n    {count: 10084, u: false},\n    {count: 10089, u: true},\n    {count: 10104, l: true},\n    {count: 10105, u: false},\n    {count: 10144, d: true},\n    {count: 10145, l: false},\n    {count: 10157, d: false},\n    {count: 10159, l: true},\n    {count: 10165, l: false},\n    {count: 10210, u: true},\n    {count: 10226, u: false},\n    {count: 10229, r: true},\n    {count: 10230, s: false},\n    {count: 10238, r: false},\n    {count: 10246, r: true},\n    {count: 10268, r: false},\n    {count: 10276, s: true},\n    {count: 10282, d: true},\n    {count: 10286, d: false},\n    {count: 10288, r: true},\n    {count: 10293, r: false},\n    {count: 10296, d: true},\n    {count: 10299, r: true},\n    {count: 10300, d: false},\n    {count: 10303, r: false},\n    {count: 10316, d: true},\n    {count: 10320, d: false},\n    {count: 10324, d: true},\n    {count: 10327, d: false},\n    {count: 10335, l: true},\n    {count: 10338, l: false},\n    {count: 10341, l: true},\n    {count: 10343, l: false},\n    {count: 10357, u: true},\n    {count: 10376, u: false},\n    {count: 10412, s: false},\n    {count: 10423, l: true},\n    {count: 10428, l: false},\n    {count: 10428, s: true},\n    {count: 10432, d: true},\n    {count: 10438, d: false},\n    {count: 10453, l: true},\n    {count: 10455, l: false},\n    {count: 10458, d: true},\n    {count: 10467, d: false},\n    {count: 10469, r: true},\n    {count: 10473, r: false},\n    {count: 10491, u: true},\n    {count: 10493, u: false},\n    {count: 10496, u: true},\n    {count: 10499, u: false},\n    {count: 10501, u: true},\n    {count: 10505, u: false},\n    {count: 10508, u: true},\n    {count: 10511, u: false},\n    {count: 10515, u: true},\n    {count: 10518, u: false},\n    {count: 10521, u: true},\n    {count: 10525, u: false},\n    {count: 10551, d: true},\n    {count: 10565, d: false},\n    {count: 10569, l: true},\n    {count: 10588, d: true},\n    {count: 10588, l: false},\n    {count: 10597, d: false},\n    {count: 10607, d: true},\n    {count: 10611, d: false},\n    {count: 10625, r: true},\n    {count: 10627, r: false},\n    {count: 10643, r: true},\n    {count: 10645, r: false},\n    {count: 10663, l: true},\n    {count: 10666, l: false},\n    {count: 10683, u: true},\n    {count: 10695, u: false},\n    {count: 10701, s: false},\n    {count: 10701, r: true},\n    {count: 10725, d: true},\n    {count: 10728, s: true},\n    {count: 10728, r: false},\n    {count: 10741, d: false},\n    {count: 10742, l: true},\n    {count: 10754, l: false},\n    {count: 10766, r: true},\n    {count: 10770, r: false},\n    {count: 10774, r: true},\n    {count: 10777, r: false},\n    {count: 10780, r: true},\n    {count: 10782, r: false},\n    {count: 10799, r: true},\n    {count: 10802, r: false},\n    {count: 10810, u: true},\n    {count: 10829, u: false},\n    {count: 10861, l: true},\n    {count: 10885, l: false},\n    {count: 10916, d: true},\n    {count: 10920, d: false},\n    {count: 10942, r: true},\n    {count: 10945, r: false},\n    {count: 10948, r: true},\n    {count: 10951, r: false},\n    {count: 11007, s: false},\n    {count: 11035, d: true},\n    {count: 11046, d: false},\n    {count: 11047, l: true},\n    {count: 11093, l: false},\n    {count: 11093, r: true},\n    {count: 11144, l: true},\n    {count: 11145, r: false},\n    {count: 11190, u: true},\n    {count: 11191, l: false},\n    {count: 11211, u: false},\n    {count: 11251, r: true},\n    {count: 11263, r: false},\n    {count: 11285, u: true},\n    {count: 11291, u: false},\n    {count: 11293, r: true},\n    {count: 11299, r: false},\n    {count: 11318, d: true},\n    {count: 11326, d: false},\n    {count: 11334, l: true},\n    {count: 11345, l: false},\n    {count: 11350, d: true},\n    {count: 11357, d: false},\n    {count: 11359, l: true},\n    {count: 11364, l: false},\n    {count: 11388, d: true},\n    {count: 11393, d: false},\n    {count: 11397, d: true},\n    {count: 11401, d: false},\n    {count: 11415, d: true},\n    {count: 11420, d: false},\n    {count: 11451, r: true},\n    {count: 11464, r: false},\n    {count: 11480, d: true},\n    {count: 11485, r: true},\n    {count: 11486, d: false},\n    {count: 11491, r: false},\n    {count: 11521, r: true},\n    {count: 11526, r: false},\n    {count: 11547, l: true},\n    {count: 11552, l: false},\n    {count: 11560, r: true},\n    {count: 11565, r: false},\n    {count: 11568, u: true},\n    {count: 11583, u: false},\n    {count: 11598, d: true},\n    {count: 11604, d: false},\n    {count: 11613, l: true},\n    {count: 11633, l: false},\n    {count: 11634, d: true},\n    {count: 11640, d: false},\n    {count: 11644, l: true},\n    {count: 11651, l: false},\n    {count: 11659, r: true},\n    {count: 11672, r: false},\n    {count: 11694, r: true},\n    {count: 11702, r: false},\n    {count: 11719, d: true},\n    {count: 11724, d: false},\n    {count: 11735, r: true},\n    {count: 11741, r: false},\n    {count: 11745, r: true},\n    {count: 11747, r: false},\n    {count: 11755, u: true},\n    {count: 11775, u: false},\n    {count: 11792, d: true},\n    {count: 11797, d: false},\n    {count: 11815, l: true},\n    {count: 11828, l: false},\n    {count: 11829, l: true},\n    {count: 11837, d: true},\n    {count: 11837, l: false},\n    {count: 11845, l: true},\n    {count: 11846, d: false},\n    {count: 11858, l: false},\n    {count: 11862, r: true},\n    {count: 11886, r: false},\n    {count: 11901, r: true},\n    {count: 11916, r: false},\n    {count: 11931, u: true},\n    {count: 11954, u: false},\n    {count: 11955, r: true},\n    {count: 11978, d: true},\n    {count: 11982, r: false},\n    {count: 11995, l: true},\n    {count: 11996, d: false},\n    {count: 12016, l: false},\n    {count: 12017, z: false},\n    {count: 12021, r: true},\n    {count: 12039, r: false},\n    {count: 12042, u: true},\n    {count: 12059, u: false},\n    {count: 12122, z: true},\n    {count: 12143, z: true},\n    {count: 12166, z: true},\n    {count: 12173, l: true},\n    {count: 12182, s: true},\n    {count: 12188, l: false},\n    {count: 12190, d: true},\n    {count: 12197, d: false},\n    {count: 12202, l: true},\n    {count: 12203, l: false},\n    {count: 12244, d: true},\n    {count: 12246, d: false},\n    {count: 12251, d: true},\n    {count: 12253, d: false},\n    {count: 12260, l: true},\n    {count: 12263, l: false},\n    {count: 12273, d: true},\n    {count: 12277, d: false},\n    {count: 12279, r: true},\n    {count: 12281, r: false},\n    {count: 13182, s: false},\n    {count: 13190, r: true},\n    {count: 13203, r: false},\n    {count: 13207, l: true},\n    {count: 13233, s: true},\n    {count: 13237, l: false},\n    {count: 13239, r: true},\n    {count: 13262, l: true},\n    {count: 13262, r: false},\n    {count: 13278, r: true},\n    {count: 13279, l: false},\n    {count: 13301, r: false},\n    {count: 13312, l: true},\n    {count: 13320, l: false},\n    {count: 13325, d: true},\n    {count: 13344, d: false},\n    {count: 13360, l: true},\n    {count: 13381, u: true},\n    {count: 13382, l: false},\n    {count: 13386, s: false},\n    {count: 13398, s: true},\n    {count: 13399, u: false},\n    {count: 13412, r: true},\n    {count: 13419, d: true},\n    {count: 13423, r: false},\n    {count: 13424, d: false},\n    {count: 13429, d: true},\n    {count: 13434, d: false},\n    {count: 13436, l: true},\n    {count: 13443, l: false},\n    {count: 13447, l: true},\n    {count: 13458, l: false},\n    {count: 13458, u: true},\n    {count: 13463, u: false},\n    {count: 13464, r: true},\n    {count: 13471, r: false},\n    {count: 13488, r: true},\n    {count: 13492, r: false},\n    {count: 13494, r: true},\n    {count: 13498, r: false},\n    {count: 13514, d: true},\n    {count: 13523, r: true},\n    {count: 13528, d: false},\n    {count: 13533, r: false},\n    {count: 13540, r: true},\n    {count: 13542, d: true},\n    {count: 13545, r: false},\n    {count: 13551, r: true},\n    {count: 13552, d: false},\n    {count: 13557, r: false},\n    {count: 13653, l: true},\n    {count: 13658, l: false},\n    {count: 13689, r: true},\n    {count: 13692, r: false},\n    {count: 13897, r: true},\n    {count: 13900, u: true},\n    {count: 13903, r: false},\n    {count: 13911, u: false},\n    {count: 13915, l: true},\n    {count: 13925, l: false},\n    {count: 13939, r: true},\n    {count: 13945, r: false},\n    {count: 13958, l: true},\n    {count: 13967, l: false},\n    {count: 14015, r: true},\n    {count: 14019, r: false},\n    {count: 14299, d: true},\n    {count: 14311, l: true},\n    {count: 14312, d: false},\n    {count: 14319, l: false},\n    {count: 14341, r: true},\n    {count: 14346, r: false},\n    {count: 14353, u: true},\n    {count: 14360, u: false},\n    {count: 14383, r: true},\n    {count: 14400, r: false},\n    {count: 14434, l: true},\n    {count: 14438, l: false},\n    {count: 14483, l: true},\n    {count: 14487, l: false},\n    {count: 14685, d: true},\n    {count: 14691, d: false},\n    {count: 14706, s: false},\n    {count: 14710, l: true},\n    {count: 14717, l: false},\n    {count: 14717, u: true},\n    {count: 14717, z: false},\n    {count: 14768, z: true},\n    {count: 14777, s: true},\n    {count: 14780, u: false},\n    {count: 14796, d: true},\n    {count: 14856, d: false},\n    {count: 14879, u: true},\n    {count: 14885, u: false},\n    {count: 14902, l: true},\n    {count: 14908, l: false},\n    {count: 14910, u: true},\n    {count: 14921, u: false},\n    {count: 14945, l: true},\n    {count: 14955, l: false},\n    {count: 14968, r: true},\n    {count: 14975, r: false},\n    {count: 14983, r: true},\n    {count: 14987, r: false},\n    {count: 14998, d: true},\n    {count: 15014, l: true},\n    {count: 15014, d: false},\n    {count: 15019, l: false},\n    {count: 15030, u: true},\n    {count: 15041, u: false},\n    {count: 15045, r: true},\n    {count: 15048, r: false},\n    {count: 15072, d: true},\n    {count: 15076, d: false},\n    {count: 15128, r: true},\n    {count: 15137, r: false},\n    {count: 15143, r: true},\n    {count: 15151, r: false},\n    {count: 15153, u: true},\n    {count: 15158, l: true},\n    {count: 15158, u: false},\n    {count: 15164, l: false},\n    {count: 15180, l: true},\n    {count: 15183, l: false},\n    {count: 15185, l: true},\n    {count: 15202, l: false},\n    {count: 15204, r: true},\n    {count: 15209, d: true},\n    {count: 15211, x: true},\n    {count: 15215, r: false},\n    {count: 15215, d: false},\n    {count: 15219, u: true},\n    {count: 15228, r: true},\n    {count: 15228, u: false},\n    {count: 15232, r: false},\n    {count: 15233, u: true},\n    {count: 15261, u: false},\n    {count: 15265, d: true},\n    {count: 15294, d: false},\n    {count: 15350, d: true},\n    {count: 15356, d: false},\n    {count: 15363, l: true},\n    {count: 15370, l: false},\n    {count: 15389, r: true},\n    {count: 15392, r: false},\n    {count: 15483, l: true},\n    {count: 15500, l: false},\n    {count: 15519, r: true},\n    {count: 15525, r: false},\n    {count: 15533, r: true},\n    {count: 15536, r: false},\n    {count: 15554, l: true},\n    {count: 15563, l: false},\n    {count: 15572, r: true},\n    {count: 15575, r: false},\n    {count: 15597, r: true},\n    {count: 15602, r: false},\n    {count: 15627, r: true},\n    {count: 15629, r: false},\n    {count: 15643, d: true},\n    {count: 15654, d: false},\n    {count: 15666, r: true},\n    {count: 15676, r: false},\n    {count: 15692, r: true},\n    {count: 15697, r: false},\n    {count: 15707, u: true},\n    {count: 15712, l: true},\n    {count: 15713, u: false},\n    {count: 15719, l: false},\n    {count: 15731, l: true},\n    {count: 15734, l: false},\n    {count: 15750, u: true},\n    {count: 15756, u: false},\n    {count: 15766, r: true},\n    {count: 15771, r: false},\n    {count: 15776, r: true},\n    {count: 15785, u: true},\n    {count: 15786, r: false},\n    {count: 15791, l: true},\n    {count: 15791, u: false},\n    {count: 15802, l: false},\n    {count: 15844, l: true},\n    {count: 15848, l: false},\n    {count: 15861, u: true},\n    {count: 15870, u: false},\n    {count: 15875, r: true},\n    {count: 15892, r: false},\n    {count: 15910, l: true},\n    {count: 15918, l: false},\n    {count: 15918, d: true},\n    {count: 15933, l: true},\n    {count: 15933, x: true},\n    {count: 15934, d: false},\n    {count: 15937, l: false},\n    {count: 15945, u: true},\n    {count: 15973, u: false},\n    {count: 15997, d: true},\n    {count: 16007, d: false},\n    {count: 16020, r: true},\n    {count: 16025, d: true},\n    {count: 16034, d: false},\n    {count: 16038, z: false},\n    {count: 16039, s: false},\n    {count: 16059, r: false},\n    {count: 16063, u: true},\n    {count: 16071, l: true},\n    {count: 16072, u: false},\n    {count: 16082, l: false},\n    {count: 16132, z: true},\n    {count: 16178, z: true},\n  ]\n}"
  },
  {
    "path": "replay/replay_list.txt",
    "content": "[\n  { id: 1, user: 'takahirox', characterIndex: 0, datetime: 1381201800000 },\n  { id: 2, user: 'takahirox', characterIndex: 1, datetime: 1381201932580 },\n]"
  },
  {
    "path": "source/Background.js",
    "content": "function BackgroundManager(gameState) {\n  this.parent = ElementManager;\n  this.parent.call(this, gameState);\n  this.activeIndex = 0;\n  this.drawers = [];\n  this.effectTextures = [];\n  this._init();\n};\n__inherit(BackgroundManager, ElementManager);\n\nBackgroundManager.prototype._MAX_NUM = 5;\n\n\nBackgroundManager.prototype._initMaxNum = function() {\n  return this._MAX_NUM;\n};\n\n\n/**\n * Unnecessary to have factory.\n */\nBackgroundManager.prototype._initFactory = function() {\n};\n\n\nBackgroundManager.prototype._init = function() {\n  this.elements.length = 0;\n  this.add(new Background(this.gameState,\n                          this.gameState.maxX,\n                          this.gameState.maxY));\n  this.add(new Background(this.gameState,\n                          this.gameState.maxX,\n                          this.gameState.maxY));\n};\n\n\nBackgroundManager.prototype.initDrawer = function(layer, image) {\n  this.drawers.length = 0;\n  this.drawers.push(new BackgroundDrawer(\n                          this.get(0), layer,\n                          this.gameState.getImage(Game._IMG_BG1)));\n  this.drawers.push(new BackgroundDrawer(\n                          this.get(1), layer,\n                          this.gameState.getImage(Game._IMG_BG2)));\n\n  this.effectTextures.length = 0;\n  this._initForwardBlackEffect(layer);\n};\n\n\n/**\n * TODO: is there a way to generate non-premultiplied image?\n */\nBackgroundManager.prototype._initForwardBlackEffect = function(layer) {\n  var h = 3;\n  var loop = 40;\n\n  var width = layer.calculateSquareValue(this.gameState.getWidth());\n  var height = layer.calculateSquareValue(h*loop);\n\n  var canvas = document.createElement('canvas');\n  canvas.width = width;\n  canvas.height = height;\n  var surface = canvas.getContext('2d');\n\n  surface.fillStyle = 'rgb(0, 0, 0)';\n  for(var i = 0; i < loop; i++) {\n    surface.globalAlpha = 0.4 - i * 0.01;\n    surface.fillRect(0, i * h, width, h);\n  }\n\n  var texture = layer.generateTexture(canvas);\n  texture.width = width;\n  texture.height = height;\n\n  this.effectTextures.push(texture);\n};\n\n\nBackgroundManager.prototype.setDarkness = function(d) {\n  this.get(this.activeIndex).getView().setDarkness(d);\n};\n\n\nBackgroundManager.prototype.draw = function(layer, darken) {\n  var d = darken ? 0.4 : 1.0;\n\n  this.setDarkness(d);\n  this.drawers[this.activeIndex].draw(layer);\n\n  if(! darken)\n    this._drawEffect(layer);\n};\n\n\nBackgroundManager.prototype._drawEffect = function(layer) {\n  var texture = this.effectTextures[0];\n  layer.viewport();\n  layer.ortho(0.1, 10.0);\n  mat4.identity(layer.mvMatrix);\n  layer.drawOneTexture(texture,\n                       texture.width/2, texture.height/2, -1.0,\n                       texture.width,   texture.height, 1.0, 1.0);\n};\n\n\n/**\n * should not call parent reset() method to\n * keep elements available.\n */\nBackgroundManager.prototype.reset = function() {\n  this.activeIndex = 0;\n  for(var i = 0; i < this.getNum(); i++) {\n    this.get(i).reset();\n  }\n};\n\n\nBackgroundManager.prototype.goNextStage = function() {\n  this.activeIndex++;\n};\n\n\n\nfunction BackgroundView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(BackgroundView, ElementView);\n\n\nBackgroundView.prototype.setDarkness = function(d) {\n  this.d = d;\n};\n\n\nBackgroundView.prototype._initVertices = function() {\n  this.vertices[0]  = -2.0;\n  this.vertices[1]  =  2.0;\n  this.vertices[2]  =  0.0;\n\n  this.vertices[3]  =  2.0;\n  this.vertices[4]  =  2.0;\n  this.vertices[5]  =  0.0;\n\n  this.vertices[6]  =  2.0;\n  this.vertices[7]  = -8.0;\n  this.vertices[8]  =  0.0;\n\n  this.vertices[9]  = -2.0;\n  this.vertices[10] = -8.0;\n  this.vertices[11] =  0.0;\n};\n\n\nBackgroundView.prototype._initCoordinates = function() {\n  this.coordinates[0] =  0.0;\n  this.coordinates[1] = 10.0;\n\n  this.coordinates[2] =  4.0;\n  this.coordinates[3] = 10.0;\n\n  this.coordinates[4] =  4.0;\n  this.coordinates[5] =  0.0;\n\n  this.coordinates[6] =  0.0;\n  this.coordinates[7] =  0.0;\n};\n\n\n\nfunction BackgroundDrawer(elementManager, gl, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, gl, image);\n};\n__inherit(BackgroundDrawer, ElementDrawer);\n\n// only for reference\nBackgroundDrawer.prototype.Math = Math;\nBackgroundDrawer.prototype.mat4 = mat4;\n\n\n\nBackgroundDrawer.prototype._project = function(layer) {\n  layer.perspective(60, 0.1, 100.0);\n};\n\n\nBackgroundDrawer.prototype._prepareDraw = function(layer) {\n  this.mat4.rotate(layer.mvMatrix, this.Math.PI/180*50, [-1, 0, 0]);\n};\n\n/**\n * independent of fighter so far.\n * TODO: remove magic numbers.\n */\nBackgroundDrawer.prototype.lookAtFromViewpointTarget = function(layer) {\n  var eye = this._VIEWPOINTS_CONTAINERS[0];\n  var center = this._VIEWPOINTS_CONTAINERS[1];\n  var up = this._VIEWPOINTS_CONTAINERS[2];\n\n  eye[0] = 0;\n  eye[1] = -0.4;\n  eye[2] = 0.1;\n\n  center[0] = 0;\n  center[1] = 0;\n  center[2] = 0;\n\n  layer.lookAt(eye, center, up);\n};\n\n\nfunction Background(gameState, maxX, maxY) {\n  this.parent = Element;\n  this.parent.call(this, gameState, maxX, maxY);\n  this._initView();\n};\n__inherit(Background, Element);\n\n\n/**\n * Excepts not to call this method unlike other Element inherit class.\n * TODO: bad design.\n */\nBackground.prototype.init = function(params, image) {\n  this.image = image;\n//  Prolly unnecessary to call perent init()\n//  this.parent.prototype.init.call(this, params, image);\n};\n\n\nBackground.prototype.reset = function() {\n  this.count = 0;\n  this.x = 0;\n  this.y = 0;\n  this.z = 0;\n};\n\n\nBackground.prototype._generateView = function() {\n  return new BackgroundView(this);\n};\n\n\n// not implemented yet and no plan to implement.\nBackground.prototype.display = function(surface) {\n};\n\n\n// TODO: temporal\nBackground.prototype.Element_runStep = Element.prototype.runStep;\nBackground.prototype.runStep = function() {\n  this.Element_runStep();\n  // TODO: should be in BackgroundView?\n  this.y = (this.count%200)/200;\n  this.z = -this.gameState.bgScale;\n};\n\n"
  },
  {
    "path": "source/Bomb.js",
    "content": "function BombManager( gameState ) {\n  this.parent = ElementManager ;\n  this.parent.call( this, gameState ) ;\n}\n__inherit( BombManager, ElementManager ) ;\n\nBombManager.prototype._MAX_NUM = 40;\n\n\nBombManager.prototype._initMaxNum = function() {\n  return this._MAX_NUM;\n};\n\n\nBombManager.prototype._initFactory = function( ) {\n  this.factory = new BombFactory( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\nBombManager.prototype.initDrawer = function(layer, image) {\n  this.drawer = new BombDrawer(this, layer,\n                               this.gameState.getImage(Game._IMG_BOMB));\n};\n\n\n// TODO: temporal\nBombManager.prototype.create = function( fighter ) {\n  var bombs = this.factory.create( fighter ) ;\n  for( var i = 0; i < bombs.length; i++ )\n    this.addElement( bombs[ i ] ) ;\n} ;\n\n\n\nfunction BombFactory( gameState, maxX, maxY ) {\n  this.parent = ElementFactory ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n  this.params = [ ] ;\n  this._initBomb( ) ;\n  this.image = null; // TODO: temporal\n}\n__inherit( BombFactory, ElementFactory ) ;\n\nBombFactory.prototype._NUM = 20 ;\nBombFactory.prototype._BULLET_NUM = 10 ;\n\n\nBombFactory.prototype._initFreelist = function() {\n  this.freelist = new BombFreeList(this._NUM, this.gameState); \n};\n\n\nBombFactory.prototype._initBomb = function() {\n  var num = this._BULLET_NUM;\n  for(var i = 0; i < num; i++) {\n    this.params.push( {\n      'x': 0,\n      'y': 0,\n      'v': { 'r': 0, 'theta': ((360 / num) | 0) * i, 'w': 1, 'ra': 0.2 }\n    } ) ;\n  }\n} ;\n\n\nBombFactory.prototype.create = function( fighter ) {\n  var bombs = [ ] ;\n  for( var i = 0; i < this.params.length; i++ ) {\n    this.params[ i ].x = fighter.getX( ) ;\n    this.params[ i ].y = fighter.getY( ) ;\n    var bomb = this.freelist.get( ) ;\n    bomb.init( this.params[ i ], this._getImage( this.params[ i ] ), fighter ) ;\n    bombs.push( bomb ) ;\n  }\n  return bombs ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nBombFactory.prototype._getImage = function(params) {\n  if(this.image === null)\n    this.image = this.gameState.getImage(Game._IMG_BOMB);\n  return this.image;\n};\n\n\n\nfunction BombFreeList( num, gameState ) {\n  this.parent = ElementFreeList ;\n  this.parent.call( this, num, gameState ) ;\n}\n__inherit( BombFreeList, ElementFreeList ) ;\n\n\nBombFreeList.prototype._generateElement = function( ) {\n  return new Bomb( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\n\nfunction BombDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(BombDrawer, ElementDrawer);\n\nBombDrawer.prototype.Layer = Layer;\n\nBombDrawer.prototype._getBlend = function() {\n  return this.Layer._BLEND_ADD_ALPHA;\n};\n\n\n\nfunction BombView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n  this.a = 0.4;\n};\n__inherit(BombView, ElementView);\n\n\n\n/**\n * Currently Bomb represents just a big bullet.\n */\nfunction Bomb( gameState, maxX, maxY ) {\n  this.parent = Element ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n}\n__inherit( Bomb, Element ) ;\n\nBomb.prototype._WIDTH  = 128 ;\nBomb.prototype._HEIGHT = 128 ;\n\nBomb.prototype._OUT_RANGE = 200 ;\n\n\nBomb.prototype.Element_init = Element.prototype.init;\nBomb.prototype.init = function( params, image, fighter ) {\n  this.Element_init(params, image);\n\n  this.setX( fighter.getX( ) ) ;\n  this.setY( fighter.getY( ) ) ;\n\n  this.width = this._WIDTH ;\n  this.height = this._HEIGHT ;\n  this.collisionWidth = this.width ;\n  this.collisionHeight = this.height ;\n  this.indexX = 0 ;\n  this.indexY = 3 ;\n  this._initView();\n} ;\n\n\nBomb.prototype._generateView = function() {\n  return new BombView(this);\n};\n\n\nBomb.prototype.display = function( surface ) {\n//  surface.save( ) ;\n  surface.globalAlpha = 0.6 ;\n  this.parent.prototype.display.call( this, surface ) ;\n  surface.globalAlpha = 1.0 ;\n//  surface.restore( ) ;\n} ;\n\n\nBomb.prototype._outOfTheField = function( ) {\n  if( this.getX( ) < -this._OUT_RANGE || this.getX( ) > this.maxX + this._OUT_RANGE ||\n      this.getY( ) < -this._OUT_RANGE || this.getY( ) > this.maxY + this._OUT_RANGE )\n    return true ;\n  return false ;\n} ;\n"
  },
  {
    "path": "source/Boss.js",
    "content": "function BossManager( gameState, params ) {\n  this.parent = ElementManager ;\n  this.parent.call( this, gameState ) ;\n  for( var i = 0; i < params.length; i++ ) {\n    params[ i ].sort( function( a, b ) {\n      return a.count - b.count ;\n    } ) ;\n  }\n  this.params = params ;\n  this.index = 0 ;\n  this.stageIndex = 0 ; // TODO: temporal\n  this.drawers = null;\n  this.activeType = null;\n} ;\n__inherit( BossManager, ElementManager ) ;\n\nBossManager.prototype._MAX_NUM = 4;\n\nBossManager.prototype._initMaxNum = function() {\n  return this._MAX_NUM;\n};\n\n\nBossManager.prototype._initFactory = function( ) {\n  this.factory = new BossFactory( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\n/**\n * TODO: consider the design. To use drawers is easy to handle,\n *       but not smart. To extend BossDrawer is smarter.\n */\nBossManager.prototype.initDrawer = function(layer, image) {\n  this.drawers = [];\n  this._generateDrawer(this.Boss._TYPE_RUMIA, layer);\n  this._generateDrawer(this.Boss._TYPE_DAIYOUSEI, layer);\n  this._generateDrawer(this.Boss._TYPE_CHIRNO, layer);\n};\n\n\nBossManager.prototype._generateDrawer = function(key, layer) {\n  this.drawers[key] = new BossDrawer(this, layer, this._getImage(key));\n};\n\n\n/**\n * TODO: consider who should manage image.\n */\nBossManager.prototype._getImage = function(type) {\n  var key;\n  switch(type) {\n    case this.Boss._TYPE_RUMIA:\n      key = Game._IMG_ENEMY_RUMIA;\n      break;\n    case this.Boss._TYPE_DAIYOUSEI:\n      key = Game._IMG_ENEMY_DAIYOUSEI;\n      break;\n    case this.Boss._TYPE_CHIRNO:\n      key = Game._IMG_ENEMY_CHILNO;\n      break;\n    // TODO: temporal\n    default:\n      key = Game._IMG_ENEMY_MOKOU;\n      break;\n  }\n  return this.gameState.getImage(key);\n};\n\n\n__copyParentMethod(BossManager, ElementManager, 'reset');\nBossManager.prototype.reset = function() {\n  this.ElementManager_reset();\n  this.index = 0;\n  this.stageIndex = 0;\n  this.activeType = null;\n};\n\n\n/**\n * assumes only one boss in a display.\n */\nBossManager.prototype.draw = function(layer) {\n  if(! this.existBoss())\n    return;\n\n  this.drawers[this.activeType].draw(layer);\n};\n\n\nBossManager.prototype.goNextStage = function() {\n  this.ElementManager_reset(this);\n  this.index = 0;\n  this.stageIndex++;\n};\n\n\n__copyParentMethod(BossManager, ElementManager, 'runStep');\nBossManager.prototype.runStep = function() {\n  this._generateBoss();\n  this.ElementManager_runStep();\n};\n\n\nBossManager.prototype._generateBoss = function() {\n  if(this.gameState.isBossExist())\n    return;\n\n  while(this.index < this.params[this.stageIndex].length &&\n        this.params[this.stageIndex][this.index].count\n          + this.gameState.pending <= this.gameState.count) {\n    var params = this.params[this.stageIndex][this.index];\n    var boss = this.factory.create(params);\n    this.activeType = this._str2type(params.character);\n    this.gameState.notifyBossAppeared(boss);\n    this.addElement(boss);\n    this.index++;\n  }\n};\n\n\nBossManager.prototype._str2type = function(str) {\n  switch(str) {\n    case 'rumia':\n      return this.Boss._TYPE_RUMIA;\n    case 'daiyousei':\n      return this.Boss._TYPE_DAIYOUSEI;\n    case 'chilno':\n      return this.Boss._TYPE_CHIRNO;\n    // TODO: temporal\n    default:\n      return null;\n  }\n};\n\n\n/**\n * TODO: temporal\n */\n__copyParentMethod(BossManager, ElementManager, 'checkLoss');\nBossManager.prototype.checkLoss = function() {\n  this.ElementManager_checkLoss(this);\n};\n\n\n/**\n * TODO: temporal\n */\nBossManager.prototype.notifyCheckLoss = function(element) {\n  if(element.dead != 'escape')\n    this.gameState.notifyBossVanishEnd(element);\n};\n\n\n/**\n * TODO: temporal. implement multi bosses?\n */\nBossManager.prototype.getBoss = function() {\n  return (this.existBoss()) > 0 ? this.elements[0] : null;\n};\n\n\nBossManager.prototype.existBoss = function() {\n  return this.getNum( ) > 0 ? true : false;\n};\n\n\n/**\n * TODO: temporal. I wanna use the parent method but bigger one should be the argument of this method.\n */\n__copyParentMethod(BossManager, ElementManager, 'checkCollisionWith');\nBossManager.prototype.checkCollisionWith = function(fighter) {\n  this.ElementManager_checkCollisionWith(null, fighter, this);\n};\n\n\nBossManager.prototype.checkCollisionWithFighters = function(fighters) {\n  for(var i = 0; i < fighters.length; i++) {\n    this.checkCollisionWith(fighters[i]);\n  }\n};\n\n\nBossManager.prototype.notifyCollision = function(id, fighter, boss) {\n  fighter.die();\n  this.gameState.notifyFighterDead(fighter, boss);\n};\n\n\n\nfunction BossFactory( gameState, maxX, maxY ) {\n  this.parent = ElementFactory ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n} ;\n__inherit( BossFactory, ElementFactory ) ;\n\nBossFactory.prototype._NUM = 2 ;\n\n\nBossFactory.prototype._initFreelist = function() {\n  this.freelist = new BossFreeList(this._NUM, this.gameState);\n};\n\n\nBossFactory.prototype._getImage = function( params ) {\n  switch( params.character ) {\n    case 'rumia':\n      return this.gameState.getImage( Game._IMG_ENEMY_RUMIA ) ;\n    case 'chilno':\n      return this.gameState.getImage( Game._IMG_ENEMY_CHILNO ) ;\n    case 'daiyousei':\n      return this.gameState.getImage( Game._IMG_ENEMY_DAIYOUSEI ) ;\n    // TODO: temporal\n    default:\n      return this.gameState.getImage( Game._IMG_ENEMY_MOKOU ) ;\n  }\n} ;\n\n\n\nfunction BossFreeList( num, gameState ) {\n  this.parent = ElementFreeList ;\n  this.parent.call( this, num, gameState ) ;\n}\n__inherit( BossFreeList, ElementFreeList ) ;\n\n\nBossFreeList.prototype._generateElement = function( ) {\n  return new Boss( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\nfunction BossDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(BossDrawer, ElementDrawer);\n\n\n\nfunction BossView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(BossView, ElementView);\n\n\n/**\n * no rotate.\n * TODO: no rotate impl should be in parent class?\n */\nBossView.prototype.rotate = function() {\n};\n\n\nBossView.prototype.doRotateForViewpoint = function() {\n  return true;\n};\n\n\nBossView.prototype.animate = function() {\n  this._initCoordinates();\n\n  if(this.element.inVanishing()) {\n    this.a = this._inVanishingEffect();\n  } else if(this.element.effects && this.element.effects['vanish']) {\n    this.a = this._vanishEffect(this.element.effects['vanish']);\n  } else {\n    this.a = 1.0;\n  }\n};\n\n\n/**\n * TODO: temporal. especially name.\n */\nBossView.prototype._inVanishingEffect = function() {\n  return (this.element._VANISH_COUNT -\n          this.element.vanishingCount + 1) * 0.01;\n};\n\n\n/**\n * TODO: temporal. especially name.\n */\nBossView.prototype._vanishEffect = function(params) {\n  var count = this.element._getCountFromBase(params, -1);\n\n  if(count >= params['count'] &&\n     count <  params['count'] + params['length']) {\n    return 1.0 - ((count - params['count']) / params['length']) ;\n  }\n  return 1.0;\n};\n\n\n\nfunction Boss( gameState, maxX, maxY ) {\n  this.parent = Element ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n\n  this.params = null ;\n  this.index = 0 ;\n  this.maxVital = 0 ;\n\n  this.appearedTalk = null ;\n  this.vanishedTalk = null ;\n  this.character = null ;\n  this.score = null ;\n  this.dead = null ;\n  this.animation = null ;\n  this.spellCard = false ;\n  this.effect = null ;\n\n  this.escaping = false;\n\n  this.vanishing = false;\n  this.vanishingCount = 0;\n\n/*\n  this.powerItem  = powerItem  ? powerItem : 0 ;\n  this.lpowerItem = lpowerItem ? lpowerItem : 0 ;\n  this.scoreItem  = scoreItem  ? scoreItem : 0 ;\n*/\n\n  this.shots = [ ] ;\n  this.shotIndices = [ ] ;\n\n}\n__inherit( Boss, Element ) ;\n\nBoss.prototype._WIDTH = 128 ;\nBoss.prototype._HEIGHT = 128 ;\n\nBoss.prototype._APPEAR_COUNT = 100 ;\nBoss.prototype._APPEAR_WAIT_COUNT = 50 ;\n\nBoss.prototype._VANISH_COUNT = 100;\n\nBoss.prototype._TYPE_RUMIA     = 0;\nBoss.prototype._TYPE_DAIYOUSEI = 1;\nBoss.prototype._TYPE_CHIRNO    = 2;\n\nBoss.prototype._ESCAPE_VECTOR = {'r': 0, 'theta': 225, 'ra': 0.1};\n\n\n__copyParentMethod(Boss, Element, 'init');\nBoss.prototype.init = function(params, image) {\n  this.Element_init(params, image);\n\n  this.params = params.params ;\n  this.index = 0 ;\n  this.maxVital = 0 ;\n\n  this.appearedTalk = params.appearedTalk ;\n  this.vanishedTalk = params.vanishedTalk ;\n  this.character = params.character ;\n  this.score = params.score ;\n  this.dead = params.dead ;\n  this.animation = params.animation ; // TODO: temporal\n  this.spellCard = false ;\n  this.effect = null ;\n\n  this.escaping = false;\n\n  this.vanishing = false;\n  this.vanishingCount = 0;\n\n/*\n  this.powerItem  = powerItem  ? powerItem : 0 ;\n  this.lpowerItem = lpowerItem ? lpowerItem : 0 ;\n  this.scoreItem  = scoreItem  ? scoreItem : 0 ;\n*/\n\n  this.shots.length = 0 ;\n  this.shotIndices.length = 0 ;\n\n  this._initState( ) ;\n  this._initView();\n} ;\n\n\nBoss.prototype._generateView = function() {\n  return new BossView(this);\n};\n\n\nBoss.prototype._shot = function( ) {\n  if( this.shots.length == 0 )\n    return ;\n\n  if(this.vanishing || this.escaping)\n    return;\n\n  var offset = this._APPEAR_COUNT + this._APPEAR_WAIT_COUNT ;\n  if( this.count < offset )\n    return ;\n  for( var i = 0; i < this.shots.length; i++ ) {\n    var count = this.count - offset ;\n    if( this.shots[ i ].baseCount )\n      count = count % this.shots[ i ].baseCount ;\n    if( count == 0 ) {\n      this.shotIndices[ i ] = 0 ;\n    }\n    if( this.shotIndices[ i ] >= this.shots[ i ].shotCount.length ) {\n      continue ;\n    }\n    if( count >= this.shots[ i ].shotCount[ this.shotIndices[ i ] ] ) {\n      // TODO: temporal\n      this.gameState.notifyEnemyDoShot( this, this.shots[ i ] ) ;\n      this.shotIndices[ i ]++ ;\n    }\n  }\n} ;\n\n\n// TODO: temporal\n__copyParentMethod(Boss, Element, 'runStep');\nBoss.prototype.runStep = function() {\n  if(this.isFlagSet(this._FLAG_UNHITTABLE) &&\n     this.count + 1 >= this._APPEAR_COUNT + this._APPEAR_WAIT_COUNT) {\n    this.clearFlag(this._FLAG_UNHITTABLE);\n    if(this.index == 0)\n      this.gameState.notifyBossBeginTalk(this);\n    else\n      this.gameState.notifyBossBecameActive(this);\n  }\n  this._shot();\n  this._doEffect();\n\n  this.Element_runStep();\n\n  // for animation\n  this._checkState();\n  // TODO: temporal\n  if(this.getXDirection() == 1) {\n    this.indexX = 2;\n    this.indexY = 3;\n  } else if(this.getXDirection() == -1) {\n    this.indexX = 2;\n    this.indexY = 1;\n  } else {\n    this.indexX = 0;\n    if(this.count % 4 == 0) {\n      this.indexY++;\n      if(this.indexY > this.animation)\n        this.indexY = 0;\n    }\n  }\n\n  if(this.vanishing)\n    this.vanishingCount++;\n};\n\n\n/**\n * TODO: temporal\n */\nBoss.prototype._getCountFromBase = function(params, o) {\n  var o = o ? o : 0;\n  var offset = this._APPEAR_COUNT + this._APPEAR_WAIT_COUNT;\n  return (this.count - offset + o) % params['baseCount'];\n};\n\n\nBoss.prototype._doEffect = function() {\n  if(this.effects && this.effects['shockwave'] !== void 0) {\n    // TODO: temporal\n    for(var i = 0; i < this.effects['shockwave'].length; i++) {\n      var params = this.effects['shockwave'][i];\n      var count = this._getCountFromBase(params);\n      if(count == params['count'])\n        this.gameState.notifyDoEffect(this, 'shockwave', params.params);\n    }\n  }\n};\n\n\n/**\n * TODO: temporal\n */\nBoss.prototype._checkState = function() {\n  if(this.vanishing || this.escaping)\n    return;\n  if(this.vital <= 0) {\n    this.index++;\n    if(this.index >= this.params.length) {\n      this.die();\n      this.gameState.notifyBossVanished(this);\n      if(this.dead == 'escape')\n        this._beginEscape();\n      else\n        this._beginVanish();\n    } else {\n      this.gameState.notifyBossMovedNextStage(this);\n      this._initState();\n    }\n  }\n};\n\n\nBoss.prototype._initState = function( ) {\n\n  // TODO: temporal\n  this.count = 0 ;\n\n  // TODO: temporal\n  var shots = this.params[ this.index ].s ;\n\n  // TODO: temporal\n  this.vectorIndex = 0 ;\n  this.vectors.length = 0 ;\n  for( var i = 0; i < this.params[ this.index ].v.length; i++ ) {\n    this.vectors.push( this.params[ this.index ].v[ i ] ) ;\n  }\n//  this.vectors = this.params[ this.index ].v ;\n  this.vectors.unshift( {\n    'count': -this._APPEAR_WAIT_COUNT,\n    'v': {\n      'r':     0,\n      'theta': 0,\n      'w':     0,\n      'ra':    0,\n      'wa':    0,\n      'raa':   0,\n    }\n  } ) ;\n  this.vectors.unshift( {\n    'count': 0,\n    'v': {\n      'r':     0,\n      'theta': 0,\n      'w':     0,\n      'ra':    0,\n      'wa':    0,\n      'raa':   0,\n      'target': { 'x': this.params[ this.index ].x,\n                  'y': this.params[ this.index ].y,\n                  'count': this._APPEAR_COUNT }\n    }\n  } ) ;\n  this.baseVectorCount = this._APPEAR_COUNT + this._APPEAR_WAIT_COUNT ;\n\n  this._initVector( ) ;\n\n  this.shots.length = 0;\n  if(shots === void 0) {\n  } else if(shots instanceof Array) {\n    for( var i = 0; i < shots.length; i++ )\n      this.shots.push( shots[ i ] ) ;\n  } else {\n    shots = [ shots ] ;\n    this.shots.push( shots[ 0 ] ) ;\n  }\n\n  // TODO: temporal\n  this.shotIndices.length = 0 ;\n  for( var i = 0; i < this.shots.length; i++ ) {\n    this.shotIndices.push( 0 ) ;\n  }\n\n  this.vital = this.params[ this.index ].vital ;\n  this.maxVital = this.vital ;\n  this.spellCard = this.params[ this.index ].spellCard ;\n  this.effects = this.params[ this.index ].e ;\n  this.setFlag( this._FLAG_UNHITTABLE ) ;\n  this.gameState.notifyBossStageChanged( this ) ;\n\n} ;\n\n\n__copyParentMethod(Boss, Element, 'getXDirection');\nBoss.prototype.getXDirection = function() {\n  if(this.vector && this.vector.r == 0)\n    return 0;\n  return this.Element_getXDirection();\n};\n\n\n__copyParentMethod(Boss, Element, '_outOfTheField');\nBoss.prototype._outOfTheField = function() {\n  if(this.Element_outOfTheField())\n    this._beInTheField();\n  return false;\n};\n\n\n/**\n * TODO: temporal function name\n */\nBoss.prototype.outOfTheField = function() {\n  return this.Element_outOfTheField();\n};\n\n\nBoss.prototype._beginEscape = function() {\n  this.escaping = true;\n  this.gravity = null;\n  // TODO: temporal\n  this.vector = this.moveVectorManager.create(this._ESCAPE_VECTOR);\n\n  // TODO: these parameters should move to EffectFactory.\n  this.gameState.notifyDoEffect(this, 'shockwave', {\n    'w': 5,\n    'g': 5,\n    'a': 0.1,\n    'b': 20,\n    'endCount': 100\n  });\n};\n\n\nBoss.prototype._beginVanish = function() {\n  this.vanishing = true;\n  this.vanishingCount = 0;\n\n  this.gravity = null;\n  this.vector = null;\n\n  // TODO: these parameters should move to EffectFactory.\n  this.gameState.notifyDoEffect(this, 'shockwave', {\n    'w': 5,\n    'g': 5,\n    'a': 0.1,\n    'b': 10,\n    'endCount': 100\n  });\n  this.gameState.effectManager.createBigExplosion(this);\n\n\n  // TODO: who manages this logic? Boss? StageState?\n  if(this.dead == 'escape' && this.vanishedTalk) {\n    this.gameState.notifyBeginTalk();\n  }\n\n};\n\n\nBoss.prototype.inVanishing = function() {\n  return (this.vanishing && this.vanishingCount < this._VANISH_COUNT);\n};\n\n\nBoss.prototype.overVanishing = function() {\n  return (this.vanishing && this.vanishingCount >= this._VANISH_COUNT);\n};\n\n\n/**\n * TODO: temporal workaround.\n */\n__copyParentMethod(Boss, Element, '_checkVectorChange');\nBoss.prototype._checkVectorChange = function() {\n  if(this.escaping || this.vanishing)\n    return false;\n  return this.Element_checkVectorChange();\n};\n\n\n/**\n * TODO: temporal logic.\n */\n__copyParentMethod(Boss, Element, 'checkLoss');\nBoss.prototype.checkLoss = function() {\n  if(this.escaping)\n    return this.Element_outOfTheField();\n\n  if(! this.vanishing)\n    return this.Element_checkLoss();\n\n  var tmp = this.state;\n  this.state = this._STATE_ALIVE;\n  var value = this.Element_checkLoss();\n  this.state = tmp;\n\n  if(value)\n    return value;\n\n  return this.overVanishing();\n};\n\n\n// TODO: temporal\nBoss.prototype.isVanishingOrEscaping = function() {\n  return (this.vanishing || this.escaping);\n};\n\n\n\n// TODO: remove the followings because they complicate the design.\n\n// only for reference\n// TODO: temporal\nBossManager.prototype.Boss = Boss.prototype;\n\n"
  },
  {
    "path": "source/Bullet.js",
    "content": "function BulletManager( gameState, params ) {\n  this.parent = ElementManager ;\n  this.parent.call( this, gameState ) ;\n  this.params = params ;\n  this.laserCounts = [0, 0]; // TODO: temporal\n} ;\n__inherit( BulletManager, ElementManager ) ;\n\nBulletManager.prototype._MAX_NUM = 500;\n\nBulletManager.prototype._initMaxNum = function() {\n  return this._MAX_NUM;\n};\n\n\nBulletManager.prototype._initFactory = function( ) {\n  this.factory = new BulletFactory( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\nBulletManager.prototype.initDrawer = function(layer, image) {\n  this.drawer = new BulletDrawer(this, layer,\n                                 this.gameState.getImage(Game._IMG_SHOT));\n};\n\n\n__copyParentMethod(BulletManager, ElementManager, 'reset');\nBulletManager.prototype.reset = function() {\n  this.ElementManager_reset();\n  for(var i = 0; i < this.laserCounts.length; i++) {\n    this.laserCounts[i] = 0;\n  }\n};\n\n\n/**\n * TODO: temporal. to make the logic straightforward.\n */\nBulletManager.prototype.create = function( fighter ) {\n  var params = this.params[ fighter.characterIndex ][ fighter.getBulletIndex( ) ][ fighter.getPowerLevel( ) ] ;\n  var flag = false ;\n  var count = 0 ;\n  var id = fighter.getID();\n  for( var i = 0; i < params.length; i++ ) {\n    // TODO: temporal\n    if( ( params[ i ].laser || params[ i ].homing ) && params[ i ].nextCount ) {\n      if( this.count < this.laserCounts[id] + params[ i ].nextCount ) {\n        continue ;\n      }\n      flag = true ;\n      if( this.count > count )\n        count = this.count ;\n    }\n    this.addElement( this.factory.create( params[ i ], fighter ) ) ;\n  }\n  if( flag )\n    this.laserCounts[id] = count ;\n} ;\n\n\n__copyParentMethod(BulletManager, ElementManager, 'checkCollisionWith');\nBulletManager.prototype.checkCollisionWithEnemies = function(enemies) {\n  var self = this;\n  for(var i = 0; i < enemies.length; i++) {\n    this.ElementManager_checkCollisionWith(null, enemies[i], this);\n  }\n};\n\n\nBulletManager.prototype.notifyCollision = function(id, enemy, bullet) {\n  // TODO: temporal\n  if(bullet._ID !== this._ID_LASER)\n    bullet.die();\n  // TODO: temporal\n  enemy.vital -= bullet.power;\n  this.gameState.notifyBulletHit(bullet, enemy);\n  if(enemy.vital <= 0) {\n    this.gameState.notifyEnemyVanished(bullet, enemy);\n    enemy.die();\n  }\n};\n\n\n/**\n * TODO: temporal\n */\n__copyParentMethod(BulletManager, ElementManager, 'checkCollisionWith2');\nBulletManager.prototype.checkCollisionWithBoss = function(boss) {\n  if(boss.isFlagSet(boss._FLAG_UNHITTABLE))\n    return;\n\n  var self = this;\n  this.ElementManager_checkCollisionWith2(null, boss, this);\n};\n\n\nBulletManager.prototype.notifyCollision2 = function(id, boss, bullet) {\n  // TODO: temporal\n  if(bullet._ID !== this._ID_LASER)\n    bullet.die();\n  boss.vital -= bullet.power;\n  this.gameState.notifyBulletHit(bullet, boss);\n};\n\n\n\nfunction BulletFactory( gameState, maxX, maxY ) {\n  this.parent = ElementFactory ;\n\n  this.homingFreelist = null ;\n  this.laserFreelist = null ;\n\n  this.parent.call( this, gameState, maxX, maxY ) ;\n  this.types = __bulletTypes ;  // TODO: temporal\n  this.image = null; // TODO: temporal\n}\n__inherit( BulletFactory, ElementFactory ) ;\n\nBulletFactory.prototype._BULLET_NUM = 100 ;\nBulletFactory.prototype._HOMING_NUM = 100 ;\nBulletFactory.prototype._LASER_NUM  = 10 ;\n\n\nBulletFactory.prototype._initFreelist = function() {\n  this.freelist       = new BulletFreeList(this._BULLET_NUM, this.gameState);\n  this.homingFreelist = new HomingFreeList(this._HOMING_NUM, this.gameState);\n  this.laserFreelist  = new LaserFreeList( this._LASER_NUM,  this.gameState);\n};\n\n\nBulletFactory.prototype.create = function( params, fighter ) {\n  if( params.laser ) {\n    var laser = this.laserFreelist.get( ) ;\n    laser.init( params, this._getImage( params ), \n                fighter.getOption(params.option), // TODO: temporal\n                this.types[ 3 ]) ; // TODO: temporal\n    return laser ;\n  }\n  if( params.homing ) {\n    var homing = this.homingFreelist.get( ) ;\n    homing.init( params, this._getImage( params ),\n                 fighter.getOption(params.option), // TODO: temporal\n                 this.types[ 2 ]) ; // TODO: temporal\n    return homing ;\n  }\n  var key = fighter.characterIndex ;\n  var bullet = this.freelist.get( ) ;\n  bullet.init( params, this._getImage( params ), this.types[ key ], fighter ) ;\n  return bullet ;\n} ;\n\n\nBulletFactory.prototype.free = function( bullet ) {\n  switch(bullet._ID) {\n    case this.BulletManager._ID_BULLET:\n      this.freelist.free( bullet ) ;\n      return;\n    case this.BulletManager._ID_LASER:\n      this.laserFreelist.free( bullet ) ;\n      return;\n    case this.BulletManager._ID_HOMING:\n      this.homingFreelist.free( bullet ) ;\n      return;\n    default:\n      // throw exception?\n  }\n};\n\n\n/**\n * TODO: temporal\n */\nBulletFactory.prototype._getImage = function(params) {\n  if(this.image === null)\n    this.image = this.gameState.getImage(Game._IMG_SHOT);\n  return this.image;\n};\n\n\n\nfunction BulletFreeList( num, gameState ) {\n  this.parent = ElementFreeList ;\n  this.parent.call( this, num, gameState ) ;\n}\n__inherit( BulletFreeList, ElementFreeList ) ;\n\n\nBulletFreeList.prototype._generateElement = function( ) {\n  return new Bullet( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\n\nfunction BulletDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(BulletDrawer, ElementDrawer);\n\n\nfunction BulletView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n  this.a = 0.8;\n};\n__inherit(BulletView, ElementView);\n\n\n\nfunction Bullet( gameState, maxX, maxY ) {\n  this.parent = Element ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n  this.rotate = null ;\n  this.power = null ;\n  this.fighter = null;\n}\n__inherit( Bullet, Element ) ;\n\nBullet.prototype._WIDTH = 16 ;\nBullet.prototype._HEIGHT = 32 ;\n\n\n/**\n * TODO: temporal. params2 should be renamed.\n */\n__copyParentMethod(Bullet, Element, 'init');\nBullet.prototype.init = function(params, image, params2, fighter) {\n\n  this.fighter = fighter;\n  this.Element_init(params, image);\n\n  this.setX(this.getX() + this.fighter.getX());\n  this.setY(this.getY() + this.fighter.getY());\n\n  // TODO: temporal. Wanna combine this logic with parent init( ).\n  this.indexX = params2.indexX !== void 0 ? params2.indexX : 0;\n  this.indexY = params2.indexY !== void 0 ? params2.indexY : 0;\n  this.width  = params2.width  !== void 0 ? params2.width  : 0;\n  this.height = params2.height !== void 0 ? params2.height : 0;\n  this.collisionWidth  = params2.collisionWidth  !== void 0 ? params2.collisionWidth  : 0;\n  this.collisionHeight = params2.collisionHeight !== void 0 ? params2.collisionHeight : 0;\n\n  this.power  = params.power   !== void 0 ? params.power   : 1;\n  this.rotate = params2.rotate !== void 0 ? params2.rotate : 0;\n  this._initView();\n};\n\n\nBullet.prototype._generateView = function() {\n  return new BulletView(this);\n};\n\n\n/**\n * TODO: which is faster save&restore or doing by my hand?\n */\nBullet.prototype.display = function( surface ) {\n//  surface.save( ) ;\n  surface.globalAlpha = 0.8 ;\n  this.parent.prototype.display.call( this, surface, true ) ;\n  surface.globalAlpha = 1.0 ;\n//  surface.restore( ) ;\n} ;\n\n\n\nfunction LaserFreeList( num, gameState ) {\n  this.parent = ElementFreeList ;\n  this.parent.call( this, num, gameState ) ;\n}\n__inherit( LaserFreeList, ElementFreeList ) ;\n\n\nLaserFreeList.prototype._generateElement = function( ) {\n  return new Laser( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\n\n/**\n * TODO: consider the option to use add blend.\n */\nfunction LaserView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(LaserView, ElementView);\n\n\nLaserView.prototype._getElementX = function() {\n  return this.element.option.getCenterX() + this.element.getX();\n};\n\n\nLaserView.prototype._getElementY = function() {\n  return this.element.option.getCenterY() + this.element.getY();\n};\n\n\nLaserView.prototype._getElementZ = function() {\n  return this.element.option.getZ();\n};\n\n\n/**\n * assumes that image height is 256 and master image size is 256.\n * TODO: temporal\n */\n__copyParentMethod(LaserView, ElementView, '_initVertices');\nLaserView.prototype._initVertices = function() {\n  this.ElementView_initVertices();\n  this.vertices[1]   = 0;\n  this.vertices[4]   = 0;\n  this.vertices[7]  *= 4;\n  this.vertices[10] *= 4;\n};\n\n\n/**\n * assumes that image height is 256 and master image size is 256.\n * TODO: temporal\n */\n__copyParentMethod(LaserView, ElementView, '_initCoordinates');\nLaserView.prototype._initCoordinates = function() {\n  this.ElementView_initCoordinates();\n  this.coordinates[1] *= 2;\n  this.coordinates[3] *= 2;\n};\n\n\n/**\n * TODO: should be in Laser?\n */\nLaserView.prototype.animate = function() {\n  if(this.element.count < this.element.waitCount ||\n     this.element.count + 10 > this.element.keepAlive )\n    this.a = 0.2;\n  else\n    this.a = 0.8;\n};\n\n\n\n/**\n * TODO: temporal\n */\nfunction Laser( gameState, maxX, maxY ) {\n  this.parent = Element ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n  this.rotate = null ;\n  this.option = null ;\n  this.power  = null ;\n}\n__inherit( Laser, Element ) ;\n\nLaser.prototype._WIDTH = 16 ;\nLaser.prototype._HEIGHT = 16 ;\n\n\n__copyParentMethod(Laser, Element, 'init');\nLaser.prototype.init = function(params, image, option, params2) {\n\n  this.Element_init(params, image);\n\n  this.option = option;\n\n  // TODO: temporal. Wanna combine this logic with parent init( ).\n  this.keepAlive = this._getValueOrDefaultValue(params.keep, 0);\n  this.indexX = params2.indexX !== void 0 ? params2.indexX : 0;\n  this.indexY = params2.indexY !== void 0 ? params2.indexY : 0;\n  this.width  = params2.width  !== void 0 ? params2.width  : 0;\n  this.height = params2.height !== void 0 ? params2.height : 0;\n  this.collisionWidth  = params2.collisionWidth  !== void 0 ? params2.collisionWidth  : 0;\n  this.collisionHeight = params2.collisionHeight !== void 0 ? params2.collisionHeight : 0;\n\n  this.power     = params.power     !== void 0 ? params.power     : 1;\n  this.waitCount = params.waitCount !== void 0 ? params.waitCount : 50;\n  this.rotate    = params2.rotate   !== void 0 ? params2.rotate   : 0;\n  this._initView();\n};\n\n\nLaser.prototype._generateView = function() {\n  return new LaserView(this);\n};\n\n\n/**\n * TODO: temporal\n */\nLaser.prototype.display = function( surface ) {\n\n  var x = Math.round( this.option.getCenterX( ) + this.getLeftX( ) ) ;\n  var y = Math.round( this.option.getCenterY( ) + this.getCenterY( ) ) ;\n//  surface.save( ) ;\n  if( this.count < this.waitCount || this.count + 10 > this.keepAlive )\n    surface.globalAlpha = 0.2 ;\n  else\n    surface.globalAlpha = 0.6 ;\n  while( y > 0 ) {\n    surface.drawImage( this.image,\n                       this.width  * this.indexX, this.height * this.indexY,\n                       this.width,                this.height,\n                       x,                         y,\n                       this.width,                -this.height ) ;\n    y -= this.height ;\n  }\n  surface.globalAlpha = 1.0 ;\n//  surface.restore( ) ;\n\n} ;\n\n\n/**\n * TODO: temporal\n */\nLaser.prototype.checkCollision = function( enemy ) {\n  if( this.count < this.waitCount )\n    return false ;\n\n  // TODO: temporal\n  if( this.count % 3 != 0 )\n    return false ;\n\n  // TODO: temporal\n  if( this.vector.theta != 270 )\n    return false ;\n\n  if( enemy.getCollisionUpY( ) > this.y + this.option.getCenterY( ) )\n    return false ;\n\n  if( enemy.getCollisionRightX( ) < this.x + this.option.getCenterX( ) - this.width/2 )\n    return false ;\n\n  if( enemy.getCollisionLeftX( ) > this.x + this.option.getCenterX( ) + this.width/2 )\n    return false ;\n\n  return true ;\n\n} ;\n\n\n/**\n * TODO: temporal\n */\nLaser.prototype.checkLoss = function( ) {\n  if( this.isDead( ) )\n    return true ;\n  if( this.keepAlive && this.count >= this.keepAlive )\n    return true ;\n  return false ;\n} ;\n\n\n\nfunction HomingFreeList( num, gameState ) {\n  this.parent = ElementFreeList ;\n  this.parent.call( this, num, gameState ) ;\n}\n__inherit( HomingFreeList, ElementFreeList ) ;\n\n\nHomingFreeList.prototype._generateElement = function( ) {\n  return new Homing( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\n\n/**\n * TODO: temporal\n */\nfunction Homing( gameState, maxX, maxY ) {\n  this.parent = Element ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n  this.rotate = null ;\n  this.option = null ;\n  this.power  = null ;\n  this.target = null ;\n  this.targetIsDead = false ;\n}\n__inherit( Homing, Element ) ;\n\nHoming.prototype.Math = Math;\n\nHoming.prototype._SEARCH_SPAN = 1000;\nHoming.prototype._HOMING_SPAN = 2;\nHoming.prototype._HOMING_COUNT = 50;\nHoming.prototype._HOMING_LAG = 5;\nHoming.prototype._HOMING_REACH = 10;\n\nHoming.prototype._OUT_RANGE = 30;\n\n\n__copyParentMethod(Homing, Element, 'init');\nHoming.prototype.init = function(params, image, option, params2) {\n\n  this.Element_init(params, image);\n\n  this.option = option;\n  this.setX(this.getX() + option.getCenterX());\n  this.setY(this.getY() + option.getCenterY());\n\n  // TODO: temporal. Wanna combine this logic with parent init( ).\n  this.keepAlive = this._getValueOrDefaultValue(params.keep, 0);\n  this.indexX = params2.indexX !== void 0 ? params2.indexX : 0;\n  this.indexY = params2.indexY !== void 0 ? params2.indexY : 0;\n  this.width  = params2.width  !== void 0 ? params2.width  : 0;\n  this.height = params2.height !== void 0 ? params2.height : 0;\n  this.collisionWidth  = params2.collisionWidth  !== void 0 ? params2.collisionWidth  : 0;\n  this.collisionHeight = params2.collisionHeight !== void 0 ? params2.collisionHeight : 0;\n\n  this.power     = params.power     !== void 0 ? params.power     : 1;\n  this.waitCount = params.waitCount !== void 0 ? params.waitCount : 50;\n  this.rotate    = params2.rotate   !== void 0 ? params2.rotate   : false;\n\n  this.target = null;\n  this.targetIsDead = false;\n  this._initView();\n};\n\n\n/**\n * unnecessary to have Homing special view.\n */\nHoming.prototype._generateView = function() {\n  return new BulletView(this);\n};\n\n\nHoming.prototype.display = function( surface ) {\n//  surface.save( ) ;\n  surface.globalAlpha = 0.8 ;\n  this.parent.prototype.display.call( this, surface, true ) ;\n  surface.globalAlpha = 1.0 ;\n//  surface.restore( ) ;\n\n} ;\n\n\n/**\n * TODO: temporal\n */\n__copyParentMethod(Homing, Element, 'runStep');\nHoming.prototype.runStep = function() {\n  if(this.count % this._SEARCH_SPAN == 0)\n    this._searchNearestEnemy();\n  if(this.count % this._HOMING_SPAN == 0)\n    this._calculateHomingPoint();\n\n  this.Element_runStep(this);\n};\n\n\n/**\n * TODO: temporal\n */\nHoming.prototype._searchNearestEnemy = function( ) {\n  // TODO: temporal\n  if( this.targetIsDead)\n    return ;\n\n  var min = 1000 * 1000 ; // TODO: temporary\n  var nearest = null ;\n  for( var i = 0; i < this.gameState.enemyManager.elements.length; i++ ) {\n    var e = this.gameState.enemyManager.elements[ i ] ;\n    var d = this.Math.pow( this.getX( ) - e.getX( ), 2 ) + this.Math.pow( this.getY( ) - e.getY( ), 2 ) ;\n    if( d < min ) {\n      min = d ;\n      nearest = e ;\n    }\n  }\n  if( this.gameState.bossManager.existBoss( ) ) {\n    var b = this.gameState.bossManager.getBoss( ) ;\n    if(! b.vanishing && ! b.escaping) {\n      var d = this.Math.pow( this.getX( ) - b.getX( ), 2 ) + this.Math.pow( this.getY( ) - b.getY( ), 2 ) ;\n      if( d < min ) {\n        min = d ;\n        nearest = b ;\n      }\n    }\n  }\n\n  // TODO: temporary\n  if( nearest )\n    this.target = nearest ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nHoming.prototype._calculateHomingPoint = function( ) {\n  if( ! this.target )\n    return ;\n  // TODO: how handles the case if target is used for the other alive element soon again?\n  if(this.target.isDead() || this.target.isFlagSet(this._FLAG_UNHITTABLE) ||\n      this.target.isVanishingOrEscaping()) {\n    this.targetIsDead = true ;\n    return ;\n  }\n  var ax = this.target.getX( ) - this.getX( ) ;\n  var ay = this.target.getY( ) - this.getY( ) ;\n  var t = this._calculateTheta( this.Math.atan2( ay, ax ) ) ;\n/*\n  var diff = t - this.vector.theta ;\n  if( Math.cos( this._calculateRadian( diff ) ) >\n      Math.cos( this._calculateRadian( Homing._HOMING_REACH ) ) ) {\n    this.vector.theta = t ;\n  } else if( Math.sin( this._calculateRadian( diff ) ) > 0 ) {\n    this.vector.theta += Homing._HOMING_REACH ;\n  } else if( Math.sin( this._calculateRadian( diff ) ) < 0 ) {\n    this.vector.theta -= Homing._HOMING_REACH ;\n  } else {\n*/\n    this.vector.theta = t ;\n/*\n  }\n*/\n  return ;\n} ;\n\n\nHoming.prototype._outOfTheField = function( ) {\n  if( this.getX( ) < -this._OUT_RANGE || this.getX( ) > this.maxX + this._OUT_RANGE ||\n      this.getY( ) < -this._OUT_RANGE || this.getY( ) > this.maxY + this._OUT_RANGE )\n    return true ;\n  return false ;\n} ;\n\n\n\n// TODO: remove the followings because they complicate the design.\n\nBulletManager.prototype._ID_BULLET = 0;\nBulletManager.prototype._ID_LASER  = 1;\nBulletManager.prototype._ID_HOMING = 2;\n\nBulletFactory.prototype.BulletManager = BulletManager.prototype;\n\nBullet.prototype._ID = BulletManager.prototype._ID_BULLET;\nLaser.prototype._ID  = BulletManager.prototype._ID_LASER;\nHoming.prototype._ID = BulletManager.prototype._ID_HOMING;\n"
  },
  {
    "path": "source/CharacterSelectState.js",
    "content": "function CharacterSelectState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n  this.elements = [ ] ;\n  this.index = 0 ;\n  this.count = 0 ;\n}\n__inherit( CharacterSelectState, GameState ) ;\n\n\nCharacterSelectState._APPEAR_SPAN = 10 ;\n\nCharacterSelectState.prototype.init = function( ) {\n  this.count = 0 ;\n  // TODO: magic number\n  for( var i = 0; i < 2; i++ ) {\n    this.elements[ i ] = { } ;\n    this.elements[ i ].width = 400 ;\n    this.elements[ i ].height = 600 ;\n  }\n  this.index = 0 ;\n} ;\n\n\nCharacterSelectState.prototype.runStep = function( ) {\n  this.count++ ;\n} ;\n\n\nCharacterSelectState.prototype.updateDisplay = function( surface ) {\n  this.game.clear( surface ) ;\n  this._displayBG( surface ) ;\n  this._displayMessage( surface ) ;\n  this._displayCharacters( surface ) ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nCharacterSelectState.prototype._displayBG = function( surface ) {\n  surface.save( ) ;\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n  surface.fillRect( 0, 0, this.getWidth( ), this.getHeight( ) ) ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.fillRect( 0, 50, this.getWidth( ), this.getHeight( ) - 100 ) ;\n\n  surface.globalAlpha = 0.05 ;\n  surface.drawImage( this.game.getImage( Game._IMG_TITLE_BG ),\n                     0,                 \n                     0,\n                     TitleState._WIDTH,\n                     TitleState._HEIGHT,\n                     0,\n                     0,\n                     this.getWidth( ),\n                     this.getHeight( ) ) ;\n\n  surface.restore( ) ;\n} ;\n\n\nCharacterSelectState.prototype._displayMessage = function( surface ) {\n  surface.save( ) ;\n  surface.font = \"30px 'Comic Sans MS'\" ;\n  surface.textAlign = 'center' ;\n  surface.textBaseAlign = 'middle' ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.fillText( 'Character Select', this.getWidth( ) / 2, 35 ) ;\n  surface.restore( ) ;\n} ;\n\n\nCharacterSelectState.prototype._displayCharacters = function( surface ) {\n  surface.save( ) ;\n  if( this.index == 0 ) {\n    surface.globalAlpha = 0.6 ;\n    this._displayMarisa( surface ) ;\n    surface.globalAlpha = 1.0 ;\n    this._displayReimu( surface ) ;\n  } else {\n    surface.globalAlpha = 0.6 ;\n    this._displayReimu( surface ) ;\n    surface.globalAlpha = 1.0 ;\n    this._displayMarisa( surface ) ;\n  }\n  surface.restore( ) ;\n} ;\n\n\nCharacterSelectState.prototype._displayReimu = function( surface ) {\n  surface.save( ) ;\n  var target = 0 ;\n  var from = this.getWidth( ) ;\n  var w = from - ( from - target ) * this.count / CharacterSelectState._APPEAR_SPAN ;\n  if( w < target )\n    w = target ;\n  surface.drawImage( this.game.getImage( Game._IMG_STAND_REIMU ),\n                     w,\n                     0 ) ;\n  surface.restore( ) ;\n} ;\n\n\nCharacterSelectState.prototype._displayMarisa = function( surface ) {\n  surface.save( ) ;\n  var target = this.getWidth( ) - this.elements[ 1 ].width ;\n  var from = -this.elements[ 1 ].width ;\n  var w = from - ( from - target ) * this.count / CharacterSelectState._APPEAR_SPAN ;\n  if( w > target )\n    w = target ;\n  surface.drawImage( this.game.getImage( Game._IMG_STAND_MARISA ),\n                     w,\n                     0 ) ;\n  surface.restore( ) ;\n} ;\n\n\nCharacterSelectState.prototype.handleKeyDown = function( e ) {\n  // TODO: temporal\n  if( this.count < CharacterSelectState._APPEAR_SPAN )\n    return ;\n\n  switch( e.keyCode ) {\n    case 37: // left\n      this.index++ ;\n      if( this.index > 1 )\n        this.index = 0 ;\n      this._soundEffect( Game._SE_SELECT ) ;\n      break ;\n    case 39: // right\n      this.index-- ;\n      if( this.index < 0 )\n        this.index = 1 ;\n      this._soundEffect( Game._SE_SELECT ) ;\n      break ;\n    case 88: // x\n      this.game.notifyLoadingConclusion( this.index ) ; // TODO: temporal\n      break ;\n    case 90: // z\n      this.game.notifyCharacterSelectConclusion( this.index ) ;\n      break ;\n  } ;\n} ;\n\n\nCharacterSelectState.prototype.handleKeyUp = function( e ) {\n\n} ;\n"
  },
  {
    "path": "source/Effect.js",
    "content": "/**\n * TODO: optimize this file.\n *       some codes and parameters are no longer used\n *       because of the design change.\n */\n\n/**\n * Effect represents an element which just shows on a screen,\n * and not affect any other elements.\n */\nfunction EffectManager(gameState) {\n  this.parent = ElementManager;\n  this.parent.call(this, gameState);\n};\n__inherit(EffectManager, ElementManager);\n\n// only for reference\nEffectManager.prototype.Layer = Layer;\nEffectManager.prototype.Math = Math;\n\nEffectManager.prototype._MAX_NUM = 200; // TODO: for each so far\n\n\nEffectManager.prototype._initMaxNum = function() {\n  return this._MAX_NUM;\n};\n\n\nEffectManager.prototype._initFactory = function() {\n  this.factory = new EffectFactory(this.gameState,\n                                   this.gameState.getWidth(),\n                                   this.gameState.getHeight());\n};\n\n\n\n/**\n * TODO: consider the design. To use drawers is easy to handle,\n *       but not smart. To extend Drawer could be smarter and\n *       performance could be better.\n */\nEffectManager.prototype.initDrawer = function(layer, image) {\n  this.drawers = [];\n  this.drawers.push(this._generateShockWaveDrawer(layer));\n  this.drawers.push(this._generateGrazeDrawer(layer));\n  this.drawers.push(this._generateExplosionDrawer(layer));\n  this.drawers.push(this._generateDamageDrawer(layer));\n  this.drawers.push(this._generateBigShockWaveDrawer(layer));\n  this.drawers.push(this._generateBigExplosionDrawer(layer));\n};\n\n\nEffectManager.prototype._generateShockWaveDrawer = function(layer) {\n  return new ShockWaveDrawer(this, layer,\n                             this._generateShockWaveImage());\n};\n\n\nEffectManager.prototype._generateGrazeDrawer = function(layer) {\n  return new GrazeDrawer(this, layer,\n                         this._generateGrazeImage());\n};\n\n\nEffectManager.prototype._generateExplosionDrawer = function(layer) {\n  return new ExplosionDrawer(this, layer,\n                             this._generateExplosionImage());\n};\n\n\nEffectManager.prototype._generateBigShockWaveDrawer = function(layer) {\n  return new BigShockWaveDrawer(this, layer,\n                                this._generateBigShockWaveImage());\n};\n\n\nEffectManager.prototype._generateBigExplosionDrawer = function(layer) {\n  return new BigExplosionDrawer(this, layer,\n                                this._generateBigExplosionImage());\n};\n\n\nEffectManager.prototype._generateDamageDrawer = function(layer) {\n  return new DamageDrawer(this, layer,\n                          this._generateDamageImage());\n};\n\n\n/**\n * create ShockWaveEffect.\n * TODO: rename or combine with other create methods.\n */\nEffectManager.prototype.create = function(element, type, params) {\n  this.addElement(this.factory.create(element, type, params));\n};\n\n\n/**\n * TODO: temporal. combine with create()?\n */\nEffectManager.prototype.createGraze = function(element, params) {\n  this.addElement(this.factory.createGraze(element, params));\n};\n\n\n/**\n * TODO: temporal. combine with create()?\n */\nEffectManager.prototype.createDamageEffect = function(enemy) {\n  this.addElement(this.factory.createDamageEffect(enemy));\n};\n\n\n/**\n * TODO: temporal. combine with create()?\n */\nEffectManager.prototype.createExplosion = function(enemy) {\n  this.addElement(this.factory.createExplosion(enemy));\n};\n\n\n/**\n * TODO: temporal. combine with create()?\n */\nEffectManager.prototype.createBigShockWave = function(enemy, type, params) {\n  this.addElement(this.factory.createBigShockWave(enemy, type, params));\n};\n\n\n/**\n * TODO: temporal. combine with create()?\n */\nEffectManager.prototype.createBigExplosion = function(enemy) {\n  this.addElement(this.factory.createBigExplosion(enemy));\n};\n\n\n/**\n * TODO: should move into ShockWave?\n */\nEffectManager.prototype._generateShockWaveImage = function() {\n  var cvs = document.createElement('canvas');\n  cvs.width = this.Layer.calculateSquareValue(this.ShockWaveEffect._WIDTH);\n  cvs.height = this.Layer.calculateSquareValue(\n                 this.ShockWaveEffect._HEIGHT*this.ShockWaveEffect._END_COUNT);\n  var ctx = cvs.getContext('2d');\n\n  var w = this.ShockWaveEffect._WIDTH;\n  var h = this.ShockWaveEffect._HEIGHT;\n  for(var i = 0; i < this.ShockWaveEffect._END_COUNT; i++) {\n    var x = w/2;\n    var y = h*i + h/2;\n    var r = this.ShockWaveEffect._SPEED * i;\n    var s = 1 - this.ShockWaveEffect._GRADATION/(this.ShockWaveEffect._SPEED*i);\n\n    if(r <= 1)\n      r = 1;\n    if(s < 0)\n      s = 0.0;\n\n    ctx.beginPath();\n    var g = ctx.createRadialGradient(x, y, 0, x, y, r);\n    g.addColorStop(s, 'rgba(255, 255, 255, 0.0)');\n    g.addColorStop(1.00, 'rgba(255, 255, 255, 1.0)');\n    ctx.fillStyle = g;\n    ctx.arc(x, y, r, 0, this.Math.PI * 2);\n    ctx.fill();\n  }\n  return cvs;\n};\n\n\n/**\n * TODO: should move into Graze?\n */\nEffectManager.prototype._generateGrazeImage = function() {\n  var cvs = document.createElement('canvas');\n  cvs.width = this.Layer.calculateSquareValue(this.GrazeEffect._SIZE);\n  cvs.height = this.Layer.calculateSquareValue(this.GrazeEffect._SIZE);\n  var ctx = cvs.getContext('2d');\n\n  var w = this.GrazeEffect._SIZE;\n  var h = this.GrazeEffect._SIZE;\n  ctx.fillStyle = 'rgb(255, 255, 255)';\n  ctx.fillRect(0, 0, w, h);\n  return cvs;\n};\n\n\n/**\n * TODO: should move into Explosion?\n */\nEffectManager.prototype._generateExplosionImage = function() {\n  var cvs = document.createElement('canvas');\n  cvs.width = this.Layer.calculateSquareValue(this.ExplosionEffect._WIDTH);\n  cvs.height = this.Layer.calculateSquareValue(\n                 this.ExplosionEffect._HEIGHT*this.ExplosionEffect._END_COUNT);\n  var ctx = cvs.getContext('2d');\n\n  var w = this.ExplosionEffect._WIDTH;\n  var h = this.ExplosionEffect._HEIGHT;\n  for(var i = 0; i < this.ExplosionEffect._END_COUNT; i++) {\n    var x = w/2;\n    var y = h*i + h/2;\n    var r = w/2 * i/this.ExplosionEffect._END_COUNT - 2;\n    if(r <= 1)\n      r = 1;\n\n    ctx.beginPath();\n    ctx.fillStyle = 'rgb(255, 255, 255)';\n    ctx.globalAlpha = 0.5;\n    ctx.arc(x, y, r, 0, this.Math.PI * 2);\n    ctx.fill();\n\n    ctx.beginPath();\n    ctx.strokeStyle = 'rgb(255, 255, 255)';\n    ctx.globalAlpha = 1;\n    ctx.lineWidth = 4;\n    ctx.arc(x, y, r, 0, this.Math.PI * 2);\n    ctx.stroke();\n  }\n  return cvs;\n};\n\n\n/**\n * TODO: should move into DamageEffect?\n */\nEffectManager.prototype._generateDamageImage = function() {\n  var cvs = document.createElement('canvas');\n  cvs.width = this.Layer.calculateSquareValue(this.DamageEffect._WIDTH);\n  cvs.height = this.Layer.calculateSquareValue(this.DamageEffect._HEIGHT);\n  var ctx = cvs.getContext('2d');\n\n  var w = this.DamageEffect._WIDTH;\n  var h = this.DamageEffect._HEIGHT;\n  var x = w/2;\n  var y = h/2;\n  var r = w/2-4;\n\n  ctx.beginPath();\n  ctx.fillStyle = 'rgb(255, 255, 255)';\n  ctx.globalAlpha = 0.5;\n  ctx.arc(x, y, r, 0, this.Math.PI * 2);\n  ctx.fill();\n\n  return cvs;\n};\n\n\n/**\n * TODO: should move into BigShockWave?\n * TODO: can share the logic with _generateShockWaveImage()?\n */\nEffectManager.prototype._generateBigShockWaveImage = function() {\n  var cvs = document.createElement('canvas');\n  cvs.width = this.Layer.calculateSquareValue(this.BigShockWaveEffect._WIDTH);\n  cvs.height = this.Layer.calculateSquareValue(this.BigShockWaveEffect._HEIGHT);\n  var ctx = cvs.getContext('2d');\n\n  var w = this.BigShockWaveEffect._WIDTH;\n  var h = this.BigShockWaveEffect._HEIGHT;\n  var x = w/2;\n  var y = h/2;\n  var r = w/2;\n  // TODO: remove magic numbers.\n  var s = 1 - (5*4)/(10*10);\n\n  if(r <= 1)\n    r = 1;\n  if(s < 0)\n    s = 0.0;\n\n  ctx.beginPath();\n  var g = ctx.createRadialGradient(x, y, 0, x, y, r);\n  // TODO: bad to get params from other class.\n  g.addColorStop(s, 'rgba(255, 255, 255, 0.0)');\n  g.addColorStop(1.00, 'rgba(255, 255, 255, 1.0)');\n  ctx.fillStyle = g;\n  ctx.arc(x, y, r, 0, this.Math.PI * 2);\n  ctx.fill();\n  return cvs;\n};\n\n\n/**\n * TODO: should move into BigExplosion?\n */\nEffectManager.prototype._generateBigExplosionImage = function() {\n  var cvs = document.createElement('canvas');\n  cvs.width = this.Layer.calculateSquareValue(this.BigExplosionEffect._WIDTH);\n  cvs.height = this.Layer.calculateSquareValue(this.BigExplosionEffect._HEIGHT);\n  var ctx = cvs.getContext('2d');\n\n  var w = this.BigExplosionEffect._WIDTH;\n  var h = this.BigExplosionEffect._HEIGHT;\n  var x = w/2;\n  var y = h/2;\n  var r = w/2 - 2;\n\n  ctx.beginPath();\n  ctx.fillStyle = 'rgb(255, 255, 255)';\n  ctx.globalAlpha = 0.5;\n  ctx.arc(x, y, r, 0, this.Math.PI * 2);\n  ctx.fill();\n\n  ctx.beginPath();\n  ctx.strokeStyle = 'rgb(255, 255, 255)';\n  ctx.globalAlpha = 1;\n  ctx.lineWidth = 4;\n  ctx.arc(x, y, r, 0, this.Math.PI * 2);\n  ctx.stroke();\n  return cvs;\n};\n\n\nEffectManager.prototype.draw = function(layer) {\n  for(var i = 0; i < this.drawers.length; i++) {\n    this.drawers[i].draw(layer);\n  }\n};\n\n\n\nfunction EffectFactory(gameState, maxX, maxY) {\n  this.parent = ElementFactory;\n  this.grazeFreelist = null;\n  this.damageFreelist = null;\n  this.explosionFreelist = null;\n  this.bShockWaveFreelist = null;\n  this.bExplosionFreelist = null;\n  this.parent.call(this, gameState, maxX, maxY);\n  this.image = null;\n} ;\n__inherit(EffectFactory, ElementFactory);\n\nEffectFactory.prototype._SHOCKWAVE_NUM = 200 ;\nEffectFactory.prototype._GRAZE_NUM = 200 ;\nEffectFactory.prototype._DAMAGE_NUM = 200;\nEffectFactory.prototype._EXPLOSION_NUM = 200;\nEffectFactory.prototype._BIG_SHOCKWAVE_NUM = 10;\nEffectFactory.prototype._BIG_EXPLOSION_NUM = 10;\n\n\n// TODO: temporal\nEffectFactory.prototype._PARAMS = [\n {'w': 4, 'g': 5, 'a': 0.1, 'b': 10, 'endCount': 10, 'default': true},\n {'x': 0, 'y': 0}\n];\n\n\nEffectFactory.prototype._initFreelist = function() {\n  this.freelist = new ShockWaveEffectFreeList(this._SHOCKWAVE_NUM,\n                                              this.gameState);\n  this.grazeFreelist = new GrazeEffectFreeList(this._GRAZE_NUM,\n                                              this.gameState);\n  this.damageFreelist = new DamageEffectFreeList(this._DAMAGE_NUM,\n                                                 this.gameState);\n  this.explosionFreelist = new ExplosionEffectFreeList(\n                                 this._EXPLOSION_NUM, this.gameState);\n  this.bShockWaveFreelist = new BigShockWaveEffectFreeList(\n                                  this._BIG_SHOCKWAVE_NUM,\n                                  this.gameState);\n  this.bExplosionFreelist = new BigExplosionEffectFreeList(\n                                  this._BIG_EXPLOSION_NUM,\n                                  this.gameState);\n};\n\n\n/**\n *\n */\nEffectFactory.prototype.create = function( element, type, params ) {\n  // TODO: temporal\n  if( ! params )\n    params = this._PARAMS[0];\n\n  params.x = element.getX( ) ;\n  params.y = element.getY( ) ;\n\n  var effect = this.freelist.get( ) ;\n  effect.init( params, this._getImage( params ), element ) ;\n  return effect ;\n} ;\n\n\n/**\n * TODO: temporal. combine this method with create( )?\n */\nEffectFactory.prototype.createGraze = function(fighter, bullet) {\n  params = this._PARAMS[1];\n\n  params.x = fighter.getX();\n  params.y = fighter.getY();\n\n  var effect = this.grazeFreelist.get();\n  effect.init(params, this._getImage(params), fighter, bullet);\n  return effect;\n};\n\n\n/**\n * TODO: temporal. combine this method with create( )?\n */\nEffectFactory.prototype.createDamageEffect = function(enemy) {\n  var effect = this.damageFreelist.get();\n  effect.init(enemy, this.gameState.getImage(Game._IMG_DAMAGE), enemy);\n  return effect;\n};\n\n\n/**\n * TODO: temporal. combine this method with create( )?\n */\nEffectFactory.prototype.createExplosion = function(enemy) {\n  var effect = this.explosionFreelist.get();\n  effect.init(enemy, this.gameState.getImage(Game._IMG_VANISHED), enemy);\n  return effect;\n};\n\n\n/**\n * TODO: temporal. combine this method with create( )?\n */\nEffectFactory.prototype.createBigShockWave = function(element, type, params) {\n  params.x = element.getX();\n  params.y = element.getY();\n\n  var effect = this.bShockWaveFreelist.get();\n  effect.init(params, this._getImage(params), element);\n  return effect;\n};\n\n\n/**\n * TODO: temporal. combine this method with create( )?\n */\nEffectFactory.prototype.createBigExplosion = function(enemy) {\n  var effect = this.bExplosionFreelist.get();\n  effect.init(enemy, this.gameState.getImage(Game._IMG_VANISHED), enemy);\n  return effect;\n};\n\n\nEffectFactory.prototype.free = function(element) {\n  switch(element._ID) {\n    case this.EffectManager._ID_GRAZE:\n      this.grazeFreelist.free(element);\n      return;\n    case this.EffectManager._ID_DAMAGE:\n      this.damageFreelist.free(element);\n      return;\n    case this.EffectManager._ID_EXPLOSION:\n      this.explosionFreelist.free(element);\n      return;\n    case this.EffectManager._ID_BIG_SHOCKWAVE:\n      this.bShockWaveFreelist.free(element);\n      return;\n    case this.EffectManager._ID_BIG_EXPLOSION:\n      this.bExplosionFreelist.free(element);\n      return;\n    default: // this.EffectManager._ID_SHOCKWAVE:\n      this.freelist.free(element);\n      return;\n  }\n};\n\n\n/**\n * TODO: temporal\n */\nEffectFactory.prototype._getImage = function(params) {\n  if(this.image === null)\n    this.image = this.gameState.getImage(Game._IMG_SHOCK_WAVE);\n  return this.image;\n};\n\n\n\nfunction ShockWaveEffectFreeList( num, gameState ) {\n  this.parent = ElementFreeList ;\n  this.parent.call( this, num, gameState ) ;\n}\n__inherit( ShockWaveEffectFreeList, ElementFreeList ) ;\n\n\nShockWaveEffectFreeList.prototype._generateElement = function( ) {\n  return new ShockWaveEffect( this.gameState,\n                              this.gameState.getWidth( ),\n                              this.gameState.getHeight( ) ) ;\n} ;\n\n\n\nfunction ShockWaveDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(ShockWaveDrawer, ElementDrawer);\n\n\nShockWaveDrawer.prototype._doPour = function(e) {\n  return (e._ID === this.elementManager._ID_SHOCKWAVE);\n};\n\n\n\nfunction ShockWaveView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n  this.a = 0.1;\n};\n__inherit(ShockWaveView, ElementView);\n\n\nShockWaveView.prototype.animate = function() {\n  this._initCoordinates();\n};\n\n\nShockWaveView.prototype.rotate = function() {\n};\n\n\nShockWaveView.prototype.doRotateForViewpoint = function() {\n  return true;\n};\n\n\n\n/**\n * This class is for small shockwave like the one\n * it shows when enemy is destroyed.\n */\nfunction ShockWaveEffect( gameState, maxX, maxY ) {\n  this.parent = Element ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n  this.element = null ;\n  this.w = null ;\n  this.g = null ;\n  this.a = null ;\n  this.b = null ;\n  this.default = null;\n  this.endCount = null ;\n  this.preCanvas = this._PRE_CANVAS;\n}\n__inherit( ShockWaveEffect, Element ) ;\n\n// only for reference\nShockWaveEffect.prototype.Math = Math;\n\nShockWaveEffect.prototype._WIDTH = 200;\nShockWaveEffect.prototype._HEIGHT = 200;\nShockWaveEffect.prototype._END_COUNT = 10;\n\nShockWaveEffect.prototype._GRADATION = 20;\nShockWaveEffect.prototype._SPEED = 10;\n\nShockWaveEffect.prototype._PRE_CANVAS = []; /* temporal */\nShockWaveEffect.prototype._INNER_COLOR = 'rgba(255, 255, 255, 0.0)';\nShockWaveEffect.prototype._OUTER_COLORS = [\n  'rgba(255, 255, 255, 0.0)',\n  'rgba(255, 255, 255, 0.1)',\n  'rgba(255, 255, 255, 0.2)',\n  'rgba(255, 255, 255, 0.3)',\n  'rgba(255, 255, 255, 0.4)',\n  'rgba(255, 255, 255, 0.5)',\n  'rgba(255, 255, 255, 0.6)',\n  'rgba(255, 255, 255, 0.7)',\n  'rgba(255, 255, 255, 0.8)',\n  'rgba(255, 255, 255, 0.9)',\n  'rgba(255, 255, 255, 1.0)',\n];\n\n\n__copyParentMethod(ShockWaveEffect, Element, 'init');\nShockWaveEffect.prototype.init = function(params, image, element) {\n  this.Element_init(params, image);\n  this.element = element;\n  this.width = this._WIDTH;\n  this.height = this._HEIGHT;\n  this.w = params.w;\n  this.g = params.g;\n  this.a = params.a;\n  this.b = params.b;\n  this.default = params.default;\n  this.endCount = this._calculateEndCount(params.endCount);\n  this._initView();\n};\n\n\nShockWaveEffect.prototype._generateView = function() {\n  return new ShockWaveView(this);\n};\n\n\nShockWaveEffect.prototype._calculateEndCount = function(count) {\n\n  if(this.default || count * this.b < this.gameState.getWidth() / 2)\n    return count;\n\n  var x = this.getX();\n  var y = this.getY();\n  if(x < this.gameState.getWidth() / 2)\n    x = this.gameState.getWidth() - x;\n  if(y < this.gameState.getHeight() / 2)\n    y = this.gameState.getHeight() - y;\n  var r = (this.Math.sqrt(x*x + y*y) | 0);\n  var count2 = ((r / this.b) | 0) + this.g;\n\n  return (count2 < count) ? count2 : count;\n\n};\n\n\nShockWaveEffect.prototype.display = function(surface) {\n\n  if(this.default) {\n    this._displayDefault(surface);\n    return;\n  }\n\n  var x = Math.round(this.getX());\n  var y = Math.round(this.getY());\n\n  surface.save();\n  this._display(surface, x, y);\n  surface.restore();\n\n//  surface.fillText( x + ':' + y, x, y ) ;\n} ;\n\n\n/**\n * display with pre-rendering.\n */\nShockWaveEffect.prototype._displayDefault = function(surface) {\n  var x = Math.round(this.getX());\n  var y = Math.round(this.getY());\n  var r = this.count * this.b;\n\n  if(this.preCanvas[this.count] == undefined) {\n    var cvs = document.createElement('canvas')\n    cvs.width = r*2 + this.w;\n    cvs.height = r*2 + this.w;\n    var ctx = cvs.getContext('2d');\n    this._display(ctx, r+this.w/2, r+this.w/2);\n    this.preCanvas[this.count] = cvs;\n  }\n  surface.drawImage(this.preCanvas[this.count], x-r-this.w/2, y-r-this.w/2);\n};\n\n\nShockWaveEffect.prototype._display = function(surface, x, y) {\n  var r = this.count * this.b;\n  if(r <= 0)\n    return;\n  var s = 1 - (this.g*this.w)/(this.count*this.b);\n  if(s < 0)\n    s = 0.0;\n  var g = surface.createRadialGradient(x, y, 0, x, y, r);\n  g.addColorStop(s, ShockWaveEffect._INNER_COLOR);\n  g.addColorStop(1.00, ShockWaveEffect._OUTER_COLORS[parseInt(this.a*10)]);\n  surface.beginPath();\n  surface.fillStyle = g;\n  surface.arc(x, y, r, 0, Math.PI * 2);\n  surface.fill();\n};\n\n\nShockWaveEffect.prototype.checkLoss = function( ) {\n  return this.count > this.endCount ? true : false ;\n} ;\n\n\nShockWaveEffect.prototype.getImageIndexX = function() {\n  return 0;\n};\n\n\nShockWaveEffect.prototype.getImageIndexY = function() {\n  return this.count;\n};\n\n\n/**\n * TODO: temporal\n */\nShockWaveEffect.prototype.getImageWidth = function() {\n  return 256;\n};\n\n\n/**\n * TODO: temporal\n */\nShockWaveEffect.prototype.getImageHeight = function() {\n  return 2048;\n};\n\n\n\nfunction BigShockWaveEffectFreeList(num, gameState) {\n  this.parent = ElementFreeList;\n  this.parent.call(this, num, gameState);\n}\n__inherit(BigShockWaveEffectFreeList, ElementFreeList);\n\n\nBigShockWaveEffectFreeList.prototype._generateElement = function() {\n  return new BigShockWaveEffect(this.gameState,\n                                this.gameState.getWidth(),\n                                this.gameState.getHeight());\n};\n\n\n\nfunction BigShockWaveDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(BigShockWaveDrawer, ElementDrawer);\n\n\nBigShockWaveDrawer.prototype._doPour = function(e) {\n  return (e._ID === this.elementManager._ID_BIG_SHOCKWAVE);\n};\n\n\n\nfunction BigShockWaveView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(BigShockWaveView, ElementView);\n\n\nBigShockWaveView.prototype.animate = function() {\n  this.a = this.element.a;\n\n  var w = this.element.b * this.element.count;\n  var h = this.element.b * this.element.count;\n\n  this.vertices[0]  = -w;\n  this.vertices[1]  = -h;\n  this.vertices[2]  = -1.0;\n  this.vertices[3]  =  w;\n  this.vertices[4]  = -h;\n  this.vertices[5]  = -1.0;\n  this.vertices[6]  =  w;\n  this.vertices[7]  =  h;\n  this.vertices[8]  = -1.0;\n  this.vertices[9]  = -w;\n  this.vertices[10] =  h;\n  this.vertices[11] = -1.0;\n};\n\n\nBigShockWaveView.prototype.rotate = function() {\n};\n\n\n\nfunction BigShockWaveEffect(gameState, maxX, maxY) {\n  this.parent = Element;\n  this.parent.call(this, gameState, maxX, maxY);\n  this.element = null;\n  this.w = null;\n  this.g = null;\n  this.a = null;\n  this.b = null;\n  this.default = null;\n  this.endCount = null;\n}\n__inherit(BigShockWaveEffect, Element);\n\n// only for reference\nBigShockWaveEffect.prototype.Math = Math;\n\nBigShockWaveEffect.prototype._WIDTH = 512;\nBigShockWaveEffect.prototype._HEIGHT = 512;\n\n\n__copyParentMethod(BigShockWaveEffect, Element, 'init');\nBigShockWaveEffect.prototype.init = function(params, image, element) {\n  this.Element_init(params, image);\n  this.element = element;\n  this.width = 512;\n  this.height = 512;\n  this.w = params.w;\n  this.g = params.g;\n  this.a = params.a;\n  this.b = params.b;\n  this.default = params.default;\n  this.endCount = this._calculateEndCount(params.endCount);\n  this._initView();\n};\n\n\nBigShockWaveEffect.prototype._generateView = function() {\n  return new BigShockWaveView(this);\n};\n\n\nBigShockWaveEffect.prototype._calculateEndCount = function(count) {\n\n  if(this.default || count * this.b < this.gameState.getWidth() / 2)\n    return count;\n\n  var x = this.getX();\n  var y = this.getY();\n  if(x < this.gameState.getWidth() / 2)\n    x = this.gameState.getWidth() - x;\n  if(y < this.gameState.getHeight() / 2)\n    y = this.gameState.getHeight() - y;\n  var r = (this.Math.sqrt(x*x + y*y) | 0);\n  var count2 = ((r / this.b) | 0) + this.g;\n\n  return (count2 < count) ? count2 : count;\n\n};\n\n\nBigShockWaveEffect.prototype.checkLoss = function( ) {\n  return this.count > this.endCount ? true : false ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nBigShockWaveEffect.prototype.getImageWidth = function() {\n  return 512;\n};\n\n\n/**\n * TODO: temporal\n */\nBigShockWaveEffect.prototype.getImageHeight = function() {\n  return 512;\n};\n\n\n\nfunction ExplosionEffectFreeList(num, gameState) {\n  this.parent = ElementFreeList;\n  this.parent.call(this, num, gameState);\n};\n__inherit(ExplosionEffectFreeList, ElementFreeList);\n\n\nExplosionEffectFreeList.prototype._generateElement = function() {\n  return new ExplosionEffect(this.gameState, this.gameState.getWidth(),\n                             this.gameState.getHeight());\n};\n\n\n\nfunction ExplosionDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(ExplosionDrawer, ElementDrawer);\n\n\nExplosionDrawer.prototype._doPour = function(e) {\n  return (e._ID === this.elementManager._ID_EXPLOSION);\n};\n\n\n\nfunction ExplosionView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(ExplosionView, ElementView);\n\n\nExplosionView.prototype.animate = function() {\n  this._initCoordinates();\n  this.a = (this.element._END_COUNT - this.element.count + 1)/\n             this.element._END_COUNT;\n};\n\n\nExplosionView.prototype.rotate = function() {\n};\n\n\nExplosionView.prototype.doRotateForViewpoint = function() {\n  return true;\n};\n\n\n\nfunction ExplosionEffect(gameState, maxX, maxY) {\n  this.parent = Element;\n  this.parent.call(this, gameState, maxX, maxY);\n  this.preCanvas = this._PRE_CANVAS;\n}\n__inherit(ExplosionEffect, Element);\n\nExplosionEffect.prototype._WIDTH = 64 ;\nExplosionEffect.prototype._HEIGHT = 64 ;\nExplosionEffect.prototype._END_COUNT = 10;\nExplosionEffect.prototype._PRE_CANVAS = []; /* TODO: temporal */\n\n\n__copyParentMethod(ExplosionEffect, Element, 'init');\nExplosionEffect.prototype.init = function(params, image, enemy) {\n  this.Element_init(params, image);\n  this.setX(enemy.getX());\n  this.setY(enemy.getY());\n  this.width  = this._WIDTH;\n  this.height = this._HEIGHT;\n  this.collisionWidth  = this.width;\n  this.collisionHeight = this.height;\n  this.indexX = 0;\n  this.indexY = 1;\n  this._initView();\n};\n\n\nExplosionEffect.prototype._generateView = function() {\n  return new ExplosionView(this);\n};\n\n\n/**\n * TODO: temporal\n */\nExplosionEffect.prototype.display = function(surface) {\n  var x = Math.round(this.getX());\n  var y = Math.round(this.getY());\n  var r = Math.round(this.width * this.count * 0.1);\n\n  if(this.preCanvas[this.count] == undefined) {\n    var cvs = document.createElement('canvas')\n    cvs.width = r*2 + 4;\n    cvs.height = r*2 + 4;\n    var ctx = cvs.getContext('2d');\n\n    ctx.beginPath();\n    ctx.fillStyle = 'rgb(255, 255, 255)';\n    ctx.globalAlpha = (ExplosionEffect._END_COUNT - this.count + 1) * 0.05;\n    ctx.arc(r+2, r+2, r, 0, Math.PI * 2);\n    ctx.fill();\n\n    ctx.beginPath();\n    ctx.strokeStyle = 'rgb(255, 255, 255)';\n    ctx.globalAlpha = (ExplosionEffect._END_COUNT - this.count + 1) * 0.1;\n    ctx.lineWidth = 3;\n    ctx.arc(r+2, r+2, r, 0, Math.PI * 2);\n    ctx.stroke();\n\n    this.preCanvas[this.count] = cvs;\n  }\n  surface.drawImage(this.preCanvas[this.count], x-r-2, y-r-2);\n\n//  surface.fillText( x + ':' + y, x, y ) ;\n};\n\n\nExplosionEffect.prototype.checkLoss = function() {\n  return this.count > this._END_COUNT ? true : false;\n};\n\n\nExplosionEffect.prototype.getImageIndexX = function() {\n  return 0;\n};\n\n\nExplosionEffect.prototype.getImageIndexY = function() {\n  return this.count;\n};\n\n\n/**\n * TODO: temporal\n */\nExplosionEffect.prototype.getImageWidth = function() {\n  return 64;\n};\n\n\n/**\n * TODO: temporal\n */\nExplosionEffect.prototype.getImageHeight = function() {\n  return 1024;\n};\n\n\n\nfunction GrazeDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(GrazeDrawer, ElementDrawer);\n\n\nGrazeDrawer.prototype._doPour = function(e) {\n  return (e._ID === this.elementManager._ID_GRAZE);\n};\n\n\n\nfunction GrazeView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n  this.a = 0.1;\n};\n__inherit(GrazeView, ElementView);\n\n\nGrazeView.prototype.animate = function() {\n  this.a = 1.0 - this.element.count/this.element._END_COUNT;\n};\n\n\nGrazeView.prototype.rotate = function() {\n};\n\n\n\nfunction GrazeEffectFreeList(num, gameState) {\n  this.parent = ElementFreeList ;\n  this.parent.call(this, num, gameState);\n}\n__inherit(GrazeEffectFreeList, ElementFreeList);\n\n\nGrazeEffectFreeList.prototype._generateElement = function() {\n  return new GrazeEffect(this.gameState,\n                         this.gameState.getWidth(),\n                         this.gameState.getHeight());\n};\n\n\n\nfunction GrazeEffect(gameState, maxX, maxY) {\n  this.parent = Element;\n  this.parent.call(this, gameState, maxX, maxY);\n  this.element = null;\n  this.theta = 0;\n}\n__inherit(GrazeEffect, Element);\n\n// only for reference\nGrazeEffect.prototype.Math = Math;\n\nGrazeEffect.prototype._END_COUNT = 20;\nGrazeEffect.prototype._SPAN = 4;\nGrazeEffect.prototype._SIZE = 4;\nGrazeEffect.prototype._FLUCTUATION = 30;\nGrazeEffect.prototype._GAP = 5;\n\n\nGrazeEffect.prototype._generateView = function() {\n  return new GrazeView(this);\n};\n\n\n__copyParentMethod(GrazeEffect, Element, 'init');\nGrazeEffect.prototype.init = function(params, image, element, bullet) {\n\n  this.Element_init(params, image);\n\n  this.element = element;\n\n  this.width = this._SIZE;\n  this.height = this._SIZE;\n\n  if(bullet.getVelocity()) {\n    this.theta = bullet.getTheta();\n  } else {\n    var ax = this.element.getCenterX() - bullet.getCenterX();\n    var ay = this.element.getCenterY() - bullet.getCenterY();\n    this.theta = this._calculateTheta(this.Math.atan2(ay, ax));\n  }\n  // TODO: temporal\n  this.theta += this.gameState.count % this._FLUCTUATION\n                - this._FLUCTUATION/2;\n\n  // TODO: temporal\n  for(var i = 0; i < this._GAP; i++)\n    this.move();\n\n  this._initView();\n};\n\n\n/**\n * TODO: use MoveVector?\n */\nGrazeEffect.prototype.move = function() {\n  var x = this.getX();\n  var y = this.getY();\n  x = x + this.Math.cos(this._calculateRadian(this.theta))\n            * this._SPAN;\n  y = y + this.Math.sin(this._calculateRadian(this.theta))\n            * this._SPAN;\n  this.setX(x);\n  this.setY(y);\n};\n\n\nGrazeEffect.prototype.display = function(surface) {\n  var x = Math.round(this.getX());\n  var y = Math.round(this.getY());\n  surface.save();\n  surface.globalAlpha = 1.0 - this.count/GrazeEffect._END_COUNT;\n  surface.fillRect(x-GrazeEffect._SIZE/2, y-GrazeEffect._SIZE/2,\n                   GrazeEffect._SIZE, GrazeEffect._SIZE);\n  surface.restore();\n\n//  surface.fillText( x + ':' + y, x, y ) ;\n} ;\n\n\nGrazeEffect.prototype.checkLoss = function() {\n  return this.count > this._END_COUNT ? true : false;\n};\n\n\n/**\n * TODO: temporal\n */\nGrazeEffect.prototype.getImageWidth = function() {\n  return this._SIZE;\n};\n\n\n/**\n * TODO: temporal\n */\nGrazeEffect.prototype.getImageHeight = function() {\n  return this._SIZE;\n};\n\n\n\nfunction DamageEffectFreeList( num, gameState ) {\n  this.parent = ElementFreeList ;\n  this.parent.call( this, num, gameState ) ;\n} ;\n__inherit( DamageEffectFreeList, ElementFreeList ) ;\n\n\nDamageEffectFreeList.prototype._generateElement = function( ) {\n  return new DamageEffect( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\n\nfunction DamageDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(DamageDrawer, ElementDrawer);\n\n\nDamageDrawer.prototype._doPour = function(e) {\n  return (e._ID === this.elementManager._ID_DAMAGE);\n};\n\n\n\nfunction DamageView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(DamageView, ElementView);\n\n\nDamageView.prototype.animate = function() {\n  this.a = (this.element._END_COUNT - this.element.count + 1) * 0.02;\n};\n\n\nDamageView.prototype.rotate = function() {\n};\n\n\nDamageView.prototype.doRotateForViewpoint = function() {\n  return true;\n};\n\n\n\nfunction DamageEffect( gameState, maxX, maxY ) {\n  this.parent = Element ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n  this.enemy = null ;\n  this.dx = 0 ;\n  this.dy = 0 ;\n}\n__inherit( DamageEffect, Element ) ;\n\n// only for reference\nDamageEffect.prototype.Math = Math;\nDamageEffect.prototype.Randomizer = __randomizer;\n\nDamageEffect.prototype._WIDTH = 64 ;\nDamageEffect.prototype._HEIGHT = 64 ;\nDamageEffect.prototype._END_COUNT = 2;\n\n\n__copyParentMethod(DamageEffect, Element, 'init');\nDamageEffect.prototype.init = function(params, image, enemy) {\n  this.Element_init(params, image);\n  this.enemy = enemy;\n  this.setX(enemy.getX());\n  this.setY(enemy.getY());\n  this.width  = this._WIDTH;\n  this.height = this._HEIGHT;\n  this.collisionWidth  = this.width;\n  this.collisionHeight = this.height;\n  this.indexX = 0;\n  this.indexY = 0;\n\n  // TODO: temporal\n  var tmp = 32;\n  this.dx = -tmp/2 + (this.Math.pow(this.gameState.count, 2)%32);\n  this.dy = -tmp/2 + (this.Math.pow(this.gameState.count, 2)%32);\n\n  this._initView();\n};\n\n\nDamageEffect.prototype._generateView = function() {\n  return new DamageView(this);\n};\n\n\n/**\n * TODO: temporal\n */\n__copyParentMethod(DamageEffect, Element, 'runStep');\nDamageEffect.prototype.runStep = function() {\n  var tmp = 32;\n  this.dx = -tmp / 2 + ((this.Randomizer.random() * tmp) | 0);\n  this.dy = -tmp / 2 + ((this.Randomizer.random() * tmp) | 0);\n  this.Element_runStep();\n};\n\n\n__copyParentMethod(DamageEffect, Element, 'getX');\nDamageEffect.prototype.getX = function() {\n  return this.Element_getX() + this.dx;\n};\n\n\n__copyParentMethod(DamageEffect, Element, 'getY');\nDamageEffect.prototype.getY = function() {\n  return this.Element_getY() + this.dy;\n};\n\n\n/**\n * TODO: temporal\n */\nDamageEffect.prototype.display = function( surface ) {\n  surface.save( ) ;\n  var x = Math.round( this.getLeftX( ) + this.dx ) ;\n  var y = Math.round( this.getUpY( )   + this.dy ) ;\n  var width  = this.getWidth( ) ;\n  var height = this.getHeight( ) ;\n  surface.globalAlpha = ( 3 - this.count ) * 0.1 ;\n  surface.drawImage( this.image,\n                     this.width  * this.indexX,\n                     this.height * this.indexY + 32 * 13,\n                     this.width,                this.height,\n                     x,                         y,\n                     width,                     height ) ;\n  surface.restore( ) ;\n//  surface.fillText( x + ':' + y, x, y ) ;\n} ;\n\n\nDamageEffect.prototype.checkLoss = function( ) {\n  return this.count > 2 ? true : false ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nDamageEffect.prototype.getImageWidth = function() {\n  return this._WIDTH;\n};\n\n\n/**\n * TODO: temporal\n */\nDamageEffect.prototype.getImageHeight = function() {\n  return this._HEIGHT;\n};\n\n\n\nfunction BigExplosionEffectFreeList(num, gameState) {\n  this.parent = ElementFreeList;\n  this.parent.call(this, num, gameState);\n};\n__inherit(BigExplosionEffectFreeList, ElementFreeList);\n\n\nBigExplosionEffectFreeList.prototype._generateElement = function() {\n  return new BigExplosionEffect(this.gameState,\n                                this.gameState.getWidth(),\n                                this.gameState.getHeight());\n};\n\n\n\nfunction BigExplosionDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(BigExplosionDrawer, ElementDrawer);\n\n\nBigExplosionDrawer.prototype._doPour = function(e) {\n  return (e._ID === this.elementManager._ID_BIG_EXPLOSION);\n};\n\n\n\nfunction BigExplosionView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(BigExplosionView, ElementView);\n\n\nBigExplosionView.prototype.animate = function() {\n  this.a = (this.element._END_COUNT - this.element.count + 1) /\n             this.element._END_COUNT;\n  var w = 32 * this.element.count * 0.1;\n  var h = 32 * this.element.count * 0.1;\n\n  this.vertices[0]  = -w;\n  this.vertices[1]  = -h;\n  this.vertices[2]  = -1.0;\n  this.vertices[3]  =  w;\n  this.vertices[4]  = -h;\n  this.vertices[5]  = -1.0;\n  this.vertices[6]  =  w;\n  this.vertices[7]  =  h;\n  this.vertices[8]  = -1.0;\n  this.vertices[9]  = -w;\n  this.vertices[10] =  h;\n  this.vertices[11] = -1.0;\n};\n\n\nBigExplosionView.prototype.rotate = function() {\n};\n\n\n\nfunction BigExplosionEffect(gameState, maxX, maxY) {\n  this.parent = Element;\n  this.parent.call(this, gameState, maxX, maxY);\n  this.boss = null;\n};\n__inherit(BigExplosionEffect, Element);\n\nBigExplosionEffect.prototype._WIDTH = 320;\nBigExplosionEffect.prototype._HEIGHT = 320;\n\nBigExplosionEffect.prototype._END_COUNT = 100;\n\n\n__copyParentMethod(BigExplosionEffect, Element, 'init');\nBigExplosionEffect.prototype.init = function(params, image, boss) {\n  this.Element_init(params, image);\n  this.width  = this._WIDTH;\n  this.height = this._HEIGHT;\n  this.collisionWidth  = this.width;\n  this.collisionHeight = this.height;\n  this.boss = boss;\n  this.indexX = 0;\n  this.indexY = 0;\n  this._initView();\n};\n\n\nBigExplosionEffect.prototype._generateView = function() {\n  return new BigExplosionView(this);\n};\n\n\n/**\n * TODO: temporal\n */\nBigExplosionEffect.prototype.display = function(surface) {\n  var x = Math.round(this.getX());\n  var y = Math.round(this.getY());\n  var r = this.width * this.count * 0.1;\n  surface.save();\n  surface.fillStyle = 'rgb(255, 255, 255)';\n  surface.globalAlpha = (BigExplosionEffect._END_COUNT - this.count + 1)\n                          * 0.005;\n  surface.beginPath();\n  surface.arc(x, y, r,  0, Math.PI * 2);\n  surface.fill();\n\n  surface.strokeStyle = 'rgb(255, 255, 255)';\n  surface.globalAlpha = (BigExplosionEffect._END_COUNT - this.count + 1 )\n                          * 0.01;\n  surface.beginPath();\n  surface.arc(x, y, r,  0, Math.PI * 2);\n  surface.lineWidth = 3;\n  surface.stroke();\n  surface.restore();\n\n//  surface.fillText( x + ':' + y, x, y ) ;\n};\n\n\nBigExplosionEffect.prototype.checkLoss = function() {\n  return this.count > this._END_COUNT ? true : false;\n};\n\n\n/**\n * TODO: temporal\n */\nBigExplosionEffect.prototype.getImageWidth = function() {\n  return 512;\n};\n\n\n/**\n * TODO: temporal\n */\nBigExplosionEffect.prototype.getImageHeight = function() {\n  return 512;\n};\n\n\n// TODO: remove the followings because they complicate the design.\n\n// TODO: temporal\n// only for reference\nEffectManager.prototype.ShockWaveEffect = ShockWaveEffect.prototype;\nEffectManager.prototype.BigShockWaveEffect = BigShockWaveEffect.prototype;\nEffectManager.prototype.ExplosionEffect = ExplosionEffect.prototype;\nEffectManager.prototype.GrazeEffect = GrazeEffect.prototype;\nEffectManager.prototype.DamageEffect = DamageEffect.prototype;\nEffectManager.prototype.BigExplosionEffect = BigExplosionEffect.prototype;\n\n// TODO: temporal\n// for _doPour() and free()\nEffectManager.prototype._ID_SHOCKWAVE     = 0;\nEffectManager.prototype._ID_BIG_SHOCKWAVE = 1;\nEffectManager.prototype._ID_EXPLOSION     = 2;\nEffectManager.prototype._ID_GRAZE         = 3;\nEffectManager.prototype._ID_DAMAGE        = 4;\nEffectManager.prototype._ID_BIG_EXPLOSION = 5;\n\nEffectFactory.prototype.EffectManager = EffectManager.prototype;\n\nShockWaveEffect.prototype._ID    = EffectManager.prototype._ID_SHOCKWAVE;\nBigShockWaveEffect.prototype._ID = EffectManager.prototype._ID_BIG_SHOCKWAVE;\nExplosionEffect.prototype._ID    = EffectManager.prototype._ID_EXPLOSION;\nGrazeEffect.prototype._ID        = EffectManager.prototype._ID_GRAZE;\nDamageEffect.prototype._ID       = EffectManager.prototype._ID_DAMAGE;\nBigExplosionEffect.prototype._ID = EffectManager.prototype._ID_BIG_EXPLOSION;\n"
  },
  {
    "path": "source/Element.js",
    "content": "/**\n * TODO: should rename Element to Entity?\n */\nfunction ElementManager(gameState) {\n  this.gameState = gameState;\n  this.elements = [];\n  this.count = 0;\n  this.factory = null;\n  this.drawer = null;\n  this.maxNum = this._initMaxNum();\n  this._initFactory();\n};\n\n\n/**\n * maximum number for WebGL Buffer.\n * TODO: bad design?\n * TODO: rename to _getMaxNum.\n */\nElementManager.prototype._initMaxNum = function() {\n  return 1;\n};\n\n\nElementManager.prototype._initFactory = function( ) {\n  this.factory = new ElementFactory( this.gameStage,\n                                     this.gameState.maxX,\n                                     this.gameState.maxY ) ;\n} ;\n\n\n/**\n * TODO: be private?\n */\nElementManager.prototype.initDrawer = function(layer, image) {\n  this.drawer = new ElementDrawer(this, layer, image);\n};\n\n\nElementManager.prototype.reset = function( ) {\n  for( var i = 0; i < this.elements.length; i++ ) {\n    this.elements[ i ].die( ) ;\n    this.elements[ i ].free( ) ;\n    this.factory.free( this.elements[ i ] ) ;\n  }\n  this.elements.length = 0 ;\n  this.count = 0 ;\n} ;\n\n\nElementManager.prototype.runStep = function() {\n  for(var i = 0, len = this.elements.length; i < len; i++)\n    this.elements[i].runStep();\n  this.count++;\n};\n\n\n/**\n * displays on 2D Canvas\n */\nElementManager.prototype.display = function( surface ) {\n  for( var i = 0; i < this.elements.length; i++ )\n    this.elements[ i ].display( surface ) ;\n} ;\n\n\n/**\n * draws on WebGL layer\n * TODO: rename\n */\nElementManager.prototype.draw = function(layer) {\n  this.drawer.draw(layer);\n};\n\n\nElementManager.prototype.create = function( params ) {\n  this.addElement( this.factory.create( params ) ) ;\n} ;\n\n\n/**\n * TODO: rename to add()\n */\nElementManager.prototype.addElement = function(element) {\n  this.elements[this.elements.length] = element;\n};\n\n\nElementManager.prototype.add = function(element) {\n  this.addElement(element);\n};\n\n\nElementManager.prototype.get = function(index) {\n  return this.elements[index];\n};\n\n\nElementManager.prototype.checkCollisionWith = function(\n    id, element, caller, flag ) {\n  for(var i = 0, len = this.elements.length; i < len; i++) {\n    if(this.elements[i].checkCollision(element)) {\n      caller.notifyCollision(id, element, this.elements[i]);\n      if(flag === true)\n        return ;\n    }\n  }\n};\n\n\n/**\n * TODO: temporal\n */\nElementManager.prototype.checkCollisionWith2 = function(\n    id, element, caller, flag) {\n  for(var i = 0, len = this.elements.length; i < len; i++) {\n    if(element.checkCollision(this.elements[i])) {\n      caller.notifyCollision2(id, element, this.elements[i]);\n      if(flag === true)\n        return;\n    }\n  }\n};\n\n\nElementManager.prototype.checkGrazeWith = function(id, element, caller) {\n  for(var i = 0, len = this.elements.length; i < len; i++) {\n    if(this.elements[i].checkGraze(element)) {\n      caller.notifyGraze(id, element, this.elements[i]);\n    }\n  }\n};\n\n\n/**\n * TODO: temporal. How deletes unnecessary entries?\n */\nElementManager.prototype.checkLoss = function(caller) {\n  var j = 0 ;\n  for(var i = 0, len = this.elements.length; i < len; i++ ) {\n    if( ! this.elements[ i ].checkLoss( ) ) {\n      this.elements[ i - j ] = this.elements[ i ] ;\n    } else {\n      this.elements[ i ].die( ) ;\n      // TODO: temporal\n      if(caller !== void 0)\n        caller.notifyCheckLoss(this.elements[i]);\n      this.elements[ i ].free( ) ;\n      this.factory.free( this.elements[ i ] ) ;\n      j++ ;\n    }\n  }\n  this.elements.length -= j ;\n}\n\n\nElementManager.prototype.getNum = function() {\n  return this.elements.length;\n};\n\n\nElementManager.prototype.getMaxNum = function() {\n  return this.maxNum;\n};\n\n\nfunction ElementFactory( gameState, maxX, maxY ) {\n  this.gameState = gameState ;\n  this.maxX = maxX ;\n  this.maxY = maxY ;\n  this.freelist = null ;\n  this._initFreelist( ) ;\n} ;\n\nElementFactory.prototype._NUM = 100 ;\n\n\nElementFactory.prototype._initFreelist = function() {\n  this.freelist = new ElementFreeList(this._NUM, this.gameState); \n};\n\n\nElementFactory.prototype.create = function( params ) {\n  var element = this.freelist.get( ) ;\n  element.init( params, this._getImage( params ) ) ;\n  return element ;\n} ;\n\n\nElementFactory.prototype.free = function( element ) {\n  this.freelist.free( element ) ;\n} ;\n\n\n/**\n * Child process must override this method.\n */\nElementFactory.prototype._getImage = function( params ) {\n  return new Image( ) ;\n} ;\n\n\n/**\n * TODO: list may should be Linked list if num is large.\n */\nfunction ElementFreeList( num, gameState ) {\n  this.gameState = gameState ;\n  FreeList.call( this, num ) ;\n}\n__inherit( ElementFreeList, FreeList ) ;\n\n\n/**\n * Child class must override this method.\n */\nElementFreeList.prototype._generateElement = function( ) {\n  return new Element( this.gameState, this.gameState.maxX, this.gameState.maxY ) ;\n} ;\n\n\n/**\n * This class has position and parameters of Element for WebGL.\n * They're used by ElementDrawer.\n * Note that this class doesn't have image and texture.\n * ElementDrawer has them.\n */\nfunction ElementView(element) {\n  this.element = element;\n  this.a = 1.0;\n  this.d = 1.0;\n  this.vertices = [];\n  this.coordinates = [];\n  this.indices = [];\n  this.colors = [];\n  this.sVertices = [];\n  this.vertices.length    = this._V_SIZE;\n  this.coordinates.length = this._C_SIZE;\n  this.indices.length     = this._I_SIZE;\n  this.colors.length      = this._A_SIZE;\n  this.sVertices.length   = this._V_SIZE;\n};\n\n// only for reference\nElementView.prototype.Math = Math;\n\nElementView.prototype._V_ITEM_SIZE = 3;\nElementView.prototype._V_ITEM_NUM = 4;\nElementView.prototype._V_SIZE = ElementView.prototype._V_ITEM_SIZE * ElementView.prototype._V_ITEM_NUM;\n\nElementView.prototype._C_ITEM_SIZE = 2;\nElementView.prototype._C_ITEM_NUM = 4;\nElementView.prototype._C_SIZE = ElementView.prototype._C_ITEM_SIZE * ElementView.prototype._C_ITEM_NUM;\n\nElementView.prototype._I_ITEM_SIZE = 1;\nElementView.prototype._I_ITEM_NUM = 6;\nElementView.prototype._I_SIZE = ElementView.prototype._I_ITEM_SIZE * ElementView.prototype._I_ITEM_NUM;\n\nElementView.prototype._A_ITEM_SIZE = 4;\nElementView.prototype._A_ITEM_NUM = 4;\nElementView.prototype._A_SIZE = ElementView.prototype._A_ITEM_SIZE * ElementView.prototype._A_ITEM_NUM;\n\n// TODO: temporal\nElementView._V_ITEM_SIZE = 3;\nElementView._V_ITEM_NUM = 4;\nElementView._V_SIZE = ElementView._V_ITEM_SIZE * ElementView._V_ITEM_NUM;\n\nElementView._C_ITEM_SIZE = 2;\nElementView._C_ITEM_NUM = 4;\nElementView._C_SIZE = ElementView._C_ITEM_SIZE * ElementView._C_ITEM_NUM;\n\nElementView._I_ITEM_SIZE = 1;\nElementView._I_ITEM_NUM = 6;\nElementView._I_SIZE = ElementView._I_ITEM_SIZE * ElementView._I_ITEM_NUM;\n\nElementView._A_ITEM_SIZE = 4;\nElementView._A_ITEM_NUM = 4;\nElementView._A_SIZE = ElementView._A_ITEM_SIZE * ElementView._A_ITEM_NUM;\n\n\nElementView.prototype.init = function() {\n  this._initVertices();\n  this._initCoordinates();\n  this._initIndices();\n  this._initColors();\n};\n\n\nElementView.prototype._initVertices = function() {\n  var w = this.element.getWidth()/2;\n  var h = this.element.getHeight()/2;\n\n  this.vertices[0]  = -w;\n  this.vertices[1]  = -h;\n  this.vertices[2]  = -1.0;\n  this.vertices[3]  =  w;\n  this.vertices[4]  = -h;\n  this.vertices[5]  = -1.0;\n  this.vertices[6]  =  w;\n  this.vertices[7]  =  h;\n  this.vertices[8]  = -1.0;\n  this.vertices[9]  = -w;\n  this.vertices[10] =  h;\n  this.vertices[11] = -1.0;\n};\n\n\nElementView.prototype._initCoordinates = function() {\n  var w = this.element.getWidth()/this.element.getImageWidth();\n  var h = this.element.getHeight()/this.element.getImageHeight();\n\n  var x1 = w * this.element.getImageIndexX();\n  var y1 = h * this.element.getImageIndexY();\n  var x2 = x1 + w;\n  var y2 = y1 + h;\n\n  this.coordinates[0] = x1;\n  this.coordinates[1] = y2;\n  this.coordinates[2] = x2;\n  this.coordinates[3] = y2;\n  this.coordinates[4] = x2;\n  this.coordinates[5] = y1;\n  this.coordinates[6] = x1;\n  this.coordinates[7] = y1;\n};\n\n\nElementView.prototype._initIndices = function() {\n  this.indices[0] = 0;\n  this.indices[1] = 1;\n  this.indices[2] = 2;\n\n  this.indices[3] = 0;\n  this.indices[4] = 2;\n  this.indices[5] = 3;\n};\n\n\nElementView.prototype._initColors = function() {\n  this.colors[0] = 1.0;\n  this.colors[1] = 1.0;\n  this.colors[2] = 1.0;\n  this.colors[3] = 1.0;\n\n  this.colors[4] = 1.0;\n  this.colors[5] = 1.0;\n  this.colors[6] = 1.0;\n  this.colors[7] = 1.0;\n\n  this.colors[8] = 1.0;\n  this.colors[9] = 1.0;\n  this.colors[10] = 1.0;\n  this.colors[11] = 1.0;\n\n  this.colors[12] = 1.0;\n  this.colors[13] = 1.0;\n  this.colors[14] = 1.0;\n  this.colors[15] = 1.0;\n};\n\n\nElementView.prototype.getNum = function() {\n  return 1;\n};\n\n\nElementView.prototype.saveVertices = function() {\n  for(var i = 0, len = this._V_SIZE * this.getNum(); i < len; i++) {\n    this.sVertices[i] = this.vertices[i];\n  }\n};\n\n\nElementView.prototype.restoreVertices = function() {\n  for(var i = 0, len = this._V_SIZE * this.getNum(); i < len; i++) {\n    this.vertices[i] = this.sVertices[i];\n  }\n};\n\n\nElementView.prototype.translate = function() {\n  for(var j = 0, len = this.getNum(); j < len; j++) {\n    var o = this._V_SIZE * j;\n    for(var i = 0; i < this._V_ITEM_NUM; i++) {\n      this.vertices[o+i*this._V_ITEM_SIZE+0] += this._getElementX();\n      // this is the trick to correspond 2D canvas coordinates.\n      this.vertices[o+i*this._V_ITEM_SIZE+1] -= this._getElementY();\n      this.vertices[o+i*this._V_ITEM_SIZE+2] += this._getElementZ();;\n    }\n  }\n};\n\n\nElementView.prototype._getElementX = function() {\n  return this.element.getX();\n};\n\n\nElementView.prototype._getElementY = function() {\n  return this.element.getY();\n};\n\n\nElementView.prototype._getElementZ = function() {\n  return this.element.getZ();\n};\n\n\nElementView.prototype.rotate = function() {\n  var theta = 270 - this.element.getDirectionTheta();\n  var radian = theta * this.Math.PI / 180;\n  for(var j = 0, len = this.getNum(); j < len; j++) {\n    var o = this._V_SIZE * j;\n    for(var i = 0; i < this._V_ITEM_NUM; i++) {\n      var x = this.vertices[o+i*this._V_ITEM_SIZE+0];\n      var y = this.vertices[o+i*this._V_ITEM_SIZE+1];\n\n      this.vertices[o+i*this._V_ITEM_SIZE+0] =\n        x * this.Math.cos(radian) - y * this.Math.sin(radian);\n      this.vertices[o+i*this._V_ITEM_SIZE+1] =\n        x * this.Math.sin(radian) + y * this.Math.cos(radian);\n    }\n  }\n};\n\n\n/**\n * TODO: optimize. and remove magic numbers;\n */\nElementView.prototype.rotateForViewpoint = function() {\n  var r = this.Math.sqrt(40*40 + 120*120);\n  var r2 = this.element.getHeight()/2;\n  var ay =  40 * r2 / r;\n  var az = 120 * r2 / r;\n  for(var j = 0, len = this.getNum(); j < len; j++) {\n    var o = this._V_SIZE * j;\n    for(var i = 0; i < this._V_ITEM_NUM; i++) {\n      var y = this.vertices[o+i*this._V_ITEM_SIZE+1];\n      var z = this.vertices[o+i*this._V_ITEM_SIZE+2];\n      if(i > 1) {\n        this.vertices[o+i*this._V_ITEM_SIZE+1] = ay;\n        this.vertices[o+i*this._V_ITEM_SIZE+2] = z+az;\n      } else {\n        this.vertices[o+i*this._V_ITEM_SIZE+1] = ay;\n        this.vertices[o+i*this._V_ITEM_SIZE+2] = z-az;\n      }\n    }\n  }\n};\n\n\nElementView.prototype.doRotateForViewpoint = function() {\n  return false;\n};\n\n\n/**\n * assume that update coordinates here in each frame.\n */\nElementView.prototype.animate = function() {\n};\n\n\n\nfunction ElementDrawer(e, layer, image) {\n  this.gameState = e.gameState;\n  if(e instanceof ElementManager) {\n    this.elementManager = e;\n    this.element = null;\n    this.maxLength = e.getMaxNum();\n  } else {\n    this.element = e;\n    this.elementManager = null;\n    this.maxLength = 1;\n  }\n  this.vArray = layer.createFloatArray(this.maxLength*this.ElementView._V_SIZE);\n  this.cArray = layer.createFloatArray(this.maxLength*this.ElementView._C_SIZE);\n  this.iArray = layer.createUintArray(this.maxLength*this.ElementView._I_SIZE);\n  this.aArray = layer.createFloatArray(this.maxLength*this.ElementView._A_SIZE);\n  this.vBuffer = layer.createBuffer();\n  this.cBuffer = layer.createBuffer();\n  this.iBuffer = layer.createBuffer();\n  this.aBuffer = layer.createBuffer();\n  this.texture = null;\n  this._initTexture(layer, image);\n};\n\n// only for reference\nElementDrawer.prototype.ElementView = ElementView.prototype;\nElementDrawer.prototype.Layer = Layer.prototype;\n\nElementDrawer.prototype._initTexture = function(layer, image) {\n  this.texture = layer.generateTexture(image);\n};\n\n\nElementDrawer.prototype._pourVertices = function(i, v) {\n  v.saveVertices();\n  if(this.gameState.doLookAtFromViewpointTarget() &&\n     v.doRotateForViewpoint())\n    v.rotateForViewpoint();\n  v.rotate();\n  v.translate();\n\n  var num = v.getNum();\n  var vLength = v._V_SIZE;\n  for(var k = 0; k < num; k++) {\n    for(var j = 0; j < vLength; j++) {\n      this.vArray[(i+k)*vLength+j] = v.vertices[k*vLength+j];\n    }\n  }\n\n  v.restoreVertices();\n};\n\n\nElementDrawer.prototype._pourCoordinates = function(i, v) {\n  var cLength = v._C_SIZE;\n  for(var k = 0, len = v.getNum(); k < len; k++) {\n    for(var j = 0; j < cLength; j++) {\n      this.cArray[(i+k)*cLength+j] = v.coordinates[k*cLength+j];\n    }\n  }\n};\n\n\nElementDrawer.prototype._pourIndices = function(i, v) {\n  // TODO: 4 is a magic number\n  var iLength = v._I_SIZE;\n  var indices = v.indices;\n  for(var k = 0, len = v.getNum(); k < len; k++) {\n    for(var j = 0; j < iLength; j++) {\n      this.iArray[(i+k)*iLength+j] = (i+k)*4 + indices[k*iLength+j];\n    }\n  }\n};\n\n\nElementDrawer.prototype._pourColors = function(i, v) {\n  var aLength = v._A_SIZE;\n  var colors = v.colors;\n  var a = v.a;\n  var d = v.d;\n  for(var k = 0, len = v.getNum(); k < len; k++) {\n    for(var j = 0; j < aLength; j++) {\n      if(j % 4 == 3)\n        this.aArray[(i+k)*aLength+j] = colors[k*aLength+j] * a;\n      else\n        this.aArray[(i+k)*aLength+j] = colors[k*aLength+j] * d;\n    }\n  }\n};\n\n\nElementDrawer.prototype._pourArray = function(e, n) {\n  var v = e.getView();\n  v.animate();\n  this._pourVertices(n, v);\n  this._pourCoordinates(n, v);\n  this._pourIndices(n, v);\n  this._pourColors(n, v);\n  return v.getNum();\n};\n\n\nElementDrawer.prototype._pourArrays = function() {\n  var n = 0;\n  for(var i = 0, len = this.elementManager.getNum(); i < len; i++) {\n    // TODO: bad design\n    var e = this.elementManager.get(i);\n    if(this._doPour(e)) {\n      n += this._pourArray(e, n);\n    }\n  }\n  return n;\n};\n\n\nElementDrawer.prototype._doPour = function(e) {\n  return true;\n};\n\n\n/**\n * This method can be performance critical function.\n * TODO: iBuffer generally doesn't need to update in each frame.\n *       It's good enough to update only its size if it's initialized.\n *       It could be improve CPU-GPU transfer performance.\n * TODO: attempt to redoce CPU-GPU transfer.\n */\nElementDrawer.prototype._pourBuffer = function(layer, n) {\n  layer.pourArrayBuffer(this.vBuffer, this.vArray, this.ElementView._V_ITEM_SIZE,\n                        n * this.ElementView._V_ITEM_NUM);\n  layer.pourArrayBuffer(this.cBuffer, this.cArray, this.ElementView._C_ITEM_SIZE,\n                        n * this.ElementView._C_ITEM_NUM);\n  layer.pourArrayBuffer(this.aBuffer, this.aArray, this.ElementView._A_ITEM_SIZE,\n                        n * this.ElementView._A_ITEM_NUM);\n  layer.pourElementArrayBuffer(this.iBuffer, this.iArray,\n                               this.ElementView._I_ITEM_SIZE,\n                               n * this.ElementView._I_ITEM_NUM);\n};\n\n\nElementDrawer.prototype._draw = function(layer) {\n  layer.draw(this.texture, this.vBuffer, this.cBuffer, this.iBuffer,\n             this.aBuffer, this._getBlend());\n};\n\n\nElementDrawer.prototype._getBlend = function() {\n  return this.Layer._BLEND_ALPHA;\n};\n\n\nElementDrawer.prototype._initDraw = function(layer) {\n  layer.viewport();\n};\n\n\n/**\n * TODO: remove magic numbers.\n */\nElementDrawer.prototype._project = function(layer) {\n  if(this.gameState.doLookAtFromViewpointTarget())\n    layer.perspective(60, 0.1, 1000.0);\n  else\n    layer.ortho(0.1, 10.0);\n};\n\n\n/**\n * Note: layer.lookAt or something should be here.\n */\nElementDrawer.prototype._prepareDraw = function(layer) {\n};\n\n\nElementDrawer.prototype._VIEWPOINTS_CONTAINERS = [\n  [0, 0, 1], // eye\n  [0, 0, 0], // center\n  [0, 1, 0]  // up\n];\n/**\n * TODO: remove magic numbers.\n */\nElementDrawer.prototype.lookAtFromViewpointTarget = function(layer) {\n  var f = this.gameState.getViewpointTarget();\n\n  var eye = this._VIEWPOINTS_CONTAINERS[0];\n  var center = this._VIEWPOINTS_CONTAINERS[1];\n  var up = this._VIEWPOINTS_CONTAINERS[2];\n\n  eye[0] =  f.getX();\n  eye[1] = -f.getY()+8;\n  eye[2] = 20;\n\n  center[0] = f.getX();\n  center[1] = -f.getY() + 128;\n  center[2] = -20;\n\n  layer.lookAt(eye, center, up);\n};\n\n\nElementDrawer.prototype.draw = function(layer) {\n  var n = this.element ? this._pourArray(this.element, 0) : this._pourArrays();\n  this._pourBuffer(layer, n);\n  this._initDraw(layer);\n  this._project(layer);\n  layer.identity();\n  this._prepareDraw(layer);\n  if(this.gameState.doLookAtFromViewpointTarget())\n    this.lookAtFromViewpointTarget(layer);\n  this._draw(layer);\n};\n\n\n\n/**\n * TODO: parameters should be object?\n */\nvar __moveVectorManager = new MoveVectorManager( ) ;\nfunction Element( gameState, maxX, maxY ) {\n  this.moveVectorManager = __moveVectorManager ; // TODO: temporal\n  this.listId = null ;\n  this.listForw = null ;\n  this.image = null ;\n\n  this.gameState = gameState ;\n  this.maxX = maxX ;\n  this.maxY = maxY ;\n\n  this.x = 0 ;\n  this.y = 0 ;\n  this.z = 0 ;\n  this.r = 0 ;\n  this.keepAlive = 0 ;\n  this.baseTheta = 0 ;\n  this.indexX = 0 ;\n  this.indexY = 0 ;\n  this.width  = 0 ;\n  this.height = 0 ;\n  this.collisionWidth  = 0 ;\n  this.collisionHeight = 0 ;\n  this.grazeWidth = 0;\n  this.grazeHeight = 0;\n\n  this.state = 0 ;\n  this.flags = 0 ;\n  this.count = 0 ;\n  this.graze = 0;\n\n  this.vectorIndex = 0 ;\n  this.vector = null ;\n  this.baseVectorCount = 0 ;\n  this.vectors = [ ] ;\n  this.gravity = null ;\n\n  this.view = this._generateView();\n};\n\n// only for reference\nElement.prototype.Math = Math;\nElement.prototype.Randomizer = __randomizer;\n\nElement.prototype._STATE_ALIVE = 1 ;\nElement.prototype._STATE_DEAD  = 2 ;\n\nElement.prototype._FLAG_MOVE_STOP  =  0x1 ;\nElement.prototype._FLAG_MOVE_LEFT  =  0x2 ;\nElement.prototype._FLAG_MOVE_UP    =  0x4 ;\nElement.prototype._FLAG_MOVE_RIGHT =  0x8 ;\nElement.prototype._FLAG_MOVE_DOWN  = 0x10 ;\nElement.prototype._FLAG_SHOT       = 0x20 ;\nElement.prototype._FLAG_HIT        = 0x40 ;\nElement.prototype._FLAG_UNHITTABLE = 0x80 ;\n\n\nElement.prototype.init = function(params, image) {\n  this.image = image ;\n\n  this.x               = this._getValueOrDefaultValue(params.x, 0);\n  this.y               = this._getValueOrDefaultValue(params.y, 0);\n  this.z               = this._getValueOrDefaultValue(params.z, 0);\n  this.r               = this._getValueOrDefaultValue(params.r, 0);\n  this.keepAlive       = this._getValueOrDefaultValue(params.keepAlive, 0);\n  this.baseTheta       = this._getValueOrDefaultValue(params.baseTheta, 0);\n  this.indexX          = this._getValueOrDefaultValue(params.indexX, 0);\n  this.indexY          = this._getValueOrDefaultValue(params.indexY, 0);\n  this.width           = this._getValueOrDefaultValue(params.width, 0);\n  this.height          = this._getValueOrDefaultValue(params.height, 0);\n  this.collisionWidth  = this._getValueOrDefaultValue(params.collisionWidth, 0);\n  this.collisionHeight = this._getValueOrDefaultValue(params.collisionHeight, 0);\n  this.grazeWidth      = this._getValueOrDefaultValue(params.grazeWidth, 0);\n  this.grazeHeight     = this._getValueOrDefaultValue(params.grazeHeight, 0);\n  this.graze           = this._getValueOrDefaultValue(params.graze, 1);\n\n  this.state = 0 ;\n  this.flags = 0 ;\n  this.count = 0 ;\n\n  this.vectorIndex = 0 ;\n  this.baseVectorCount = 0 ;\n  // TODO: temporal\n  this.vectors.length = 0 ;\n  if(params.v === void 0) {\n  } else if( params.v instanceof Array ) {\n    for( var i = 0; i < params.v.length; i++ )\n      this.vectors.push( params.v[ i ] ) ;\n  } else {\n    params.v = [ { 'v': params.v } ] ;\n    this.vectors.push( params.v[ 0 ] ) ;\n//    this.vectors.push( { 'v': params.v } ) ;\n  }\n\n  if( this.vectors.length > 0 )\n    this.vectors[ 0 ].count = 0 ;\n  this.vector = null ;\n  this.gravity = null ;\n\n  if( this.vectors.length > 0 )\n    this._initVector( ) ;\n  this._supplyPosition( ) ;\n\n} ;\n\n\nElement.prototype._initView = function() {\n  this.view.init();\n};\n\n\nElement.prototype.getView = function() {\n  return this.view;\n};\n\n\nElement.prototype._generateView = function() {\n  return new ElementView(this);\n};\n\n\nElement.prototype._getValueOrDefaultValue = function(value, defaultValue) {\n  return value !== void 0 ? value : defaultValue;\n};\n\n\nElement.prototype.free = function( ) {\n  if(this.vector !== null)\n    this.moveVectorManager.free( this.vector ) ;\n  if(this.gravity !== null)\n    this.moveVectorManager.free( this.gravity ) ;\n} ;\n\n\nElement.prototype._checkVectorChange = function( ) {\n  if( this.vectorIndex >= this.vectors.length - 1 )\n    return false ;\n  if( this.count >=\n        this.vectors[ this.vectorIndex + 1 ].count + this.baseVectorCount ) {\n    return true ;\n  }\n  return false ;\n} ;\n\n\nElement.prototype._changeVector = function( ) {\n  this.vectorIndex++ ;\n  if( typeof( this.vectors[ this.vectorIndex ].v ) == 'number' ) {\n    this.vectorIndex = this.vectors[ this.vectorIndex ].v ;\n    this.baseVectorCount = this.count ;\n  }\n} ;\n\n\n/**\n * TODO: to make the logic straightforward.\n */\nElement.prototype._initVector = function( ) {\n  // save previous data\n  var preTheta = null;\n  if(this.vector !== null)\n    preTheta = this.vector.theta ;\n  var tmpTheta = this.vectors[ this.vectorIndex ].v.theta ;\n  var tmpR     = this.vectors[ this.vectorIndex ].v.r ;\n\n  // for special propose\n  // these functions will updates this.vectors[ this.vectorIndex ],\n  // so previous data needs to be saved.\n  if(this.vectors[ this.vectorIndex ].v.aimed !== void 0)\n    this._calculateAimedVector( ) ;\n  if(this.vectors[ this.vectorIndex ].v.target !== void 0)\n    this._calculateTargetVector( ) ;\n\n  // set normal vector\n  if(this.vector !== null)\n    this.moveVectorManager.free( this.vector ) ;\n  this.vector = this.moveVectorManager.create( this.vectors[ this.vectorIndex ].v ) ;\n  if(this.baseTheta !== null)\n    this.vector.theta += this.baseTheta ;\n  if(preTheta !== null && this.vectors[ this.vectorIndex ].v.theta === void 0)\n    this.vector.theta = preTheta ;\n\n  // restore previous data\n  this.vectors[ this.vectorIndex ].v.theta = tmpTheta ;\n  this.vectors[ this.vectorIndex ].v.r = tmpR ;\n\n  // set gravity vector\n  if(this.gravity !== null)\n    this.moveVectorManager.free( this.gravity ) ;\n  if(this.vectors[ this.vectorIndex ].v.g !== void 0)\n    this.gravity = this.moveVectorManager.create( this.vectors[ this.vectorIndex ].v.g ) ;\n  else\n    this.gravity = null ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nElement.prototype._supplyPosition = function( ) {\n\n  if(this.r === 0 || this.vector === null)\n    return ;\n\n  var ax = 0 ;\n  var ay = 0 ;\n\n  if(this.gravity === null) {\n    ax = this.r * this.Math.cos( this._calculateRadian( this.vector.theta ) ) ;\n    ay = this.r * this.Math.sin( this._calculateRadian( this.vector.theta ) ) ;\n  } else {\n    var dx = this.vector.moveX( ) + this.gravity.moveX( ) ;\n    var dy = this.vector.moveY( ) + this.gravity.moveY( ) ;\n    var t = this.Math.atan2( dy, dx ) ;\n    ax = this.r * this.Math.cos( t ) ;\n    ay = this.r * this.Math.sin( t ) ;\n  }\n\n  this.setX( this.getX( ) + ax ) ;\n  this.setY( this.getY( ) + ay ) ;\n\n} ;\n\n\n/**\n * TODO: temporal\n */\nElement.prototype._calculateAimedVector = function() {\n  var fighter = this.gameState.fighterManager.getClosestFighter(this);\n  var ax = fighter.getCenterX() - this.getCenterX();\n  var ay = fighter.getCenterY() - this.getCenterY();\n  this.vectors[this.vectorIndex].v.theta += this._calculateTheta(this.Math.atan2(ay, ax));\n};\n\n\n/**\n * TODO: temporal\n */\nElement.prototype._calculateTargetVector = function( ) {\n  var x = typeof( this.vectors[ this.vectorIndex ].v.target.x ) == 'object'\n             ? this._getRandomValue( this.vectors[ this.vectorIndex ].v.target.x )\n             : this.vectors[ this.vectorIndex ].v.target.x ;\n  var y = typeof( this.vectors[ this.vectorIndex ].v.target.y ) == 'object'\n             ? this._getRandomValue( this.vectors[ this.vectorIndex ].v.target.y )\n             : this.vectors[ this.vectorIndex ].v.target.y ;\n\n  var ax = x - this.getX( ) ;\n  var ay = y - this.getY( ) ;\n  this.vectors[ this.vectorIndex ].v.theta = this._calculateTheta( this.Math.atan2( ay, ax ) ) ;\n  this.vectors[ this.vectorIndex ].v.r = this.Math.sqrt( ax * ax + ay * ay ) / this.vectors[ this.vectorIndex ].v.target.count ;\n} ;\n\n\n/**\n * TODO: temporal\n * duplicated code\n */\nElement.prototype._getRandomValue = function(range) {\n  var differ = range.max - range.min;\n  return ((this.Randomizer.random() * differ) | 0) + range.min;\n};\n\n\nElement.prototype._calculateRadian = function( theta ) {\n  return theta * this.Math.PI / 180 ;\n} ;\n\n\nElement.prototype._calculateTheta = function(radian) {\n  return (radian * 180 / this.Math.PI) | 0;\n};\n\n\nElement.prototype.display = function( surface, rotate, angle ) {\n  var x = this.Math.round( this.getLeftX( ) ) ;\n  var y = this.Math.round( this.getUpY( ) ) ;\n  if( rotate ) {\n    var rx = this.Math.round( this.getCenterX( ) ) ;\n    var ry = this.Math.round( this.getCenterY( ) ) ;\n    if(angle === null || angle === void 0)\n      angle = this._calculateRadian( this.getDirectionTheta( ) + 90 ) ;\n    else\n      angle = this._calculateRadian( angle ) ;\n    surface.save( ) ;\n    surface.translate( rx, ry ) ;\n    surface.rotate( angle ) ;\n    surface.translate( -rx, -ry ) ;\n  }\n  surface.drawImage( this.image,\n                     this.width  * this.indexX, this.height * this.indexY,\n                     this.width,                this.height,\n                     x,                         y,\n                     this.width,                this.height ) ;\n  if( rotate ) {\n    surface.restore( ) ;\n  }\n} ;\n\n\nElement.prototype.getX = function( ) {\n  return this.x ;\n} ;\n\n\nElement.prototype.getY = function( ) {\n  return this.y ;\n} ;\n\n\nElement.prototype.getZ = function() {\n  return this.z;\n};\n\n\nElement.prototype.getWidth = function( ) {\n  return this.width ;\n} ;\n\n\nElement.prototype.getHeight = function( ) {\n  return this.height ;\n} ;\n\n\nElement.prototype.getImageIndexX = function() {\n  return this.indexX;\n};\n\n\nElement.prototype.getImageIndexY = function() {\n  return this.indexY;\n};\n\n\nElement.prototype.getImageWidth = function() {\n  return this.image.width;\n};\n\n\nElement.prototype.getImageHeight = function() {\n  return this.image.height;\n};\n\n\nElement.prototype.setX = function( x ) {\n  this.x = x ;\n} ;\n\n\nElement.prototype.setY = function( y ) {\n  this.y = y ;\n} ;\n\n\nElement.prototype.getCenterX = function( ) {\n  return this.getX( ) ;\n} ;\n\n\nElement.prototype.getCenterY = function( ) {\n  return this.getY( ) ;\n} ;\n\n\nElement.prototype.getLeftX = function( ) {\n  return this.getCenterX( ) - this.getWidth( ) / 2 ;\n} ;\n\n\nElement.prototype.getRightX = function( ) {\n  return this.getCenterX( ) + this.getWidth( ) / 2 ;\n} ;\n\n\n/**\n * TODO: rename. Up -> Top\n */\nElement.prototype.getUpY = function( ) {\n  return this.getCenterY( ) - this.getHeight( ) / 2 ;\n} ;\n\n\nElement.prototype.getBottomY = function( ) {\n  return this.getCenterY( ) + this.getHeight( ) / 2 ;\n} ;\n\n\nElement.prototype.getCollisionLeftX = function( ) {\n  return this.getCenterX( ) - this.collisionWidth / 2 ;\n} ;\n\n\nElement.prototype.getCollisionRightX = function( ) {\n  return this.getCenterX( ) + this.collisionWidth / 2 ;\n} ;\n\n\nElement.prototype.getCollisionUpY = function( ) {\n  return this.getCenterY( ) - this.collisionHeight / 2 ;\n} ;\n\n\nElement.prototype.getCollisionBottomY = function( ) {\n  return this.getCenterY( ) + this.collisionHeight / 2 ;\n} ;\n\n\nElement.prototype.inCollisionArea = function( x, y ) {\n  if( x >= this.getCollisionLeftX( ) && x <= this.getCollisionRightX( ) &&\n      y >= this.getCollisionUpY( )   && y <= this.getCollisionBottomY( ) )\n    return true ;\n  return false ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nElement.prototype.checkCollision = function( e ) {\n\n  if( this.isDead( ) )\n    return false ;\n\n  if( this.inCollisionArea( e.getCollisionLeftX( ),  e.getCollisionUpY( ) ) ||\n      this.inCollisionArea( e.getCollisionLeftX( ),  e.getCollisionBottomY( ) ) ||\n      this.inCollisionArea( e.getCollisionRightX( ), e.getCollisionUpY( ) ) ||\n      this.inCollisionArea( e.getCollisionRightX( ), e.getCollisionBottomY( ) ) ||\n      this.inCollisionArea( e.getCenterX( ),         e.getCenterY( ) ) ) {\n    return true ;\n  }\n\n  return false ;\n\n} ;\n\n\nElement.prototype.getGrazeLeftX = function() {\n  return this.getCenterX() - this.grazeWidth/2;\n};\n\n\nElement.prototype.getGrazeRightX = function() {\n  return this.getCenterX() + this.grazeWidth/2;\n};\n\n\nElement.prototype.getGrazeUpY = function() {\n  return this.getCenterY() - this.grazeHeight/2;\n};\n\n\nElement.prototype.getGrazeBottomY = function() {\n  return this.getCenterY() + this.grazeHeight/2;\n};\n\n\nElement.prototype.inGrazeArea = function(x, y) {\n  if(x >= this.getGrazeLeftX() && x <= this.getGrazeRightX() &&\n     y >= this.getGrazeUpY()   && y <= this.getGrazeBottomY())\n    return true;\n  return false;\n};\n\n\n/**\n * TODO: temporal\n */\nElement.prototype.checkGraze = function(e) {\n\n  if(!this.graze)\n    return false;\n\n  if(this.isDead())\n    return false;\n\n  if(this.inGrazeArea(e.getGrazeLeftX(),  e.getGrazeUpY()) ||\n     this.inGrazeArea(e.getGrazeLeftX(),  e.getGrazeBottomY()) ||\n     this.inGrazeArea(e.getGrazeRightX(), e.getGrazeUpY()) ||\n     this.inGrazeArea(e.getGrazeRightX(), e.getGrazeBottomY()) ||\n     this.inGrazeArea(e.getCenterX(),     e.getCenterY())) {\n    return true;\n  }\n\n  return false;\n\n};\n\n\nElement.prototype.inViewArea = function( x, y ) {\n  if( x > this.getLeftX( ) && x < this.getRightX( ) &&\n      y > this.getUpY( )   && y < this.getBottomY( ) )\n    return true ;\n  return false ;\n} ;\n\n\nElement.prototype.checkViewCollision = function( e ) {\n\n  if( this.isDead( ) )\n    return false ;\n\n  if( this.inViewArea( e.getLeftX( ),  e.getUpY( ) ) ||\n      this.inViewArea( e.getLeftX( ),  e.getBottomY( ) ) ||\n      this.inViewArea( e.getRightX( ), e.getUpY( ) ) ||\n      this.inViewArea( e.getRightX( ), e.getBottomY( ) ) ) {\n    return true ;\n  }\n\n  return false ;\n\n} ;\n\n\nElement.prototype._beInTheField = function( ) {\n  if( this.getX( ) < 0 )\n    this.setX( 0 ) ;\n  if( this.getX( ) > this.maxX )\n    this.setX( this.maxX ) ;\n  if( this.getY( ) < 0 )\n    this.setY( 0 ) ;\n  if( this.getY( ) > this.maxY )\n    this.setY( this.maxY ) ;\n} ;\n\n\n/**\n * TODO: separate the check loss logic and reflect logic?\n */\nElement.prototype.checkLoss = function( ) {\n\n  if( this.isDead( ) )\n    return true ;\n\n  if( this._outOfKeepAlive( ) )\n    return true ;\n\n  if( this._checkReflect( ) )\n    return true ;\n\n  if( this._outOfTheField( ) )\n    return true ;\n\n  return false ;\n\n} ;\n\n\nElement.prototype._outOfKeepAlive = function( ) {\n  if( this.keepAlive && this.count >= this.keepAlive )\n    return true ;\n} ;\n\n\nElement.prototype._outOfTheField = function( ) {\n  if( this.getX( ) < 0 || this.getX( ) > this.maxX ||\n      this.getY( ) < 0 || this.getY( ) > this.maxY )\n    return true ;\n  return false ;\n} ;\n\n\nElement.prototype._checkReflect = function( ) {\n  if( this.vectors.length <= 0 )\n    return false ;\n\n  if( this.vectors[ this.vectorIndex ].v.reflectX ) {\n    if( this.getX( ) < 0 || this.getX( ) > this.maxX ) {\n      this.vector.reflectX( ) ;\n      this._beInTheField( ) ;\n      if( this.vectors[ this.vectorIndex ].v.reflectCount &&\n          this.vector.getReflectCount( ) > this.vectors[ this.vectorIndex ].v.reflectCount )\n        return true ;\n    }\n  }\n  if( this.vectors[ this.vectorIndex ].v.reflectY ) {\n    if( this.getY( ) < 0 || this.getY( ) > this.maxY ) {\n      this.vector.reflectY( ) ;\n      this._beInTheField( ) ;\n      if( this.vectors[ this.vectorIndex ].v.reflectCount &&\n          this.vector.getReflectCount( ) > this.vectors[ this.vectorIndex ].v.reflectCount )\n        return true ;\n    }\n  } \n  if( this.vectors[ this.vectorIndex ].v.reflect ) {\n    if( this.getX( ) < 0 || this.getX( ) > this.maxX ||\n        this.getY( ) < 0 || this.getY( ) > this.maxY ) {\n      this.vector.reflect( ) ;\n      this._beInTheField( ) ;\n      if( this.vectors[ this.vectorIndex ].v.reflectCount &&\n          this.vector.getReflectCount( ) > this.vectors[ this.vectorIndex ].v.reflectCount )\n        return true ;\n    }\n  }\n  return false ;\n} ;\n\n\nElement.prototype.move = function( ) {\n  if( this.vector ) {\n    this.setX( this.getX( ) + this._moveX( ) ) ;\n    this.setY( this.getY( ) + this._moveY( ) ) ;\n  }\n\n  if( this.gravity ) {\n    this.setX( this.getX( ) + this._moveGravityX( ) ) ;\n    this.setY( this.getY( ) + this._moveGravityY( ) ) ;\n  }\n} ;\n\n\nElement.prototype._moveX = function( ) {\n  return this.vector.moveX( ) ;\n} ;\n\n\nElement.prototype._moveY = function( ) {\n  return this.vector.moveY( ) ;\n} ;\n\n\nElement.prototype._moveGravityX = function( ) {\n  return this.gravity.moveX( ) ;\n} ;\n\n\nElement.prototype._moveGravityY = function( ) {\n  return this.gravity.moveY( ) ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nElement.prototype.getDirectionTheta = function( ) {\n  if( ! this.vector )\n    return 90 ;\n  if( this.vector && ! this.gravity )\n    return this.vector.theta ;\n\n  // TODO: is there any simpler logics?\n  var ax = this.vector.moveX( ) + this.gravity.moveX( ) ;\n  var ay = this.vector.moveY( ) + this.gravity.moveY( ) ;\n  return this._calculateTheta( this.Math.atan2( ay, ax ) ) ;\n} ;\n\n\nElement.prototype.getXDirection = function( ) {\n  if( ! this.vector )\n    return 0 ;\n  var cos = this.Math.cos( this._calculateRadian( this.getDirectionTheta( ) ) ) ;\n  if( cos > 1.00e-10 )\n    return 1 ;\n  else if( cos < -1.00e-10 )\n    return -1 ;\n  return 0 ;\n\n} ;\n\n\nElement.prototype.getTheta = function() {\n  if(this.getVelocity() >= 0)\n    return this.vector.theta;\n  return -this.vector.theta;\n};\n\n\nElement.prototype.getVelocity = function() {\n  return this.vector.r;\n};\n\n\n/**\n * TODO: divide count up and runstep?\n */\nElement.prototype.runStep = function( ) {\n  this.move( ) ;\n  if( this.gravity ) {\n    this.gravity.runStep( ) ;\n  }\n  if( this.vector ) {\n    this.vector.runStep( ) ;\n    if( this._checkVectorChange( ) ) {\n      this._changeVector( ) ;\n      this._initVector( ) ;\n    }\n  }\n  this.count++ ;\n} ;\n\n\nElement.prototype.die = function( ) {\n  this.state = this._STATE_DEAD ;\n} ;\n\n\nElement.prototype.isDead = function( ) {\n  return this.state == this._STATE_DEAD ;\n} ;\n\n\nElement.prototype.isFlagSet = function( type ) {\n  return ( this.flags & type ) ? true : false ;\n} ;\n\n\n/**\n * Returns true if previous value is false. Otherwise returns false.\n */\nElement.prototype.setFlag = function( type ) {\n  var pre = this.isFlagSet( type ) ;\n  this.flags |= type ;\n  return ! pre ;\n} ;\n\n\n/**\n * Returns true if previous value is true. Otherwise returns false.\n */\nElement.prototype.clearFlag = function( type ) {\n  var pre = this.isFlagSet( type ) ;\n  this.flags &= ~type ;\n  return pre ;\n} ;\n\n"
  },
  {
    "path": "source/EndingState.js",
    "content": "function EndingState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n  this.count = 0 ;\n}\n__inherit( EndingState, GameState ) ;\n\n\nEndingState.prototype.init = function( ) {\n  this._soundBGM( Game._BGM_ENDING ) ;\n} ;\n\n\nEndingState.prototype.runStep = function( ) {\n  this.count++ ;\n} ;\n\n\nEndingState.prototype.updateDisplay = function( surface ) {\n  this.game.clear( surface ) ;\n  this._displayBG( surface ) ;\n  this._displayMessage( surface ) ;\n} ;\n\n\nEndingState.prototype._displayBG = function( surface ) {\n  surface.save( ) ;\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n  surface.fillRect( 0, 0, this.getWidth( ), this.getHeight( ) ) ;\n  surface.restore( ) ;\n} ;\n\n\nEndingState.prototype._displayMessage = function( surface ) {\n  surface.save( ) ;\n  surface.font = '30pt Calibri' ;\n  surface.textAlign = 'center' ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  if( this.count >= 0 ) {\n    surface.fillText( 'You\\'ve done.', this.getWidth( ) / 2, 50 ) ;\n  }\n  if( this.count >= 100 ) {\n    surface.fillText( 'And all was over.', this.getWidth( ) / 2, 100 ) ;\n  }\n  if( this.count >= 200 ) {\n    surface.fillText( 'Thank you for the playing.', this.getWidth( ) / 2, 150 ) ;\n  }\n  surface.restore( ) ;\n} ;\n\n\nEndingState.prototype.handleKeyDown = function( e ) {\n} ;\n\n\nEndingState.prototype.handleKeyUp = function( e ) {\n} ;\n"
  },
  {
    "path": "source/Enemy.js",
    "content": "function EnemyManager( gameState, params ) {\n  this.parent = ElementManager ;\n  this.parent.call( this, gameState ) ;\n  for( var i = 0; i < params.length; i++ ) {\n    params[ i ].sort( function( a, b ) {\n      return a.count - b.count ;\n    } ) ;\n  }\n  this.params = params ;\n  this.index = 0 ;\n  this.stageIndex = 0 ; // TODO: temporal\n} ;\n__inherit( EnemyManager, ElementManager ) ;\n\nEnemyManager.prototype._MAX_NUM = 200;\n\n\nEnemyManager.prototype._initMaxNum = function() {\n  return this._MAX_NUM;\n};\n\n\nEnemyManager.prototype._initFactory = function( ) {\n  this.factory = new EnemyFactory( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\nEnemyManager.prototype.initDrawer = function(layer, image) {\n  this.drawer = new EnemyDrawer(this, layer,\n                                this.gameState.getImage(Game._IMG_ENEMY));\n};\n\n\n__copyParentMethod(EnemyManager, ElementManager, 'reset');\nEnemyManager.prototype.reset = function() {\n  this.ElementManager_reset();\n  this.index = 0;\n  this.stageIndex = 0;\n};\n\n\nEnemyManager.prototype.goNextStage = function() {\n  this.ElementManager_reset();\n  this.index = 0;\n  this.stageIndex++;\n};\n\n\n__copyParentMethod(EnemyManager, ElementManager, 'runStep');\nEnemyManager.prototype.runStep = function() {\n  this._generateEnemy();\n  this.ElementManager_runStep();\n};\n\n\nEnemyManager.prototype._generateEnemy = function( ) {\n  if(this.gameState.isBossExist())\n    return;\n  while( this.index < this.params[ this.stageIndex ].length &&\n         this.params[ this.stageIndex ][ this.index ].count + this.gameState.pending <= this.gameState.count ) {\n    if(! this.gameState.isBombExist())\n      this.addElement( this.factory.create( this.params[ this.stageIndex ][ this.index ] ) ) ;\n    this.index++ ;\n  }\n} ;\n\n\n__copyParentMethod(EnemyManager, ElementManager, 'checkCollisionWith');\nEnemyManager.prototype.checkCollisionWith = function(fighter) {\n  if(fighter.isFlagSet(fighter._FLAG_UNHITTABLE))\n    return;\n  this.ElementManager_checkCollisionWith(null, fighter, this)\n};\n\n\nEnemyManager.prototype.checkCollisionWithFighters = function(fighters) {\n  for(var i = 0; i < fighters.length; i++) {\n    this.checkCollisionWith(fighters[i]);\n  }\n};\n\n\nEnemyManager.prototype.notifyCollision = function(id, fighter, enemy) {\n  fighter.die();\n  this.gameState.notifyFighterDead(fighter, enemy);\n};\n\n\n/**\n * TODO: temporal\n */\nEnemyManager.prototype.bomb = function( fighter ) {\n  for( var i = 0; i < this.elements.length; i++ ) {\n    this.elements[ i ].die( ) ;\n    this.gameState.notifyEnemyVanished( null, this.elements[ i ] ) ; // TODO: null is ok?\n  }\n} ;\n\n\n\nfunction EnemyFactory( gameState, maxX, maxY ) {\n  this.parent = ElementFactory ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n  this.image = null; // TODO: temporal\n} ;\n__inherit( EnemyFactory, ElementFactory ) ;\n\nEnemyFactory.prototype._NUM = 200 ;\n\n\nEnemyFactory.prototype._initFreelist = function() {\n  this.freelist = new EnemyFreeList(this._NUM, this.gameState);\n};\n\n\n/**\n *\n */\nEnemyFactory.prototype.create = function( params ) {\n  var enemy = this.freelist.get( ) ;\n  enemy.init( params, this._getImage( params ) ) ;\n  return enemy ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nEnemyFactory.prototype._getImage = function(params) {\n  if(this.image === null)\n    this.image = this.gameState.getImage(Game._IMG_ENEMY);\n  return this.image;\n};\n\n\n\nfunction EnemyFreeList( num, gameState ) {\n  this.parent = ElementFreeList ;\n  this.parent.call( this, num, gameState ) ;\n}\n__inherit( EnemyFreeList, ElementFreeList ) ;\n\n\nEnemyFreeList.prototype._generateElement = function( ) {\n  return new Enemy( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\n\nfunction EnemyDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(EnemyDrawer, ElementDrawer);\n\n\n\nfunction EnemyView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(EnemyView, ElementView);\n\n\n/**\n * no rotate.\n * TODO: no rotate impl should be in parent class?\n */\nEnemyView.prototype.rotate = function() {\n};\n\n\nEnemyView.prototype.doRotateForViewpoint = function() {\n  return true;\n};\n\n\nEnemyView.prototype.animate = function() {\n  this._initCoordinates();\n};\n\n\n\nfunction Enemy( gameState, maxX, maxY ) {\n  this.parent = Element ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n\n  this.shots = [ ] ;\n\n  // TODO: temporal\n  this.shotIndices = [ ] ;\n  this.baseShotCounts = [ ] ;\n  this.endShotCounts = [ ] ;\n\n  this.vital = null ;\n  this.powerItem  = null ;\n  this.lpowerItem = null ;\n  this.scoreItem  = null ;\n}\n__inherit( Enemy, Element ) ;\n\nEnemy.prototype._WIDTH = 32 ;\nEnemy.prototype._HEIGHT = 32 ;\n\n\n__copyParentMethod(Enemy, Element, 'init');\nEnemy.prototype.init = function(params, image) {\n  this.Element_init(params, image);\n\n  // TODO: temporal\n  this.shots.length = 0;\n  if(params.s === void 0) {\n//  } else if(params.s instanceof Array) {\n  } else if(params.s.length !== void 0) {\n    for(var i = 0; i < params.s.length; i++)\n      this.shots[this.shots.length] = params.s[i];\n } else {\n    this.shots[this.shots.length] = params.s;\n  }\n\n  // TODO: temporal\n  this.shotIndices.length = 0;\n  this.baseShotCounts.length = 0;\n  this.endShotCounts.length = 0;\n  for(var i = 0; i < this.shots.length; i++) {\n    this.shotIndices[this.shotIndices.length] = 0;\n\n    if(this.shots[i].baseCount !== void 0)\n      this.baseShotCounts[this.baseShotCounts.length] = this.shots[i].baseCount;\n    else\n      this.baseShotCounts[this.baseShotCounts.length] = 0;\n\n    if(this.shots[i].endCount !== void 0)\n      this.endShotCounts[this.endShotCounts.length] = this.shots[i].endCount;\n    else\n      this.endShotCounts[this.endShotCounts.length] = 0;\n  }\n\n  this.width  = this._WIDTH;\n  this.height = this._HEIGHT;\n  this.collisionWidth  = this.width;\n  this.collisionHeight = this.height;\n  this.vital      = params.vital      !== void 0 ? params.vital      : 4; // TODO: temporal\n  this.powerItem  = params.powerItem  !== void 0 ? params.powerItem  : 0;\n  this.lpowerItem = params.lpowerItem !== void 0 ? params.lpowerItem : 0;\n  this.scoreItem  = params.scoreItem  !== void 0 ? params.scoreItem  : 0;\n  this._initView();\n};\n\n\nEnemy.prototype._generateView = function() {\n  return new EnemyView(this);\n};\n\n\nEnemy.prototype._shot = function( ) {\n  if( this.shots.length == 0 )\n    return ;\n\n  for( var i = 0; i < this.shots.length; i++ ) {\n    if( this.shotIndices[ i ] >= this.shots[ i ].shotCount.length )\n      continue ;\n    if( this.endShotCounts[ i ] && this.count >= this.endShotCounts[ i ] )\n      continue ;\n    if( this.count >= this.shots[ i ].shotCount[ this.shotIndices[ i ] ] + this.baseShotCounts[ i ] ) {\n      // TODO: temporal\n      this.gameState.notifyEnemyDoShot( this, this.shots[ i ] ) ;\n      this.shotIndices[ i ]++ ;\n      if( this.shots[ i ].loop && this.shotIndices[ i ] >= this.shots[ i ].shotCount.length ) {\n        this.shotIndices[ i ] = 0 ;\n        this.baseShotCounts[ i ] = this.count ;\n      }\n    }\n  }\n} ;\n\n\n// TODO: temporal\n__copyParentMethod(Enemy, Element, 'runStep');\nEnemy.prototype.runStep = function() {\n  this._shot();\n\n  this.Element_runStep();\n\n  // for animation\n  if(this.count % 5 == 0) {\n    this.indexX++;\n    if(this.indexX > 2)\n      this.indexX = 0;\n  }\n};\n\n\n// TODO: temporal\nEnemy.prototype.isVanishingOrEscaping = function() {\n  return false;\n};\n"
  },
  {
    "path": "source/EnemyBullet.js",
    "content": "function EnemyBulletManager( gameState, params ) {\n  this.parent = ElementManager ;\n  this.parent.call( this, gameState ) ;\n  this.params = params ;\n  this.index = 0 ;\n  this.reservedLength = 0 ; // TODO: temporal\n  this.reserved = [ ] ;     // TODO: temporal\n  this._initReserved( ) ;\n  this.beamDrawer = null; // TODO: temporal\n} ;\n__inherit( EnemyBulletManager, ElementManager ) ;\n\nEnemyBulletManager.prototype._RESERVED_NUM = 50 ; // TODO: temporal\nEnemyBulletManager.prototype._MAX_NUM = 1000 ; // TODO: temporal\n\n\nEnemyBulletManager.prototype._initMaxNum = function() {\n  return this._MAX_NUM;\n};\n\n\nEnemyBulletManager.prototype._initFactory = function( ) {\n  this.factory = new EnemyBulletFactory( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\nEnemyBulletManager.prototype.initDrawer = function(layer, image) {\n  this.drawer = new EnemyBulletDrawer(\n                      this, layer,\n                      this.gameState.getImage(Game._IMG_ENEMY_SHOT));\n  this.beamDrawer = new EnemyBeamDrawer(\n                      this, layer,\n                      this.gameState.getImage(Game._IMG_BEAM));\n};\n\n\n/**\n * TODO: temporal. should implement reserved freelist?\n */\nEnemyBulletManager.prototype._initReserved = function( ) {\n  for( var i = 0; i < this._RESERVED_NUM; i++ ) {\n    this.reserved.push( { 'enemy': null,\n                          'index': 0,\n                          'count': 0,\n                          'shot' : null,\n                          'array': null } ) ;\n  }\n} ;\n\n\n__copyParentMethod(EnemyBulletManager, ElementManager, 'reset');\nEnemyBulletManager.prototype.reset = function() {\n  this.ElementManager_reset();\n  this.reservedLength = 0;\n  this.index = 0;\n};\n\n\n__copyParentMethod(EnemyBulletManager, ElementManager, 'runStep');\nEnemyBulletManager.prototype.runStep = function() {\n  this._shotReserved();\n  for(var i = 0; i < this.reservedLength; i++)\n    this.reserved[ i ].count++;\n  this.ElementManager_runStep();\n};\n\n\n/**\n * TODO: temporal. to make the logic straightforward.\n */\nEnemyBulletManager.prototype._shotReserved = function( ) {\n  for( var i = 0; i < this.reservedLength; i++ ) {\n    if( this.reserved[ i ].enemy.isDead( ) )\n      continue ;\n    while( this.reserved[ i ].index < this.reserved[ i ].array.length &&\n           this.reserved[ i ].count >= this.reserved[ i ].array[ this.reserved[ i ].index ].count ) {\n      // TODO: temporal\n      if(! this.gameState.isBombExist()) {\n        this.addElement(\n          this.factory.create(\n            this.reserved[ i ].enemy,\n            this.reserved[ i ].array[ this.reserved[ i ].index ],\n            this.reserved[ i ].shot ) ) ;\n        this.gameState.notifyEnemyDidShot( this.reserved[ i ].enemy,\n                                           this.reserved[ i ].shot ) ;\n      }\n      this.reserved[ i ].index++ ;\n    }\n  }\n} ;\n\n\nEnemyBulletManager.prototype.create = function( enemy, shot ) {\n  // TODO: temporal. to make reserved manager?\n  if(this.params[shot.bullet][0].count !== void 0) {\n    var r = this.reserved[ this.reservedLength ] ;\n    r.enemy = enemy ;\n    r.index = 0 ;\n    r.count = 0 ;\n    r.shot  = shot ;\n    r.array = this.params[ shot.bullet ] ;\n    this.reservedLength++ ;\n    return ;\n  }\n\n  for( var i = 0; i < this.params[ shot.bullet ].length; i++ ) {\n    if(! this.gameState.isBombExist()) {\n      this.addElement( this.factory.create( enemy, this.params[ shot.bullet ][ i ], shot ) ) ;\n      this.gameState.notifyEnemyDidShot( enemy, shot ) ;\n    }\n  }\n} ;\n\n\n__copyParentMethod(EnemyBulletManager, ElementManager, 'checkLoss');\nEnemyBulletManager.prototype.checkLoss = function( ) {\n  this.ElementManager_checkLoss();\n\n  // TODO: temporal. to use freelist?\n  var j = 0 ;\n  for( var i = 0; i < this.reservedLength; i++ ) {\n    if( ! this.reserved[ i ].enemy.isDead( ) && this.reserved[ i ].index < this.reserved[ i ].array.length ) {\n      var tmp = this.reserved[ i - j ] ;\n      this.reserved[ i - j ] = this.reserved[ i ] ;\n      this.reserved[ i ] = tmp ;\n    } else {\n      j++ ;\n    }\n  }\n  this.reservedLength -= j ;\n\n};\n\n\n/**\n * TODO: temporal\n */\nEnemyBulletManager.prototype.clearReserved = function( enemy ) {\n  this.reservedLength = 0 ;\n} ;\n\n\n__copyParentMethod(EnemyBulletManager, ElementManager, 'checkCollisionWith');\nEnemyBulletManager.prototype.checkCollisionWith = function(fighter) {\n  if(fighter.isFlagSet(fighter._FLAG_UNHITTABLE))\n    return;\n  this.ElementManager_checkCollisionWith(null, fighter, this, true);\n};\n\n\nEnemyBulletManager.prototype.checkCollisionWithFighters = function(fighters) {\n  for(var i = 0; i < fighters.length; i++) {\n    this.checkCollisionWith(fighters[i]);\n  }\n};\n\nEnemyBulletManager.prototype.notifyCollision = function(id, fighter, bullet) {\n  fighter.die();\n  this.gameState.notifyFighterDead(fighter, bullet);\n};\n\n\n__copyParentMethod(EnemyBulletManager, ElementManager, 'checkGrazeWith');\nEnemyBulletManager.prototype.checkGrazeWith = function(fighter) {\n  this.ElementManager_checkGrazeWith(null, fighter, this);\n};\n\n\nEnemyBulletManager.prototype.checkGrazeWithFighters = function(fighters) {\n  for(var i = 0; i < fighters.length; i++) {\n    this.checkGrazeWith(fighters[i]);\n  }\n};\n\n\nEnemyBulletManager.prototype.notifyGraze = function(id, fighter,\n    bullet) {\n  this.gameState.notifyGraze(fighter, bullet);\n};\n\n\n/**\n * TODO: temporal\n */\nEnemyBulletManager.prototype.bomb = function( fighter ) {\n  for( var i = 0; i < this.elements.length; i++ ) {\n    this.elements[ i ].die( ) ;\n    this.gameState.notifyBeScoreItem(fighter, this.elements[i]);\n  }\n} ;\n\n\nEnemyBulletManager.prototype.removeBulletsOfEnemy = function( enemy ) {\n  for( var i = 0; i < this.elements.length; i++ ) {\n    if( this.elements[ i ].enemy == enemy )\n      this.elements[ i ].die( ) ;\n  }\n} ;\n\n\nEnemyBulletManager.prototype.beItem = function(fighter) {\n  for( var i = 0; i < this.elements.length; i++ ) {\n    this.elements[ i ].die( ) ;\n    this.gameState.notifyBeScoreItem(fighter, this.elements[i]);\n  }\n  // TODO: temporal\n  this.clearReserved( ) ;\n} ;\n\n\nEnemyBulletManager.prototype.draw = function(layer) {\n  this.drawer.draw(layer);\n  this.beamDrawer.draw(layer);\n};\n\n\n\nfunction EnemyBulletFactory( gameState, maxX, maxY ) {\n  this.parent = ElementFactory ;\n\n  this.beamFreelist = null ;\n  this.laserFreelist = null ;\n\n  this.parent.call( this, gameState, maxX, maxY ) ;\n  this.types = __enemyBulletTypes ; // TODO: temporal\n\n  // TODO: temporal\n  this.image = null;\n  this.beamImage = null;\n}\n__inherit( EnemyBulletFactory, ElementFactory ) ;\n\nEnemyBulletFactory.prototype._NUM = 1000 ;\nEnemyBulletFactory.prototype._BEAM_NUM = 100 ;\nEnemyBulletFactory.prototype._LASER_NUM = 50 ;\n\n\nEnemyBulletFactory.prototype._initFreelist = function() {\n  this.freelist      = new EnemyBulletFreeList(this._NUM, this.gameState);\n  this.beamFreelist  = new EnemyBeamFreeList(this._BEAM_NUM, this.gameState);\n  this.laserFreelist = new EnemyLaserFreeList(this._LASER_NUM, this.gameState);\n};\n\n\n// TODO: temporal\nEnemyBulletFactory.prototype.create = function( enemy, params, shot ) {\n  // TODO: temporal. How can I remove this save and restore.\n  var preX = params.x ;\n  var preY = params.y ;\n  var preR = params.r ;\n  var preBaseTheta = params.baseTheta ;\n\n  params.r = shot.r ;\n  params.baseTheta = shot.baseTheta ;\n\n  params.x = ( params.x ? params.x : 0 ) + enemy.getX( ) + ( shot.x ? shot.x : 0 ) ;\n  params.y = ( params.y ? params.y : 0 ) + enemy.getY( ) + ( shot.y ? shot.y : 0 ) ;\n  var bullet ;\n  if( params.beam ) {\n    bullet = this.beamFreelist.get( ) ;\n    bullet.init( params, this._getImage( params ), enemy ) ;\n  } else if( params.laser ) {\n    bullet = this.laserFreelist.get( ) ;\n    bullet.init( params, this._getImage( params ), enemy ) ;\n  } else {\n    var key = shot.type ? shot.type : 0 ;\n    bullet = this.freelist.get( ) ;\n    bullet.init( params, this._getImage( params ), enemy, this.types[ key ] ) ;\n  }\n  params.x = preX ;\n  params.y = preY ;\n  params.r = preR ;\n  params.baseTheta = preBaseTheta ;\n  return bullet ;\n} ;\n\n\nEnemyBulletFactory.prototype.free = function(bullet) {\n  switch(bullet._ID) {\n    case this.EnemyBulletManager._ID_BULLET:\n      this.freelist.free(bullet);\n      return;\n    case this.EnemyBulletManager._ID_LASER:\n      this.laserFreelist.free(bullet);\n      return;\n    case this.EnemyBulletManager._ID_BEAM:\n      this.beamFreelist.free(bullet);\n      return;\n    default:\n      // throw exception?\n  }\n};\n\n\n/**\n * TODO: temporal\n */\nEnemyBulletFactory.prototype._getImage = function(params) {\n  if(params.beam) {\n    if(this.beamImage === null)\n      this.beamImage = this.gameState.getImage(Game._IMG_BEAM);\n    return this.beamImage;\n  } else {\n    if(this.image === null)\n      this.image = this.gameState.getImage(Game._IMG_ENEMY_SHOT);\n    return this.image;\n  }\n};\n\n\n\nfunction EnemyBulletFreeList( num, gameState ) {\n  this.parent = ElementFreeList ;\n  this.parent.call( this, num, gameState ) ;\n} ;\n__inherit( EnemyBulletFreeList, ElementFreeList ) ;\n\n\nEnemyBulletFreeList.prototype._generateElement = function( ) {\n  return new EnemyBullet( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\n\nfunction EnemyBulletDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(EnemyBulletDrawer, ElementDrawer);\n\n\nEnemyBulletDrawer.prototype._doPour = function(e) {\n  return (e._ID === this.elementManager._ID_BEAM) ? false : true;\n};\n\n\n\nfunction EnemyBulletView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(EnemyBulletView, ElementView);\n\n\n\nfunction EnemyBullet( gameState, maxX, maxY ) {\n  this.parent = Element ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n\n  this.enemy = null ;\n  this.rotate = false ;\n}\n__inherit( EnemyBullet, Element ) ;\n\n\n__copyParentMethod(EnemyBullet, Element, 'init');\nEnemyBullet.prototype.init = function(params, image, enemy, params2) {\n  this.Element_init(params, image);\n  this.enemy = enemy;\n\n  this.width           = params2.width;\n  this.height          = params2.height;\n  this.collisionWidth  = params2.collisionWidth;\n  this.collisionHeight = params2.collisionHeight;\n  this.indexX          = params2.indexX;\n  this.indexY          = params2.indexY;\n  this.rotate          = params2.rotate;\n  this.grazeWidth      = this.width;\n  this.grazeHeight     = this.height;\n  this._initView();\n};\n\n\nEnemyBullet.prototype._generateView = function() {\n  return new EnemyBulletView(this);\n};\n\n\nEnemyBullet.prototype.display = function( surface ) {\n  this.parent.prototype.display.call( this, surface, this.rotate ) ;\n} ;\n\n\n\nfunction EnemyLaserFreeList( num, gameState ) {\n  this.parent = ElementFreeList ;\n  this.parent.call( this, num, gameState ) ;\n} ;\n__inherit( EnemyLaserFreeList, ElementFreeList ) ;\n\n\nEnemyLaserFreeList.prototype._generateElement = function( ) {\n  return new EnemyLaser( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\n\nfunction EnemyLaserView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(EnemyLaserView, ElementView);\n\n\n__copyParentMethod(EnemyLaserView, ElementView, '_initVertices');\nEnemyLaserView.prototype._initVertices = function() {\n  this.ElementView_initVertices();\n  this.vertices[1] = 0;\n  this.vertices[4] = 0;\n  this.vertices[7] *= 2;\n  this.vertices[10] *= 2;\n};\n\n\n__copyParentMethod(EnemyLaserView, ElementView, '_initCoordinates');\nEnemyLaserView.prototype._initCoordinates = function() {\n  this.ElementView_initCoordinates();\n  // TODO: temporal.\n  var s = 0.01;\n  var h = this.element.getWidth()/this.element.getImageHeight();\n  var y1 = h * this.element.getImageIndexY();\n  var y2 = y1 + h - s;\n\n  this.coordinates[1] = y2;\n  this.coordinates[3] = y2;\n  this.coordinates[5] = y1;\n  this.coordinates[7] = y1;\n};\n\n\n/**\n * TODO: should be in EnemyLaser?\n */\nEnemyLaserView.prototype.animate = function() {\n  var w = this.element.getWidth()/2;\n  if(this.element.count < this.element.waitCount) {\n    w = w * this.element.count / this.element.waitCount ;\n    this.a = 0.2;\n  } else if (this.element.inExtendTime()) {\n    w = w * (this.element.keepAlive + this.element._EXTEND_COUNT\n               - this.element.count)\n            / this.element._EXTEND_COUNT;\n    this.a = 0.2;\n  } else {\n    this.a = 0.8;\n  }\n\n  this.vertices[0] = -w;\n  this.vertices[3] =  w;\n  this.vertices[6] =  w;\n  this.vertices[9] = -w;\n};\n\n\n\n/**\n * TODO: temporal\n */\nfunction EnemyLaser( gameState, maxX, maxY ) {\n  this.parent = Element ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n  this.baseX = 0 ;\n  this.baseY = 0 ;\n}\n__inherit( EnemyLaser, Element ) ;\n\n// only for reference\nEnemyLaser.prototype.Math = Math;\n\n// TODO: temporal\nEnemyLaser.prototype._WIDTH = 16; \nEnemyLaser.prototype._HEIGHT = 400 * 2;\nEnemyLaser.prototype._EXTEND_COUNT = 20;\n\n\n__copyParentMethod(EnemyLaser, Element, 'init');\nEnemyLaser.prototype.init = function(params, image, enemy) {\n  this.Element_init(params, image);\n\n  this.enemy = enemy;\n  this.width = this._WIDTH;\n  this.height = this._HEIGHT;\n  this.collisionWidth = this.width;\n  this.collisionHeight = this.height;\n\n  this.waitCount = this._getValueOrDefaultValue(params.waitCount, 0);\n  this.keepAlive = this._getValueOrDefaultValue(params.keep, 0);\n  this.baseX = this.Math.round(enemy.getX());\n  this.baseY = this.Math.round(enemy.getY());\n  this.indexX = 15;\n  this.indexY = 0;\n  this._initView();\n};\n\n\nEnemyLaser.prototype._generateView = function() {\n  return new EnemyLaserView(this);\n};\n\n\n/**\n * TODO: temporal\n */\nEnemyLaser.prototype.display = function( surface ) {\n  surface.save( ) ;\n  var width = this.getWidth( ) ;\n  if( this.count < this.waitCount ) {\n    width = width * this.count / this.waitCount ;\n    surface.globalAlpha = 0.2 ;\n  } else if ( this.count + 10 > this.keepAlive ) {\n    width = width * ( 10 - this.count + this.keepAlive ) / 10 ;\n    surface.globalAlpha = 0.2 ;\n  } else {\n    surface.globalAlpha = 0.8 ;\n  }\n  var x = Math.round( this.getCenterX( ) ) ;\n  var y = Math.round( this.getCenterY( ) - width / 2 ) ;\n  surface.translate( this.baseX, this.baseY ) ;\n  surface.rotate( this._calculateRadian( this.vector.theta ) ) ;\n  surface.translate( -this.baseX, -this.baseY ) ;\n  surface.drawImage( this.image,\n                     this.getWidth( ) * this.indexX, this.height * this.indexY,\n                     this.getWidth( ),               this.getWidth( ),\n                     x,                              y,\n                     this.height,                    width ) ;\n  surface.restore( ) ;\n//  surface.fillText( x + ':' + y, x, y ) ;\n} ;\n\n\nEnemyLaser.prototype._getTheta = function( ) {\n  return this._calculateRadian( this.vector.theta ) ;\n} ;\n\n\nEnemyLaser.prototype.getUpLeftX = function( ) {\n  return this.getCenterX( ) - ( this.getWidth( ) / 2 ) * this.Math.cos( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getUpLeftY = function( ) {\n  return this.getCenterY( ) - ( this.getWidth( ) / 2 ) * this.Math.sin( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getUpRightX = function( ) {\n  return this.getCenterX( ) + ( this.getWidth( ) / 2 ) * this.Math.cos( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getUpRightY = function( ) {\n  return this.getCenterY( ) + ( this.getWidth( ) / 2 ) * this.Math.sin( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getBottomLeftX = function( ) {\n  return this.getUpLeftX( ) + this.getHeight( ) * this.Math.cos( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getBottomLeftY = function( ) {\n  return this.getUpLeftY( ) + this.getHeight( ) * this.Math.sin( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getBottomRightX = function( ) {\n  return this.getUpRightX( ) + this.getHeight( ) * this.Math.cos( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getBottomRightY = function( ) {\n  return this.getUpRightY( ) + this.getHeight( ) * this.Math.sin( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getCollisionUpLeftX = function( ) {\n  return this.getCenterX( ) - ( this.collisionWidth / 2 ) * this.Math.sin( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getCollisionUpLeftY = function( ) {\n  return this.getCenterY( ) + ( this.collisionWidth / 2 ) * this.Math.cos( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getCollisionUpRightX = function( ) {\n  return this.getCenterX( ) + ( this.collisionWidth / 2 ) * this.Math.sin( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getCollisionUpRightY = function( ) {\n  return this.getCenterY( ) - ( this.collisionWidth / 2 ) * this.Math.cos( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getCollisionBottomLeftX = function( ) {\n  return this.getCollisionUpLeftX( ) + this.collisionHeight * this.Math.cos( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getCollisionBottomLeftY = function( ) {\n  return this.getCollisionUpLeftY( ) + this.collisionHeight * this.Math.sin( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getCollisionBottomRightX = function( ) {\n  return this.getCollisionUpRightX( ) + this.collisionHeight * this.Math.cos( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.getCollisionBottomRightY = function( ) {\n  return this.getCollisionUpRightY( ) + this.collisionHeight * this.Math.sin( this._getTheta( ) ) ;\n} ;\n\n\nEnemyLaser.prototype.inCollisionArea = function( x, y ) {\n\n  if(this.inExtendTime() || this.overExtendTime())\n    return false;\n\n  if(! this._inCollisionTheta(\n         this.getCollisionUpRightX(), this.getCollisionUpRightY(),\n         x,                           y,\n         this.getCollisionUpLeftX(),  this.getCollisionUpLeftY()\n     ))\n    return false;\n\n  if(! this._inCollisionTheta(\n         this.getCollisionBottomLeftX(),   this.getCollisionBottomLeftY(),\n         x,                                y,\n         this.getCollisionBottomRightX(),  this.getCollisionBottomRightY()\n     ))\n    return false;\n\n  return true;\n\n};\n\n\nEnemyLaser.prototype._inCollisionTheta = function( x1, y1, x2, y2, baseX, baseY ) {\n  var ax1 = x1 - baseX ;\n  var ax2 = x2 - baseX ;\n  var ay1 = y1 - baseY ;\n  var ay2 = y2 - baseY ;\n  var t = this._calculateTheta( this.Math.atan2( ax1 * ay2 - ax2 * ay1, ax1 * ax2 + ay1 * ay2 ) ) ;\n  if( t >= 0 && t <= 90 )\n    return true ;\n  return false ;  \n} ;\n\n\nEnemyLaser.prototype.inViewArea = function( x, y ) {\n  return false ;\n} ;\n\n\nEnemyLaser.prototype.checkViewCollision = function( e ) {\n  return false ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nEnemyLaser.prototype.checkLoss = function() {\n  if(this.isDead())\n    return true;\n  if(this.overExtendTime())\n    return true;\n  return false;\n};\n\n\nEnemyLaser.prototype.inExtendTime = function() {\n  if(this.keepAlive &&\n     this.count >= this.keepAlive && \n     this.count < this.keepAlive + this._EXTEND_COUNT)\n    return true;\n  return false;\n};\n\n\nEnemyLaser.prototype.overExtendTime = function() {\n  if(this.keepAlive &&\n     this.count >= this.keepAlive + this._EXTEND_COUNT)\n    return true;\n  return false;\n};\n\n\nfunction EnemyBeamFreeList(num, gameState) {\n  this.parent = ElementFreeList;\n  this.hFreelist = new EnemyBeamHistoryFreeList(this._HISTORY_NUM);\n  this.pFreelist = new EnemyBeamPositionFreeList(this._HISTORY_NUM);\n  this.parent.call(this, num, gameState);\n};\n__inherit(EnemyBeamFreeList, ElementFreeList);\n\nEnemyBeamFreeList.prototype._HISTORY_NUM = 1000; \n\n\nEnemyBeamFreeList.prototype._generateElement = function( ) {\n  return new EnemyBeam( this.gameState,\n                        this.gameState.getWidth( ),\n                        this.gameState.getHeight( ),\n                        this.hFreelist,\n                        this.pFreelist ) ;\n} ;\n\n\n\nfunction EnemyBeamDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(EnemyBeamDrawer, ElementDrawer);\n\n\nEnemyBeamDrawer.prototype._doPour = function(e) {\n  return (e._ID === this.elementManager._ID_BEAM) ? true : false;\n};\n\n\n\nfunction EnemyBeamView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n\n  // TODO: temporal\n  this.vertices.length = this._V_SIZE * element.historyMax;\n  this.coordinates.length = this._C_SIZE * element.historyMax;\n  this.indices.length = this._I_SIZE * element.historyMax;\n  this.colors.length = this._A_SIZE * element.historyMax;\n  this.sVertices.length = this._V_SIZE * element.historyMax;\n};\n__inherit(EnemyBeamView, ElementView);\n\n\n/**\n * TODO: temporal.\n */\nEnemyBeamView.prototype.getNum = function() {\n  return this.element.p.length;\n};\n\n\nEnemyBeamView.prototype._initVertices = function() {\n  for(var i = 0; i < this.element.p.length; i++) {\n    var p = this.element.p[i];\n    var o = this._V_SIZE * i;\n    this.vertices[o+0]  =  p.x0;\n    this.vertices[o+1]  = -p.y0;\n    this.vertices[o+2]  = -1.0;\n    this.vertices[o+3]  =  p.x1;\n    this.vertices[o+4]  = -p.y1;\n    this.vertices[o+5]  = -1.0;\n    this.vertices[o+6]  =  p.x3;\n    this.vertices[o+7]  = -p.y3;\n    this.vertices[o+8]  = -1.0;\n    this.vertices[o+9]  =  p.x2;\n    this.vertices[o+10] = -p.y2;\n    this.vertices[o+11] = -1.0;\n  }\n};\n\n\nEnemyBeamView.prototype._initCoordinates = function() {\n  // TODO: temporal\n  var w = this.element.imageWidth/this.element.getImageWidth();\n  var h = this.element.imageHeight/this.element.getImageHeight();\n\n  var x1 = w * this.element.getImageIndexX();\n  var x2 = x1 + w;\n  var y = h * this.element.getImageIndexY();\n  var dy = h / this.element.p.length;\n\n  for(var i = 0; i < this.element.p.length; i++) {\n    var o = this._C_SIZE * i;\n    var y1 = y + dy * i;\n    var y2 = y + dy * (i+1);\n    // y order is reversed from the normal one.\n    this.coordinates[o+0] = x1;\n    this.coordinates[o+1] = y1;\n    this.coordinates[o+2] = x2;\n    this.coordinates[o+3] = y1;\n    this.coordinates[o+4] = x2;\n    this.coordinates[o+5] = y2;\n    this.coordinates[o+6] = x1;\n    this.coordinates[o+7] = y2;\n  }\n};\n\n\nEnemyBeamView.prototype._initIndices = function() {\n  for(var i = 0; i < this.element.p.length; i++) {\n    var o = this._I_SIZE * i;\n    this.indices[o+0] = 0;\n    this.indices[o+1] = 1;\n    this.indices[o+2] = 2;\n\n    this.indices[o+3] = 0;\n    this.indices[o+4] = 2;\n    this.indices[o+5] = 3;\n  }\n};\n\n\nEnemyBeamView.prototype._initColors = function() {\n  for(var i = 0; i < this.element.p.length; i++) {\n    var o = this._A_SIZE * i;\n    this.colors[o+0] = 1.0;\n    this.colors[o+1] = 1.0;\n    this.colors[o+2] = 1.0;\n    this.colors[o+3] = 1.0;\n\n    this.colors[o+4] = 1.0;\n    this.colors[o+5] = 1.0;\n    this.colors[o+6] = 1.0;\n    this.colors[o+7] = 1.0;\n\n    this.colors[o+8] = 1.0;\n    this.colors[o+9] = 1.0;\n    this.colors[o+10] = 1.0;\n    this.colors[o+11] = 1.0;\n\n    this.colors[o+12] = 1.0;\n    this.colors[o+13] = 1.0;\n    this.colors[o+14] = 1.0;\n    this.colors[o+15] = 1.0;\n  }\n};\n\n\n/**\n * unnecessary to translate cuz it's already done in EnemyBeam.\n */\nEnemyBeamView.prototype.translate = function() {\n};\n\n\n/**\n * unnecessary to rotate cuz it's already done in EnemyBeam.\n */\nEnemyBeamView.prototype.rotate = function() {\n};\n\n\n/**\n * unnecessary to save vertices cuz translate() and rotate() do nothing.\n */\nEnemyBeamView.prototype.saveVertices = function() {\n};\n\n\n/**\n * unnecessary to restore vertices cuz translate() and rotate() do nothing.\n */\nEnemyBeamView.prototype.restoreVertices = function() {\n};\n\n\nEnemyBeamView.prototype.animate = function() {\n  this._initVertices();\n  this._initCoordinates();\n  this._initIndices();\n  this._initColors();\n  this.a = 0.9;\n};\n\n\n/**\n * TODO: temporal\n * TODO: add histories, p, hFreelist and pFreelist descriptions.\n * TODO: implement checkColision().\n */\nfunction EnemyBeam(gameState, maxX, maxY, hFreelist, pFreelist) {\n  this.histories = [];\n  this.p = [];\n  this.hFreelist = hFreelist;\n  this.pFreelist = pFreelist;\n  this.historyMax = this._HISTORY_MAX;\n\n  this.parent = Element;\n  this.parent.call(this, gameState, maxX, maxY);\n  this.imageWidth = this._IMAGE_WIDTH;\n  this.imageHeight = this._IMAGE_HEIGHT;\n}\n__inherit(EnemyBeam, Element);\n\n// only for reference\nEnemyBeam.prototype.Math = Math;\n\nEnemyBeam.prototype._WIDTH  = 16;\nEnemyBeam.prototype._HEIGHT = 16;\n\nEnemyBeam.prototype._IMAGE_WIDTH  = 20;\nEnemyBeam.prototype._IMAGE_HEIGHT = 256;\n\nEnemyBeam.prototype._HISTORY_MAX = 16;\n\nEnemyBeam.prototype._SPAN = 1;\n\n\nEnemyBeam.prototype._generateView = function() {\n  return new EnemyBeamView(this);\n};\n\n\n__copyParentMethod(EnemyBeam, Element, 'free');\nEnemyBeam.prototype.free = function() {\n  this._freeHistoriesUntil(0);\n  this._freePositionsUntil(0);\n  this.Element_free();\n};\n\n\nEnemyBeam.prototype._freeHistoriesUntil = function(num) {\n  while(this.histories.length > num) {\n    this.hFreelist.free(this.histories[this.histories.length-1]) ;\n    this.histories.length--;\n  }\n};\n\n\nEnemyBeam.prototype._freePositionsUntil = function(num) {\n  while(this.p.length > num){\n    this.pFreelist.free(this.p[this.p.length-1]);\n    this.p.length--;\n  }\n};\n\n\n__copyParentMethod(EnemyBeam, Element, 'init');\nEnemyBeam.prototype.init = function(params, image, enemy) {\n  this.Element_init(params, image);\n  this.enemy = enemy;\n\n  // TODO: temporal\n  this.width = this._WIDTH;\n  this.height = this._HEIGHT;\n  this.collisionWidth = this.width;\n  this.collisionHeight = this.height;\n\n  this.indexX = 1;\n  this.indexY = 0;\n  this.histories.length = 0;\n  this.p.length = 0;\n  this._initView();\n};\n\n\n__copyParentMethod(EnemyBeam, Element, 'runStep');\nEnemyBeam.prototype.runStep = function() {\n  this.Element_runStep();\n  if((this.count % this._SPAN) == 0) {\n    this._addHistory();\n    this._freeHistoriesUntil(this.historyMax);\n    this._freePositionsUntil(this.historyMax);\n  }\n};\n\n\nEnemyBeam.prototype._addHistory = function() {\n\n  var h = this.hFreelist.get();\n  h.x = this.getX();\n  h.y = this.getY();\n  if(this.histories.length > 0) {\n    var x1 = h.x;\n    var y1 = h.y;\n    var x2 = this.histories[0].x;\n    var y2 = this.histories[0].y;\n    var dx = x1 - x2;\n    var dy = y1 - y2; \n    var rad = this.Math.atan2(dy, dx);\n    var p = this.pFreelist.get();\n\n    p.x0 = x1 - this.width/2 * this.Math.sin(rad);\n    p.y0 = y1 + this.width/2 * this.Math.cos(rad);\n    p.x1 = x1 + this.width/2 * this.Math.sin(rad);\n    p.y1 = y1 - this.width/2 * this.Math.cos(rad);\n    p.x2 = x2 - this.width/2 * this.Math.sin(rad);\n    p.y2 = y2 + this.width/2 * this.Math.cos(rad);\n    p.x3 = x2 + this.width/2 * this.Math.sin(rad);\n    p.y3 = y2 - this.width/2 * this.Math.cos(rad);\n\n    if(this.p.length > 0) {\n      this.p[0].x0 = p.x2;\n      this.p[0].y0 = p.y2;\n      this.p[0].x1 = p.x3;\n      this.p[0].y1 = p.y3;\n    }\n\n    this.p.unshift(p);\n  }\n  this.histories.unshift(h);\n\n};\n\n\n/**\n * TODO: temporal, make this function fast.\n */\nEnemyBeam.prototype.display = function( surface ) {\n\n  var height = this.imageHeight / this.histories.length ;\n  var width = this.imageWidth ;\n\n  var p = this.p ;\n  for( var i = 0; i < this.histories.length - 1; i++ ) {\n    var by = height * i ;\n\n    surface.save( ) ;\n/*\n    surface.beginPath( ) ;\n    surface.strokeStyle = 'white' ;\n    surface.moveTo( p[ i ].x0, p[ i ].y0 ) ;\n    surface.lineTo( p[ i ].x1, p[ i ].y1 ) ;\n    surface.lineTo( p[ i ].x3, p[ i ].y3 ) ;\n    surface.lineTo( p[ i ].x2, p[ i ].y2 ) ;\n    surface.closePath( ) ;\n    surface.clip( ) ;\n//    surface.stroke( ) ;\n*/\n    var t1 = ( p[ i ].x1 - p[ i ].x0 ) / width ;\n    var t2 = ( p[ i ].y1 - p[ i ].y0 ) / width ;\n    var t3 = ( p[ i ].x2 - p[ i ].x0 ) / height ;\n    var t4 = ( p[ i ].y2 - p[ i ].y0 ) / height ;\n    var t5 = p[ i ].x0 ;\n    var t6 = p[ i ].y0 ;\n    surface.setTransform( t1, t2, t3, t4, t5, t6 ) ;\n\n    surface.globalAlpha = 0.5 ;\n    surface.drawImage( this.image,\n                       width,\n                       by,\n                       width,\n                       height,\n                       0,\n                       0,\n                       width,\n                       height ) ;\n\n    surface.restore( ) ;\n\n\n    surface.save( ) ;\n/*\n    surface.beginPath( ) ;\n    surface.strokeStyle = 'white' ;\n    surface.moveTo( p[ i ].x1, p[ i ].y1 ) ;\n    surface.lineTo( p[ i ].x2, p[ i ].y2 ) ;\n    surface.lineTo( p[ i ].x3, p[ i ].y3 ) ;\n    surface.closePath( ) ;\n    surface.clip( ) ;\n//    surface.stroke( ) ;\n*/\n    var t1 = ( p[ i ].x3 - p[ i ].x2 ) / width ;\n    var t2 = ( p[ i ].y3 - p[ i ].y2 ) / width ;\n    var t3 = ( p[ i ].x3 - p[ i ].x1 ) / height ;\n    var t4 = ( p[ i ].y3 - p[ i ].y1 ) / height;\n    var t5 = p[ i ].x2 ;\n    var t6 = p[ i ].y2 ;\n    surface.setTransform( t1, t2, t3, t4, t5, t6 ) ;\n\n    surface.globalAlpha = 0.5 ;\n    surface.drawImage( this.image,\n                       width,\n                       by,\n                       width,\n                       height,\n                       0,\n                       0,\n                       width,\n                       -height ) ;\n\n    surface.restore( ) ;\n\n  }\n\n} ;\n\n\n/**\n * TODO: temporal\n */\nEnemyBeam.prototype._outOfTheField = function( ) {\n  var x = this.histories[ this.histories.length - 1 ].x ;\n  var y = this.histories[ this.histories.length - 1 ].y ;\n  if( x < 0 || x > this.maxX ||\n      y < 0 || y > this.maxY )\n    return true ;\n  return false ;\n} ;\n\n\n\nfunction EnemyBeamHistoryFreeList( num ) {\n  FreeList.call( this, num ) ;\n}\n__inherit( EnemyBeamHistoryFreeList, FreeList ) ;\n\n\nEnemyBeamHistoryFreeList.prototype._generateElement = function( ) {\n  return {\n    'x0': 0.0,\n    'y0': 0.0,\n    'x1': 0.0,\n    'y1': 0.0,\n    'x2': 0.0,\n    'y2': 0.0,\n    'x3': 0.0,\n    'y3': 0.0\n  } ;\n} ;\n\n\n\nfunction EnemyBeamPositionFreeList( num ) {\n  FreeList.call( this, num ) ;\n}\n__inherit( EnemyBeamPositionFreeList, FreeList ) ;\n\n\nEnemyBeamPositionFreeList.prototype._generateElement = function( ) {\n  return { 'x': 0.0, 'y': 0.0 } ;\n} ;\n\n\n\n// TODO: remove the followings because they complicate the design.\nEnemyBulletManager.prototype._ID_BULLET = 0;\nEnemyBulletManager.prototype._ID_LASER  = 1;\nEnemyBulletManager.prototype._ID_BEAM   = 2;\n\nEnemyBulletFactory.prototype.EnemyBulletManager = EnemyBulletManager.prototype;\n\nEnemyBullet.prototype._ID = EnemyBulletManager.prototype._ID_BULLET;\nEnemyLaser.prototype._ID  = EnemyBulletManager.prototype._ID_LASER;\nEnemyBeam.prototype._ID   = EnemyBulletManager.prototype._ID_BEAM;\n\n"
  },
  {
    "path": "source/Fighter.js",
    "content": "/**\n * care for two players in the future.\n */\nfunction FighterManager(gameState) {\n  this.parent = ElementManager;\n  this.parent.call(this, gameState);\n  this.id = 0;\n  this._init();\n};\n__inherit(FighterManager, ElementManager);\n\nFighterManager.prototype._MAX_NUM = 2;\n\nFighterManager.prototype.Randomizer = __randomizer;\nFighterManager.prototype.Math = Math;\n\n\nFighterManager.prototype._initMaxNum = function() {\n  return this._MAX_NUM;\n};\n\n\n/**\n * Note: not return the resouces to freelist.\n */\nFighterManager.prototype.reset = function() {\n  for(var i = 0; i < this.elements.length; i++) {\n    this.elements[i].reset();\n    this.elements[i].beDefaultPosition();\n  }\n  this.count = 0;\n};\n\n\nFighterManager.prototype.recoverWhenContinue = function() {\n  for(var i = 0; i < this.elements.length; i++) {\n    this.elements[i].recoverWhenContinue();\n  }\n};\n\n\nFighterManager.prototype.beNeutral = function() {\n  for(var i = 0; i < this.elements.length; i++) {\n    this.elements[i].beNeutral();\n  }\n};\n\n\nFighterManager.prototype.getFighter = function() {\n  return this.get(0);\n};\n\n\nFighterManager.prototype.getRandom = function() {\n  return this.get((this.Randomizer.random() * this.elements.length) | 0);\n};\n\n\nFighterManager.prototype.getMe = function(isMaster) {\n  return this.get(isMaster ? 0 : 1);\n};\n\n\nFighterManager.prototype.getOther = function(isMaster) {\n  return this.get(isMaster ? 1 : 0);\n};\n\n\nFighterManager.prototype._init = function() {\n  this.add(this._createFighter());\n  this.get(0).beDefaultPosition();\n\n  if(this.gameState.isMultiPlay()) {\n    this.add(this._createFighter());\n    this.get(1).beDefaultPosition();\n  }\n};\n\n\nFighterManager.prototype._createFighter = function() {\n  return new Fighter(this.gameState,\n                     this.gameState.getWidth(),\n                     this.gameState.getHeight(),\n                     this._getImage(),\n                     this.id++);\n};\n\n\n/**\n * unnecessary.\n */\nFighterManager.prototype._initFactory = function() {\n};\n\n\nFighterManager.prototype.initDrawer = function(layer, image) {\n  this.drawer = new FighterDrawer(this, layer, this._getImage());\n};\n\n\nFighterManager.prototype._getImage = function() {\n  return this.gameState.getImage(Game._IMG_FIGHTER);\n};\n\n\n// TODO: duplicated code.\n// TODO: check Active numbers\nFighterManager.prototype.getClosestFighter = function(e) {\n  var target = this.get(0);\n  if(this.elements.length <= 1)\n    return target;\n\n  var min = 1024 * 1024; // TODO: temporal\n  for(var i = 0; i < this.elements.length; i++) {\n    var f = this.get(i);\n    var d = this.Math.pow(f.getX() - e.getX(), 2) +\n              this.Math.pow(f.getY() - e.getY(), 2);\n    if(d < min) {\n      min = d;\n      target = f;\n    }\n  }\n  return target;\n};\n\n\n\nfunction FighterDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(FighterDrawer, ElementDrawer);\n\n\n\n/**\n * TODO: consider if should make Reimu/Marisa View.\n */\nfunction FighterView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(FighterView, ElementView);\n\n\n/**\n * no rotate.\n * TODO: no rotate impl should be in parent class?\n */\nFighterView.prototype.rotate = function() {\n};\n\n\nFighterView.prototype.animate = function() {\n  this._initCoordinates();\n  // TODO: temporal\n  this.a = this.element.isFlagSet(this.element._FLAG_UNHITTABLE) ||\n           this.element.gameState.doLookAtFromViewpointTarget() ? 0.7 : 1.0;\n};\n\n\nFighterView.prototype.doRotateForViewpoint = function() {\n  return true;\n};\n\n\n\nfunction Fighter(gameState, maxX, maxY, image, id) {\n  this.id = id;\n  this.characterIndex = 0;  // TODO: temporal\n  this.parent = Element;\n  this.parent.call(this, gameState, maxX, maxY);\n  this.image = image;\n  this.width = this._WIDTH;\n  this.height = this._HEIGHT;\n  this.collisionWidth = this._COLLISION_WIDTH[this.characterIndex];\n  this.collisionHeight = this._COLLISION_HEIGHT[this.characterIndex];\n  this.grazeWidth = this.width;\n  this.grazeHeight = this.height;\n  this.power = 0;\n  this.powerLevel = 0;\n  this.deadCount = 0;\n  this.spellCard = 'Special Spell'; // TODO: temporary\n  this.setFlag(this._FLAG_UNHITTABLE);\n  this.options = [];\n  this._initView();\n};\n__inherit(Fighter, Element);\n\n\n// TODO: temporal\nFighter.prototype._REIMU = 0 ;\nFighter.prototype._MARISA = 1 ;\n\n// TODO: prameters should be in parameter .js file.\nFighter.prototype._SHIP_IMAGE = [ Game._IMG_REIMU_SHIP, Game._IMG_MARISA_SHIP ] ;\nFighter.prototype._SPAN_FAST = [ 4, 5 ] ;\nFighter.prototype._SPAN_SLOW = [ 3, 4 ] ;\nFighter.prototype._COLLISION_WIDTH = [ 4, 6 ] ;\nFighter.prototype._COLLISION_HEIGHT = [ 4, 6 ] ;\n\nFighter.prototype._FLAG_SLOW = 0x1000 ;\n\nFighter.prototype._UNHITABLE_COUNT = 100 ;\n\nFighter.prototype._WIDTH = 32 ;\nFighter.prototype._HEIGHT = 48 ;\n\nFighter.prototype._ANIMATION_SPAN = 2 ;\n\n\nFighter.prototype.reset = function( ) {\n  this.state = this._STATE_ALIVE ;\n  this.flags = 0 ;\n  this.setFlag( this._FLAG_UNHITTABLE ) ;\n  this.power = 0 ;\n  this.powerLevel = 0 ;\n  this.deadCount = 0 ;\n  this.count = 0 ;\n  this.indexX = 0 ;\n  this.indexY = 0 ;\n} ;\n\n\nFighter.prototype._generateView = function() {\n  return new FighterView(this);\n};\n\n\nFighter.prototype.beDefaultPosition = function( ) {\n  this.setX( parseInt( this.maxX / 2 ) ) ;\n  this.setY( this.maxY - 100 ) ;\n} ;\n\n\nFighter.prototype.display = function( surface ) {\n  if( this.isFlagSet( this._FLAG_UNHITTABLE ) )\n    surface.globalAlpha = 0.7 ;\n//  surface.save( ) ;\n  this.parent.prototype.display.call( this, surface ) ;\n  if( this.isFlagSet( this._FLAG_UNHITTABLE ) )\n    surface.globalAlpha = 1.0 ;\n//  surface.restore( ) ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nFighter.prototype._setDirection = function( ) {\n  if( ( ! this.isFlagSet( this._FLAG_MOVE_LEFT ) &&\n        ! this.isFlagSet( this._FLAG_MOVE_RIGHT ) ) ||\n      (   this.isFlagSet( this._FLAG_MOVE_LEFT ) &&\n          this.isFlagSet( this._FLAG_MOVE_RIGHT ) ) ) {\n    this.indexY = 0 ;\n  } else if( this.isFlagSet( this._FLAG_MOVE_LEFT ) ) {\n    this.indexY = 1 ;\n    this.indexX = 7 ;\n  } else if( this.isFlagSet( this._FLAG_MOVE_RIGHT ) ) {\n    this.indexY = 2 ;\n    this.indexX = 7 ;\n  }\n} ;\n\n\nFighter.prototype.move = function( ) {\n\n  this._setDirection( ) ;\n  var d = this.isFlagSet( this._FLAG_SLOW )\n            ? this._SPAN_SLOW[ this.characterIndex ] : this._SPAN_FAST[ this.characterIndex ] ;\n  // TODO: temporal\n  if( this.isFlagSet( this._FLAG_MOVE_LEFT ) ) {\n    this.x -= d ;\n  }\n  if( this.isFlagSet( this._FLAG_MOVE_DOWN ) ) {\n    this.y += d ;\n  }\n  if( this.isFlagSet( this._FLAG_MOVE_RIGHT ) ) {\n    this.x += d ;\n  }\n  if( this.isFlagSet( this._FLAG_MOVE_UP ) ) {\n    this.y -= d ;\n  }\n  this._beInTheField( ) ;\n} ;\n\nFighter.prototype.Element_runStep = Element.prototype.runStep;\nFighter.prototype.runStep = function( ) {\n  if( this.isFlagSet( this._FLAG_UNHITTABLE ) && this.count > this._UNHITABLE_COUNT + this.deadCount ) {\n    this.clearFlag( this._FLAG_UNHITTABLE ) ;\n  }\n\n  this._shot( ) ;\n\n  this.Element_runStep();\n  if( this.count % this._ANIMATION_SPAN == 0 ) {\n    this.indexX++ ;\n    if( ! this.indexY && this.indexX > 7 )\n      this.indexX = 0 ;\n    else if( this.indexY && this.indexX > 7 )\n      this.indexX = 4 ;\n  }\n} ;\n\n\nFighter.prototype._shot = function( ) {\n  if( this.isFlagSet( this._FLAG_SHOT ) )\n    this.gameState.notifyFighterDoShot( this ) ;\n} ;\n\n\nFighter.prototype.getBulletIndex = function( ) {\n  return this.isFlagSet( this._FLAG_SLOW ) ? 1 : 0 ;\n} ;\n\n\nFighter.prototype.setCharacterIndex = function(index) {\n  this.characterIndex = index;\n  this._updateFighterInfoDependingCharacterIndex();\n};\n\n\n/**\n * TODO: temporal\n */\nFighter.prototype.changeCharacter = function( ) {\n  this.characterIndex++ ;\n  if( this.characterIndex > 1 )\n    this.characterIndex = 0 ;\n  this._updateFighterInfoDependingCharacterIndex( ) ;\n} ;\n\n\nFighter.prototype._updateFighterInfoDependingCharacterIndex = function() {\n  this.collisionWidth = this._COLLISION_WIDTH[ this.characterIndex ];\n  this.collisionHeight = this._COLLISION_HEIGHT[ this.characterIndex ];\n};\n\n\nFighter.prototype._initVector = function( ) {\n} ;\n\n\n/**\n * TODO: temporal\n */\nFighter.prototype.getPower = function( ) {\n  return this.power ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nFighter.prototype.getPowerLevel = function( ) {\n  return this.powerLevel > 3 ? 3 : this.powerLevel;\n} ;\n\n\nFighter.prototype._calculatePowerLevel = function( power ) {\n  if( this.power < 8 )\n    return 0 ;\n  if( this.power < 16 )\n    return 1 ;\n  if( this.power < 32 )\n    return 2 ;\n  if( this.power < 48 )\n    return 3 ;\n  if( this.power < 64 )\n    return 4 ;\n  if( this.power < 80 )\n    return 5 ;\n  if( this.power < 96 )\n    return 6 ;\n  if( this.power < 128 )\n    return 7 ;\n  return 8 ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nFighter.prototype.hasOption = function( ) {\n  return this.getPowerLevel( ) > 0 ? true : false ;\n} ;\n\n\nFighter.prototype.addOption = function(option) {\n  this.options.push(option);\n};\n\n\nFighter.prototype.getOption = function(index) {\n  return this.options[index];\n};\n\n\n/**\n * TODO: temporal\n */\nFighter.prototype.incrementPower = function( num ) {\n\n  var prePowerLevel = this._calculatePowerLevel( this.power ) ;\n  this.power += num ;\n\n  if( this.power > 128 ) {\n    this.power = 128 ;\n    return false ;\n  }\n\n  this.powerLevel = this._calculatePowerLevel( this.power ) ;\n\n  if( this.powerLevel > prePowerLevel )\n    this.gameState.notifyFighterPowerUp( ) ;\n\n} ;\n\n\nFighter.prototype.beNeutral = function( ) {\n  this.clearFlag( this._FLAG_SLOW ) ;\n  this.clearFlag( this._FLAG_MOVE_LEFT ) ;\n  this.clearFlag( this._FLAG_MOVE_UP ) ;\n  this.clearFlag( this._FLAG_MOVE_RIGHT ) ;\n  this.clearFlag( this._FLAG_MOVE_DOWN ) ;\n  this.clearFlag( this._FLAG_SHOT ) ;\n} ;\n\n\n/**\n * TODO: temporal. bad design.\n */\nFighter.prototype.Element_getImageIndexY = Element.prototype.getImageIndexY;\nFighter.prototype.getImageIndexY = function() {\n  return this.Element_getImageIndexY() + this.characterIndex * 3;\n};\n\n\nFighter.prototype.recoverWhenContinue = function() {\n  this.state = this._STATE_ALIVE;\n  this.setX((this.gameState.getWidth() / 2) | 0);\n  this.setY(this.gameState.getHeight() - 100);\n};\n\n\nFighter.prototype.getID = function() {\n  return this.id;\n};\n\n\n"
  },
  {
    "path": "source/FighterOption.js",
    "content": "function FighterOptionManager(gameState, fighters) {\n  this.parent = ElementManager;\n  this.parent.call(this, gameState);\n  this.fighters = fighters;\n  this._init();\n};\n__inherit(FighterOptionManager, ElementManager);\n\n\nFighterOptionManager.prototype._MAX_NUM = 4;\n\nFighterOptionManager.prototype._PARAMS = [];\nFighterOptionManager.prototype._PARAMS[0] = {\n  'r':  32,\n  'angle': 180,\n  'theta': 180,\n  'd':  1,\n  'trange': {'min': 180, 'max': 250}\n};\nFighterOptionManager.prototype._PARAMS[1] = {\n  'r':  32,\n  'angle':   0,\n  'theta': 360,\n  'd': -1,\n  'trange': {'min': 290, 'max': 360}\n};\n\n\nFighterOptionManager.prototype._initMaxNum = function() {\n  return this._MAX_NUM;\n};\n\n\nFighterOptionManager.prototype._init = function() {\n  // TODO: move these parameters to outside.\n  for(var i = 0; i < this.fighters.length; i++) {\n    var fighter = this.fighters[i];\n    this.create(fighter, this._PARAMS[0]);\n    this.create(fighter, this._PARAMS[1]);\n  }\n};\n\n\n/**\n * keeps the elements even it resets.\n * TODO: unstraightforward.\n */\nFighterOptionManager.prototype.reset = function() {\n  for(var i = 0; i < this.elements.length; i++) {\n    this.elements[i].reset(this._PARAMS[i%2]);\n  }\n  this.count = 0 ;\n};\n\n\nFighterOptionManager.prototype._initFactory = function( ) {\n  this.factory = new FighterOptionFactory( this.gameState,\n                                           this.gameState.getWidth( ),\n                                           this.gameState.getHeight( ) ) ;\n} ;\n\n\nFighterOptionManager.prototype.initDrawer = function(layer, image) {\n  this.drawer = new FighterOptionDrawer(this, layer, this._getImage());\n};\n\n\n/**\n * TODO: consider who should manage image.\n */\nFighterOptionManager.prototype._getImage = function() {\n  return this.gameState.getImage(Game._IMG_FIGHTER_OPTION);\n};\n\n\nFighterOptionManager.prototype.create = function(fighter, params) {\n  var o = this.factory.create(fighter, params, this._getImage());\n  fighter.addOption(o);\n  this.addElement(o);\n};\n\n\n\nfunction FighterOptionFactory( gameState, maxX, maxY ) {\n  this.parent = ElementFactory ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n} ;\n__inherit( FighterOptionFactory, ElementFactory ) ;\n\nFighterOptionFactory.prototype._NUM = 10 ;\n\n\nFighterOptionFactory.prototype._initFreelist = function( ) {\n  this.freelist = new FighterOptionFreeList( this._NUM,\n                                             this.gameState ) ;\n} ;\n\n\n/**\n *\n */\nFighterOptionFactory.prototype.create = function(fighter, params, image) {\n  var option = this.freelist.get();\n  option.init(params, image, fighter);\n  return option;\n};\n\n\n\nfunction FighterOptionFreeList( num, gameState ) {\n  this.parent = ElementFreeList ;\n  this.parent.call( this, num, gameState ) ;\n} ;\n__inherit( FighterOptionFreeList, ElementFreeList ) ;\n\n\nFighterOptionFreeList.prototype._generateElement = function( ) {\n  return new FighterOption( this.gameState,\n                            this.gameState.getWidth( ),\n                            this.gameState.getHeight( ) ) ;\n} ;\n\n\nfunction FighterOptionDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(FighterOptionDrawer, ElementDrawer);\n\n\n\nfunction FighterOptionView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(FighterOptionView, ElementView);\n\n\n\n/**\n * if fighter doesn't have option, return 0 not to draw.\n * TODO: not straight forward design.\n */\nFighterOptionView.prototype.getNum = function() {\n  return (this.element.fighter.hasOption()) ? 1 : 0;\n};\n\n\n__copyParentMethod(FighterOptionView, ElementView, '_getElementX');\nFighterOptionView.prototype._getElementX = function() {\n  return this.ElementView_getElementX() + this.element.fighter.getX();\n};\n\n\n__copyParentMethod(FighterOptionView, ElementView, '_getElementY');\nFighterOptionView.prototype._getElementY = function() {\n  return this.ElementView_getElementY() + this.element.fighter.getY();\n};\n\n\n__copyParentMethod(FighterOptionView, ElementView, '_getElementZ');\nFighterOptionView.prototype._getElementZ = function() {\n  return this.ElementView_getElementZ() + this.element.fighter.getZ();\n};\n\n\n/**\n * for character change.\n * TODO: bad design.\n */\nFighterOptionView.prototype.animate = function() {\n  this._initCoordinates();\n  this.a = this.element.fighter.isFlagSet(this.element._FLAG_UNHITTABLE) ? 0.7 : 1.0;\n};\n\n\n\nfunction FighterOption(gameState, maxX, maxY) {\n  this.parent = Element;\n  this.parent.call(this, gameState, maxX, maxY);\n  this.fighter = null;\n  this.angle   = null;\n  this.theta   = null;\n  this.d       = null;\n  this.trange  = null;\n}\n__inherit(FighterOption, Element);\n\n// only for reference\nFighterOption.prototype.Math = Math;\n\nFighterOption.prototype._WIDTH = 16 ;\nFighterOption.prototype._HEIGHT = 16 ;\n\nFighterOption.prototype._MOVE_SPEED = 8 ;\nFighterOption.prototype._ROTATE_SPEED = 4 ;\n\n\n__copyParentMethod(FighterOption, Element, 'init');\nFighterOption.prototype._init = function(params, image) {\n  this.Element_init(params, image);\n\n  this.width  = this._WIDTH;\n  this.height = this._HEIGHT;\n  this.collisionWidth  = this.width;\n  this.collisionHeight = this.height;\n\n  this.angle  = this._getValueOrDefaultValue(params.angle, 0);\n  this.theta  = this._getValueOrDefaultValue(params.theta, 0);\n  this.d      = this._getValueOrDefaultValue(params.d, 0);\n  this.trange = this._getValueOrDefaultValue(params.trange, null);\n};\n\n\nFighterOption.prototype.init = function(params, image, fighter) {\n  this.fighter = fighter;\n  this._init(params, image);\n  this._initView();\n};\n\n\nFighterOption.prototype.reset = function(params) {\n  this._init(params, this.image);\n};\n\n\nFighterOption.prototype._generateView = function() {\n  return new FighterOptionView(this);\n};\n\n\n/**\n * TODO: temporal. Should I use MoveVector?\n */\n__copyParentMethod(FighterOption, Element, 'runStep');\nFighterOption.prototype.runStep = function() {\n  if(this.fighter.hasOption()) {\n    this.theta += (this.fighter.isFlagSet(this.fighter._FLAG_SLOW) ? 1 : -1)\n                    * this.d * this._MOVE_SPEED;\n    if(this.theta > this.trange.max)\n      this.theta = this.trange.max;\n    if(this.theta < this.trange.min)\n      this.theta = this.trange.min;\n    this.setX(this.r * this.Math.cos(this._calculateRadian(this.theta)));\n    this.setY(this.r * this.Math.sin(this._calculateRadian(this.theta)));\n  }\n  this.Element_runStep();\n};\n\n\n/**\n * TODO: temporal\n */\nFighterOption.prototype.display = function( surface ) {\n  if( ! this.fighter.hasOption( ) )\n    return ;\n\n  this.image = this.fighter.characterIndex == 0\n                 ? this.gameState.getImage( Game._IMG_REIMU_OPTION )\n                 : this.gameState.getImage( Game._IMG_MARISA_OPTION ) ;\n\n  this.parent.prototype.display.call( this, surface, true, angle ) ;\n} ;\n\n\nFighterOption.prototype.getDirectionTheta = function() {\n  return (this.angle + this.count * this._ROTATE_SPEED + 90) % 360;\n};\n\n\nFighterOption.prototype.checkLoss = function( ) {\n  return false ;\n} ;\n\n\nFighterOption.prototype.getCenterX = function( ) {\n  return this.getX( ) + this.fighter.getX( ) ;\n} ;\n\n\nFighterOption.prototype.getCenterY = function( ) {\n  return this.getY( ) + this.fighter.getY( ) ;\n} ;\n\n\n/**\n * TODO: temporal. bad design.\n */\nFighterOption.prototype.getImageIndexY = function() {\n  return this.fighter.characterIndex;\n};\n\n"
  },
  {
    "path": "source/Game.js",
    "content": "function Game(mainCanvas, bgCanvas) {\n  this.gs = new GameSocket(this);\n  this.gs.connect();\n\n  this.surface = mainCanvas.getContext('2d');\n  this.surface.fillStyle = 'white';\n\n  this.bgLayer = new Layer(bgCanvas);\n\n//  this.width = Number(mainCanvas.getAttribute('width')) - Game._SIDE_WIDTH;\n  this.width = Number(mainCanvas.getAttribute('width'));\n  this.height = Number(mainCanvas.getAttribute('height'));\n  this.sounds = [ ] ;\n  this.bgms = [ ] ;\n  this.images = [ ] ;\n\n  this.interval = null ;\n  this.oldTIme = null ;\n  this.fps = null ;\n  this.count = 0 ;\n\n  this.someoneState = -1;\n  this.onlineActiveNum = 0;\n  this.messegeReceiveCount = 0;\n\n  this.state = 0 ;\n  this.flags = 0 ;\n\n  this.states = [ ] ; // TODO: temporal\n  this.states[ Game._STATE_LOAD ]        = new LoadingState( this ) ;\n  this.states[ Game._STATE_OPENING ]     = new OpeningState( this ) ;\n  this.states[ Game._STATE_CHARA_SEL ]   = new CharacterSelectState( this ) ;\n  this.states[ Game._STATE_REPLAY_SEL ]  = new ReplaySelectState( this ) ;\n  this.states[ Game._STATE_IN_STAGE ]    = new StageState( this ) ;\n  this.states[ Game._STATE_ENDING ]      = new EndingState( this ) ;\n  this.states[ Game._STATE_STAFF_ROLL ]  = new StaffRollState( this ) ;\n  this.states[ Game._STATE_POST_REPLAY ] = new PostReplayState( this ) ;\n\n  this._changeState( Game._STATE_LOAD, { } ) ;\n\n  var self = this;\n  this.runFunc = function() { self._runStep(); };\n\n  this.lag = null;\n  this.room = null;\n  this.peer = null;\n  this.master = false;\n  this.multiPlay = false;\n  this.connected = false;\n  this.waitingOther = false;\n  this.receivedOther = false;\n  this.otherParams = null;\n  this.meParams = null;\n\n  this.onWsReady = null;\n  this.onConnected = null;\n  this.onSentParams = null;\n  this.onRan = null;\n  this.onRoomUpdate = null;\n}\n\nGame.prototype.Randomizer = __randomizer;\n\n//Game.prototype._WS_URL = 'ws://localhost:5000';\nGame.prototype._WS_URL = 'wss://boiling-anchorage-5279.herokuapp.com/';\n\nGame.prototype._PEER_ID_START = 0;\nGame.prototype._PEER_ID_SYNC = 1;\n\nGame._SIDE_WIDTH = 160 ;\nGame._FPS = 60 ;\nGame._FPS_SPAN = 60 ;\n\nGame._SOMEONE_STATE_DISPLAY_COUNT = 60*5;\n\nGame._STATE_LOAD        = 0x0 ;\nGame._STATE_OPENING     = 0x1 ;\nGame._STATE_CHARA_SEL   = 0x2 ;\nGame._STATE_REPLAY_SEL  = 0x3 ;\nGame._STATE_IN_STAGE    = 0x4 ;\nGame._STATE_STAGE_CLEAR = 0x5 ;\nGame._STATE_ENDING      = 0x6 ;\nGame._STATE_STAFF_ROLL  = 0x7 ;\nGame._STATE_POST_REPLAY = 0x8 ;\n\nGame._SE_SELECT       = 0 ;\nGame._SE_DEAD         = 1 ;\nGame._SE_SHOT         = 2 ;\nGame._SE_ENEMY_SHOT   = 3 ;\nGame._SE_ENEMY_VANISH = 4 ;\nGame._SE_ENEMY_DAMAGE = 5 ;\nGame._SE_GRAZE        = 6 ;\nGame._SE_POWERUP      = 7 ;\nGame._SE_POWER_EFFECT = 8 ;\n\nGame._IMG_FIGHTER         =  0;\nGame._IMG_REIMU_SHIP      =  1;\nGame._IMG_MARISA_SHIP     =  2;\nGame._IMG_FIGHTER_OPTION  =  3;\nGame._IMG_REIMU_OPTION    =  4;\nGame._IMG_MARISA_OPTION   =  5;\nGame._IMG_SHOT            =  6;\nGame._IMG_BOMB            =  7;\nGame._IMG_ENEMY_SHOT      =  8;\nGame._IMG_LASER           =  9;\nGame._IMG_BEAM            = 10;\nGame._IMG_ENEMY           = 11;\nGame._IMG_DAMAGE          = 12;\nGame._IMG_VANISHED        = 13;\nGame._IMG_SHOCK_WAVE      = 14;\nGame._IMG_REIMU_FACE_1    = 15;\nGame._IMG_REIMU_FACE_2    = 16;\nGame._IMG_REIMU_FACE_3    = 17;\nGame._IMG_REIMU_FACE_4    = 18;\nGame._IMG_MARISA_FACE_1   = 19;\nGame._IMG_MARISA_FACE_2   = 20;\nGame._IMG_MARISA_FACE_3   = 21;\nGame._IMG_MARISA_FACE_4   = 22;\nGame._IMG_ENEMY_MOKOU     = 23;\nGame._IMG_ENEMY_RUMIA     = 24;\nGame._IMG_ENEMY_DAIYOUSEI = 25;\nGame._IMG_ENEMY_CHILNO    = 26;\nGame._IMG_ITEM            = 27;\nGame._IMG_POWER_ITEM      = 28;\nGame._IMG_SCORE_ITEM      = 29;\nGame._IMG_BG1             = 30;\nGame._IMG_BG2             = 31;\nGame._IMG_SCORE_BACK      = 32;\nGame._IMG_STAND_REIMU     = 33;\nGame._IMG_STAND_MARISA    = 34;\nGame._IMG_STAND_MOKOU     = 35;\nGame._IMG_STAND_RUMIA     = 36;\nGame._IMG_STAND_CHILNO    = 37;\nGame._IMG_TITLE_BG        = 38;\n\nGame._IMGS = { } ;\nGame._IMGS[Game._IMG_FIGHTER]            = 'image/fighter.png';\nGame._IMGS[ Game._IMG_REIMU_SHIP ]       = 'image/reimu.png' ;\nGame._IMGS[ Game._IMG_MARISA_SHIP ]      = 'image/marisa.png' ;\nGame._IMGS[ Game._IMG_REIMU_OPTION ]     = 'image/reimu_option.png' ;\nGame._IMGS[ Game._IMG_MARISA_OPTION ]    = 'image/marisa_option.png' ;\nGame._IMGS[Game._IMG_FIGHTER_OPTION]     = 'image/fighter_option.png';\nGame._IMGS[ Game._IMG_SHOT ]             = 'image/pl_shot.png' ;\nGame._IMGS[ Game._IMG_BOMB ]             = 'image/th128_Bullet2HD.png' ;\nGame._IMGS[ Game._IMG_ENEMY_SHOT ]       = 'image/bullet.png' ;\nGame._IMGS[ Game._IMG_LASER ]            = 'image/pl_shot.png' ;\nGame._IMGS[ Game._IMG_BEAM ]             = 'image/beam.png' ;\nGame._IMGS[ Game._IMG_ENEMY ]            = 'image/enemy.png' ;\nGame._IMGS[ Game._IMG_ENEMY_MOKOU ]      = 'image/mokou.png' ;\nGame._IMGS[ Game._IMG_ENEMY_RUMIA ]      = 'image/rumia.png' ;\nGame._IMGS[ Game._IMG_ENEMY_DAIYOUSEI ]  = 'image/daiyousei.png' ;\nGame._IMGS[ Game._IMG_ENEMY_CHILNO ]     = 'image/chilno.png' ;\nGame._IMGS[ Game._IMG_DAMAGE ]           = 'image/th128_BulletHD.png' ;\nGame._IMGS[ Game._IMG_VANISHED ]         = 'image/th128_Bullet2.png' ;\nGame._IMGS[ Game._IMG_SHOCK_WAVE ]       = 'image/shockwave.png' ;\nGame._IMGS[ Game._IMG_REIMU_FACE_1 ]     = 'image/reimu_1.png' ;\nGame._IMGS[ Game._IMG_REIMU_FACE_2 ]     = 'image/reimu_2.png' ;\nGame._IMGS[ Game._IMG_REIMU_FACE_3 ]     = 'image/reimu_3.png' ;\nGame._IMGS[ Game._IMG_REIMU_FACE_4 ]     = 'image/reimu_4.png' ;\nGame._IMGS[ Game._IMG_MARISA_FACE_1 ]    = 'image/marisa_1.png' ;\nGame._IMGS[ Game._IMG_MARISA_FACE_2 ]    = 'image/marisa_2.png' ;\nGame._IMGS[ Game._IMG_MARISA_FACE_3 ]    = 'image/marisa_3.png' ;\nGame._IMGS[ Game._IMG_MARISA_FACE_4 ]    = 'image/marisa_4.png' ;\nGame._IMGS[ Game._IMG_ITEM ]             = 'image/item.png' ;\nGame._IMGS[ Game._IMG_POWER_ITEM ]       = 'image/power_item.png' ;\nGame._IMGS[ Game._IMG_SCORE_ITEM ]       = 'image/score_item.png' ;\nGame._IMGS[ Game._IMG_BG1 ]              = 'image/bg1.png' ;\nGame._IMGS[ Game._IMG_BG2 ]              = 'image/bg2.png' ;\nGame._IMGS[ Game._IMG_SCORE_BACK ]       = 'image/scoreback.png' ;\nGame._IMGS[ Game._IMG_STAND_REIMU ]      = 'image/reimu_stand.png' ;\nGame._IMGS[ Game._IMG_STAND_MARISA ]     = 'image/marisa_stand.png' ;\nGame._IMGS[ Game._IMG_STAND_MOKOU ]      = 'image/mokou_stand.png' ;\nGame._IMGS[ Game._IMG_STAND_RUMIA ]      = 'image/rumia_stand.png' ;\nGame._IMGS[ Game._IMG_STAND_CHILNO ]     = 'image/chilno_stand.png' ;\nGame._IMGS[ Game._IMG_TITLE_BG ]         = 'image/title_bg.png' ;\n\nGame._BGM_TITLE  = 0 ;\nGame._BGM_1      = 1 ;\nGame._BGM_ENDING = 2 ;\n\nGame._BGMS = { } ;\nGame._BGMS[ Game._BGM_TITLE ]  = 'BGM/title.mp3' ;\nGame._BGMS[ Game._BGM_1 ]      = 'BGM/bgm.mp3' ;\nGame._BGMS[ Game._BGM_ENDING ] = 'BGM/ending.mp3' ;\n\nGame._SES = { } ;\nGame._SES[ Game._SE_SELECT ]       = 'SE/select.wav' ;\nGame._SES[ Game._SE_DEAD ]         = 'SE/dead.wav' ;\nGame._SES[ Game._SE_SHOT ]         = 'SE/shot.wav' ;\nGame._SES[ Game._SE_ENEMY_SHOT ]   = 'SE/shot.wav' ;\nGame._SES[ Game._SE_ENEMY_VANISH ] = 'SE/enemy_vanish.wav' ;\nGame._SES[ Game._SE_ENEMY_DAMAGE ] = 'SE/enemy_damage.wav' ;\nGame._SES[ Game._SE_GRAZE ]        = 'SE/graze.wav' ;\nGame._SES[ Game._SE_POWERUP ]      = 'SE/powerup.wav' ;\nGame._SES[ Game._SE_POWER_EFFECT ] = 'SE/enemy_powereffect.wav' ;\n\n\nGame._SOMEONE_MESSAGES = [];\nGame._SOMEONE_MESSAGES[GameSocket._STATE_OPEN]\n  = 'opened';\nGame._SOMEONE_MESSAGES[GameSocket._STATE_CLOSE]\n  = 'closed';\nGame._SOMEONE_MESSAGES[GameSocket._STATE_BEGIN_GAME]\n  = 'began the game';\nGame._SOMEONE_MESSAGES[GameSocket._STATE_DEAD]\n  = 'dead';\nGame._SOMEONE_MESSAGES[GameSocket._STATE_DESTROY_STAGE1_MID_BOSS]\n  = 'destroyed Rumia';\nGame._SOMEONE_MESSAGES[GameSocket._STATE_DESTROY_STAGE1_BIG_BOSS]\n  = 'destroyed Rumia';\nGame._SOMEONE_MESSAGES[GameSocket._STATE_DESTROY_STAGE2_MID_BOSS]\n  = 'destroyed Dai Yousei';\nGame._SOMEONE_MESSAGES[GameSocket._STATE_DESTROY_STAGE2_BIG_BOSS]\n  = 'destroyed Chirno';\nGame._SOMEONE_MESSAGES[GameSocket._STATE_GAME_CLEAR]\n  = 'completed the game';\nGame._SOMEONE_MESSAGES[GameSocket._STATE_GAME_OVER]\n  = 'game over';\n\n\nGame.prototype.getImage = function( key ) {\n  return this.images[ key ] ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nGame.prototype.soundEffect = function(key) {\n  var game = Game;\n  switch(key) {\n    case game._SE_SHOT:\n      this.sounds[key].volume = 0.012;\n      break;\n    case game._SE_SELECT:\n      this.sounds[key].volume = 0.04;\n      break;\n    case game._SE_POWER_EFFECT:\n      this.sounds[key].volume = 0.14;\n      break;\n    case game._SE_ENEMY_SHOT:\n      this.sounds[key].volume = 0.02;\n      break;\n    case game._SE_ENEMY_DAMAGE:\n      this.sounds[key].volume = 0.014;\n      break;\n    case game._SE_ENEMY_VANISH:\n      this.sounds[key].volume = 0.03;\n      break;\n    case game._SE_DEAD:\n      this.sounds[key].volume = 0.05;\n      break;\n    case game._SE_POWERUP:\n      this.sounds[key].volume = 0.04;\n      break;\n    case game._SE_GRAZE:\n      this.sounds[key].volume = 0.05;\n      break;\n    default:\n      this.sounds[key].volume = 0.1;\n      break;\n  }\n\n  this.sounds[ key ].pause();\n  this.sounds[ key ].currentTime = 0;\n  this.sounds[ key ].play();\n//  this.sounds[ key ] = new Audio( this.sounds[ key ].src ) ;\n} ;\n\n\nGame.prototype.soundBGM = function( key ) {\n\n  for( var i = 0; i < this.bgms.length; i++ ) {\n    this.bgms[ i ].pause( ) ;\n    this.bgms[ i ].currentTime = 0 ;\n  }\n\n  this.bgms[ key ].loop = true ;\n  // TODO: temporal\n  if( key == Game._BGM_TITLE )\n    this.bgms[ key ].volume = 0.08 ;\n  else\n    this.bgms[ key ].volume = 0.2 ;\n  this.bgms[ key ].play( ) ;\n} ;\n\n\nGame.prototype.run = function( ) {\n//  this.states[ this.state ].init( ) ;\n//  this.interval = setInterval( this._runStep.bind( this ), 1000 / Game._FPS ) ;\n  this._runStep( ) ;\n} ;\n\n\nGame.prototype.clear = function( surface ) {\n  surface.clearRect( 0, 0, this.width, this.height ) ;\n} ;\n\n\nGame.prototype.handleKeyDown = function( e ) {\n  // TODO: temporal\n  if(this.isMultiPlay() && this.waitingOther && ! this.receivedOther)\n    return;\n\n  this.states[ this.state ].handleKeyDown( e ) ;\n  e.preventDefault( ) ;\n} ;\n\n\nGame.prototype.handleKeyUp = function( e ) {\n  // TODO: temporal\n  if(this.isMultiPlay() && this.waitingOther && ! this.receivedOther)\n    return;\n\n  this.states[ this.state ].handleKeyUp( e ) ;\n  e.preventDefault( ) ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nGame.prototype._runStep = function( ) {\n  this.states[ this.state ].runStep( ) ;\n  this.states[ this.state ].updateDisplay( this.surface ) ;\n  this._displayFps( this.surface ) ;\n  this._displayOnlineState(this.surface);\n\n  if(this.someoneState >= 0 &&\n     this.count > this.messageReceiveCount +\n                  Game._SOMEONE_STATE_DISPLAY_COUNT)\n    this.someoneState = -1;\n\n  this.count++ ;\n  if(this.states[this.state].doRunNextStep())\n    this.runNextStep();\n} ;\n\n\nGame.prototype.runNextStep = function() {\n  requestAnimationFrame(this.runFunc);\n};\n\n\nGame.prototype._calculateFps = function( ) {\n  if( ( this.count % Game._FPS_SPAN ) != 0 )\n    return ;\n  var newTime = Date.now( ) ;\n  if( this.oldTime ) {\n    this.fps = parseInt( 1000 * Game._FPS_SPAN / ( newTime - this.oldTime ) ) ;\n  }\n  this.oldTime = newTime ;\n} ;\n\n\nGame.prototype._displayFps = function( surface ) {\n  this._calculateFps( ) ;\n  if( ! this.fps )\n    return ;\n\n  surface.save( ) ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.font = '16px Arial' ;\n  surface.fillText( this.fps + 'fps', this.getWidth( ) - 50, this.getHeight( ) - 15 ) ;\n  surface.restore( ) ;\n} ;\n\n\n/**\n * TODO: temporal.\n */\nGame.prototype._displayOnlineState = function(surface) {\n  if(! this.gs.connected())\n    return;\n\n  surface.save();\n  surface.textAlign = 'right';\n  surface.fillStyle = 'rgb(255, 255, 255)';\n  surface.font = '12px Arial';\n  surface.fillText(this.onlineActiveNum + ' playing now',\n                   this.getWidth() - 5,\n                   15);\n  if(this.someoneState >= 0) {\n    var x = (this.count - this.messageReceiveCount)*4 - 100;\n    if(x > 5)\n      x = 5;\n    surface.fillText('someone', this.getWidth() - x - 30, 30);\n    surface.fillText(Game._SOMEONE_MESSAGES[this.someoneState],\n                     this.getWidth() - x,\n                     45);\n  }\n  surface.restore();\n};\n\n\n/**\n * TODO: temporal.\n */\nGame.prototype.sendMessageToServer = function(key) {\n  this.gs.send(key);\n};\n\n\n/**\n * TODO: temporal.\n */\nGame.prototype.notifyMessageReceive = function(activeNum, key) {\n  this.onlineActiveNum = activeNum;\n  this.someoneState = key;\n  this.messageReceiveCount = this.count;\n};\n\n\nGame.prototype.notifyLoadingConclusion = function( ) {\n  this._changeState( Game._STATE_OPENING, { } ) ;\n//  this._changeState( Game._STATE_STAFF_ROLL, { } ) ;\n} ;\n\n\nGame.prototype.notifyOpeningConclusion = function( ) {\n  this._changeState( Game._STATE_CHARA_SEL, { } ) ;\n} ;\n\n\nGame.prototype.notifyCharacterSelectConclusion = function(index) {\n  var seed = (new Date()).getTime() & 0xffff;\n\n  if(this.isMultiPlay()) {\n    var p = {};\n    p.i = index;\n    p.s = seed;\n    if(this.lag)\n      p.l = this.lag;\n    this.meParams = p;\n    this.waitingOther = true;\n    this._startSync(p);\n    if(this.receivedOther) {\n      this._changeState(Game._STATE_IN_STAGE,\n                        this._makeStageStateParameterForMultiPlay());\n      if(this.onRan !== null)\n        this.onRan();\n    }\n  } else {\n    var params = {};\n    params.characterIndex = index; // me\n    params.seed = seed;\n    this._changeState(Game._STATE_IN_STAGE, params);\n  }\n};\n\n\nGame.prototype.notifyReplaySelectBegin = function( index ) {\n  this._changeState( Game._STATE_REPLAY_SEL, { } ) ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nGame.prototype.notifyReplaySelectConclusion = function( params ) {\n  // currently, only Reimu.\n  this._changeState( Game._STATE_IN_STAGE,\n                     { 'autoplayParams': params, 'autoplay': true } ) ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nGame.prototype.notifyQuitStage = function( flag ) {\n  if(flag && ! this.isMultiPlay())\n    this._changeState( Game._STATE_POST_REPLAY, { } ) ;\n  else\n    this._changeState( Game._STATE_OPENING, { } ) ;\n\n  // TODO: temporal\n  if(this.isMultiPlay())\n    this.resetSyncParams();\n} ;\n\n\nGame.prototype.notifyGameClear = function( ) {\n//  this._changeState( Game._STATE_ENDING, { } ) ;\n  this._changeState( Game._STATE_STAFF_ROLL, { } ) ;\n\n  // TODO: temporal\n  if(this.isMultiPlay())\n    this.resetSyncParams();\n} ;\n\n\nGame.prototype._changeState = function( state, params ) {\n  this.state = state ;\n  this.states[ this.state ].init( params ) ;\n} ;\n\n\nGame.prototype.getWidth = function( ) {\n  return this.width ;\n} ;\n\n\nGame.prototype.getHeight = function( ) {\n  return this.height ;\n} ;\n\n\nGame.prototype.isFlagSet = function( type ) {\n  return ( this.flags & type ) ? true : false ;\n} ;\n\n\nGame.prototype.setFlag = function( type ) {\n  this.flags |= type ;\n} ;\n\n\nGame.prototype.clearFlag = function( type ) {\n  this.flags &= ~type ;\n} ;\n\n\nGame.prototype.setLag = function(lag) {\n  this.lag = lag;\n};\n\n\nGame.prototype.setRoom = function(room) {\n  this.room = room;\n  this.peer = new Peer(this.room, this._WS_URL, this);\n  this.peer.createPeerConnection();\n  this.multiPlay = true;\n};\n\n\nGame.prototype.notifyWsReady = function(e) {\n  if(this.onWsReady !== null)\n    this.onWsReady(e);\n};\n\n\nGame.prototype.notifyRoomUpdate = function(num) {\n  if(this.onRoomUpdate !== null)\n    this.onRoomUpdate(num);\n};\n\n\nGame.prototype.connect = function() {\n  this.peer.offer();\n  this.master = true;\n};\n\n\nGame.prototype.notifyOpenPeer = function(e) {\n  this.connected = true;\n  if(this.onConnected !== null)\n    this.onConnected(e);\n};\n\n\nGame.prototype._startSync = function(params) {\n  this.peer.send({id: this._PEER_ID_START, p: params});\n  if(this.onSentParams !== null)\n    this.onSentParams();\n};\n\n\nGame.prototype.sync = function(params) {\n  // TODO: temporal impl to reduce the amount data transferred.\n//  this.peer.send({id: this._PEER_ID_SYNC, p: params});\n  this.peer.send(params);\n};\n\n\nGame.prototype.receiveFromPeer = function(data) {\n  // TODO: temporal impl to reduce the amount data transferred.\n/*\n  switch(data.id) {\n    case this._PEER_ID_START:\n      this.receivedOther = true;\n      this.otherParams = data.p;\n      if(this.waitingOther) {\n        this._changeState(Game._STATE_IN_STAGE,\n                          this._makeStageStateParameterForMultiPlay());\n        if(this.onRan !== null)\n          this.onRan();\n      }\n      break;\n    case this._PEER_ID_SYNC:\n      this.states[this.state].receiveFromPeer(data.p);\n      break;\n  }\n*/\n  if(data.id !== void 0) {\n    switch(data.id) {\n      case this._PEER_ID_START:\n        this.receivedOther = true;\n        this.otherParams = data.p;\n        if(this.waitingOther) {\n          this._changeState(Game._STATE_IN_STAGE,\n                            this._makeStageStateParameterForMultiPlay());\n          if(this.onRan !== null)\n            this.onRan();\n        }\n        break;\n      case this._PEER_ID_SYNC:\n        this.states[this.state].receiveFromPeer(data.p);\n        break;\n    }\n  } else {\n    this.states[this.state].receiveFromPeer(data);\n  }\n\n\n};\n\n\nGame.prototype._makeStageStateParameterForMultiPlay = function() {\n  var p = {};\n  p.characterIndex = this.meParams.i;\n  p.characterIndex2 = this.otherParams.i;\n  // use greater one.\n  p.seed = this.meParams.s > this.otherParams.s\n             ? this.meParams.s : this.otherParams.s;\n\n  if(this.meParams.l !== void 0 && this.otherParams.l === void 0) {\n    p.lag = this.meParams.l;\n  } else if(this.meParams.l === void 0 && this.otherParams.l !== void 0) {\n    p.lag = this.otherParams.l;\n  } else if(this.meParams.l !== void 0 && this.otherParams.l !== void 0) {\n    p.lag = this.meParams.l > this.otherParams.l\n              ? this.meParams.l : this.otherParams.l;\n  }\n\n  return p;\n};\n\n\nGame.prototype.isMultiPlay = function() {\n  return this.multiPlay;\n};\n\n\nGame.prototype.isMaster = function() {\n  return this.master;\n};\n\n\nGame.prototype.isConnected = function() {\n  return this.connected;\n};\n\n\nGame.prototype.resetSyncParams = function() {\n  this.waitingOther = false;\n  this.receivedOther = false;\n  this.otherParams = null;\n  this.meParams = null;\n\n  // TODO: temporal\n  if(this.onConnected !== null)\n    this.onConnected();\n};\n"
  },
  {
    "path": "source/GameSocket.js",
    "content": "/**\n *  transferred data: state and activeNum.\n */\nfunction GameSocket(game) {\n  this.game = game;\n  this.ws = null;\n  this.params = {}; // for sent data.\n  this.interval = null;\n\n  var self = this;\n  this.onMessageFunc = function(event) { self._messageCallback(event); };\n  this.dummySendFunc = function() { self._keepSendDummy(); };\n};\n\nGameSocket._URL = 'wss://safe-retreat-9152.herokuapp.com/';\n//GameSocket._URL = 'ws://localhost:5000';\n\nGameSocket._DUMMY_SPAN = 1000 * 20;\n\n// Share these parameters with Server.\nGameSocket._STATE_OPEN                    = 0;\nGameSocket._STATE_CLOSE                   = 1;\n\nGameSocket._STATE_BEGIN_GAME              = 2;\nGameSocket._STATE_DEAD                    = 3;\nGameSocket._STATE_DESTROY_STAGE1_MID_BOSS = 4;\nGameSocket._STATE_DESTROY_STAGE1_BIG_BOSS = 5;\nGameSocket._STATE_DESTROY_STAGE2_MID_BOSS = 6;\nGameSocket._STATE_DESTROY_STAGE2_BIG_BOSS = 7;\nGameSocket._STATE_GAME_CLEAR              = 8;\nGameSocket._STATE_GAME_OVER               = 9;\n\nGameSocket._CONNECTION_STATUS_MAX_NUM = 1;\nGameSocket._SHOOTING_STATE_MAX_NUM    = 9;\n\n\nGameSocket.prototype.connected = function() {\n  return this.ws ? true : false;\n};\n\n\nGameSocket.prototype.connect = function() {\n  try {\n    this.ws = new WebSocket(GameSocket._URL);\n    this.ws.onmessage = this.onMessageFunc;\n  } catch(e) {\n    this.ws = null;\n    console.log(e);\n  }\n  this._setIntervalForDummy();\n};\n\n\nGameSocket.prototype._messageCallback = function(event) {\n  try {\n    var message = JSON.parse(event.data);\n  } catch(e) {\n    return;\n  }\n\n  var activeNum = this.convertToValidActiveNum(message.activeNum);\n  var key = this.convertToValidState(message.state);\n  if(this.isValidState(key) && this.isValidActiveNum(activeNum))\n    this.game.notifyMessageReceive(activeNum, key);\n};\n\n\n/**\n * Prolly JSON.stringify allocates new memory in it and\n * this could lead GC.\n */\nGameSocket.prototype.send = function(key) {\n  if(! this.ws)\n    return;\n  this.params.state = key;\n  var data = JSON.stringify(this.params);\n  this.ws.send(data);\n};\n\n\nGameSocket.prototype._keepSendDummy = function() {\n  this.send(-1);\n  this._setIntervalForDummy();\n};\n\n\nGameSocket.prototype._setIntervalForDummy = function() {\n  if(! this.ws)\n    return;\n  this.interval = setTimeout(this.dummySendFunc, GameSocket._DUMMY_SPAN);\n};\n\n\nGameSocket.prototype.convertToValidState = function(key) {\n  return parseInt(key);\n};\n\n\nGameSocket.prototype.isValidShootingState = function(key) {\n  if(key >  GameSocket._CONNECTION_STATUS_MAX_NUM &&\n     key <= GameSocket._SHOOTING_STATE_MAX_NUM)\n    return true;\n  return false;\n};\n\n\nGameSocket.prototype.isValidState = function(key) {\n  if(key >= 0 &&\n     key <= GameSocket._SHOOTING_STATE_MAX_NUM)\n    return true;\n  return false;\n};\n\n\nGameSocket.prototype.convertToValidActiveNum = function(num) {\n  return parseInt(num);\n};\n\n\nGameSocket.prototype.isValidActiveNum = function(num) {\n  if(num >= 0)\n    return true;\n  return false;\n};\n"
  },
  {
    "path": "source/GameState.js",
    "content": "function GameState( game ) {\n  this.game = game ;\n  this.flags = 0 ;\n  this.state = 0 ;\n}\n\n\nGameState.prototype.init = function( params ) {\n} ;\n\n\nGameState.prototype.runStep = function( ) {\n} ;\n\n\nGameState.prototype.doRunNextStep = function() {\n  return true;\n};\n\n\nGameState.prototype.updateDisplay = function( surface ) {\n} ;\n\n\nGameState.prototype.handleKeyDown = function( e ) {\n} ;\n\n\nGameState.prototype.handleKeyUp = function( e ) {\n} ;\n\n\nGameState.prototype.getImage = function( key ) {\n  return this.game.getImage( key ) ;\n} ;\n\n\nGameState.prototype.getWidth = function( ) {\n  return this.game.width ;\n} ;\n\n\nGameState.prototype.getHeight = function( ) {\n  return this.game.height ;\n} ;\n\n\nGameState.prototype._soundBGM = function( key ) {\n  this.game.soundBGM( key ) ;\n} ;\n\n\nGameState.prototype._soundEffect = function( key ) {\n  this.game.soundEffect( key ) ;\n} ;\n\n\nGameState.prototype.isFlagSet = function( type ) {\n  return ( this.flags & type ) ? true : false ;\n} ;\n\n\nGameState.prototype.setFlag = function( type ) {\n  this.flags |= type ;\n} ;\n\n\nGameState.prototype.clearFlag = function( type ) {\n  this.flags &= ~type ;\n} ;\n\n\nGameState.prototype.isMultiPlay = function() {\n  return this.game.isMultiPlay();\n};\n\n\nGameState.prototype.isMaster = function() {\n  return this.game.isMaster();\n};\n\n\nGameState.prototype.isConnected = function() {\n  return this.game.isConnected();\n};\n\n\nGameState.prototype.receiveFromPeer = function(data) {\n};\n\n"
  },
  {
    "path": "source/Item.js",
    "content": "function ItemManager( gameState ) {\n  this.parent = ElementManager ;\n  this.parent.call( this, gameState ) ;\n} ;\n__inherit( ItemManager, ElementManager ) ;\n\nItemManager.prototype._MAX_NUM = 1000;\n\n\nItemManager.prototype._initMaxNum = function() {\n  return this._MAX_NUM;\n};\n\n\nItemManager.prototype._initFactory = function( ) {\n  this.factory = new ItemFactory( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\nItemManager.prototype.initDrawer = function(layer, image) {\n  this.drawer = new ItemDrawer(this, layer,\n                               this.gameState.getImage(Game._IMG_ITEM));\n};\n\n\n/**\n * TODO: temporary\n */\nItemManager.prototype.create = function( enemy, type ) {\n  this.addElement( this.factory.create( enemy, type ) ) ;\n} ;\n\n\nItemManager.prototype.createPowerItem = function(enemy) {\n  this.create(enemy, this.Item._TYPE_POWER);\n};\n\n\nItemManager.prototype.createScoreItem = function(enemy) {\n  this.create(enemy, this.Item._TYPE_SCORE);\n};\n\n\n/**\n * TODO: temporary\n */\nItemManager.prototype.createHoming = function(fighter, enemy) {\n  var item = this.factory.create(enemy, this.Item._TYPE_SCORE);\n  item.setTarget(fighter);\n  this.addElement(item);\n};\n\n\n__copyParentMethod(ItemManager, ElementManager, 'checkCollisionWith');\nItemManager.prototype.checkCollisionWith = function( fighter ) {\n  this.ElementManager_checkCollisionWith(null, fighter, this);\n};\n\n\nItemManager.prototype.checkCollisionWithFighters = function(fighters) {\n  for(var i = 0; i < fighters.length; i++) {\n    this.checkCollisionWith(fighters[i]);\n  }\n};\n\nItemManager.prototype.notifyCollision = function(id, fighter, item) {\n  item.die();\n  if(item.isPower())\n    this.gameState.notifyFighterGotPowerItem(fighter, item);\n  else\n    this.gameState.notifyFighterGotScoreItem(fighter, item);\n};\n\n\nItemManager.prototype.beHomingAll = function( fighter ) {\n  for( var i = 0; i < this.elements.length; i++ ) {\n    this.elements[ i ].setTarget( fighter ) ;\n  }\n} ;\n\n\n\nfunction ItemFactory( gameState, maxX, maxY ) {\n  this.parent = ElementFactory ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n  this.image = null; // TODO: temporal\n} ;\n__inherit( ItemFactory, ElementFactory ) ;\n\nItemFactory.prototype._NUM = 1000 ;\nItemFactory.prototype._PARAMS = {\n  'x': 0,\n  'y': 0,\n  'v': { 'r': 4, 'theta': 270, 'w': 0, 'ra':-0.1, 'wa': 0 }\n} ;\n\n\nItemFactory.prototype._initFreelist = function() {\n  this.freelist = new ItemFreeList(this._NUM, this.gameState); \n};\n\n\n/**\n * TODO: temporal\n */\nItemFactory.prototype.create = function(element, type) {\n  var params = this._PARAMS;\n  params.x = element.getX();\n  params.y = element.getY();\n  var item = this.freelist.get();\n  item.init(params, this._getImage(type), type);\n  return item;\n};\n\n\nItemFactory.prototype._getImage = function(type) {\n  if(this.image === null)\n    this.image = this.gameState.getImage(Game._IMG_ITEM);\n  return this.image;\n};\n\n\n\nfunction ItemFreeList( num, gameState ) {\n  this.parent = ElementFreeList ;\n  this.parent.call( this, num, gameState ) ;\n}\n__inherit( ItemFreeList, ElementFreeList ) ;\n\n\nItemFreeList.prototype._generateElement = function( ) {\n  return new Item( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\n\nfunction ItemDrawer(elementManager, layer, image) {\n  this.parent = ElementDrawer;\n  this.parent.call(this, elementManager, layer, image);\n};\n__inherit(ItemDrawer, ElementDrawer);\n\n\n\nfunction ItemView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(ItemView, ElementView);\n\n\n/**\n * no rotate.\n * TODO: no rotate impl should be in parent class?\n */\nItemView.prototype.rotate = function() {\n};\n\n\nItemView.prototype.doRotateForViewpoint = function() {\n  return true;\n};\n\n\nfunction Item( gameState, maxX, maxY ) {\n  this.parent = Element ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n  this.type = null ;\n  this.target = null ;\n}\n__inherit( Item, Element ) ;\n\n// only for reference\nItem.prototype.Math = Math;\n\nItem.prototype._WIDTH = 12 ;\nItem.prototype._HEIGHT = 12 ;\n\nItem.prototype._COLLISION_WIDTH = 50 ;\nItem.prototype._COLLISION_HEIGHT = 50 ;\n\nItem.prototype._HOMING_SPAN = 2 ;\nItem.prototype._HOMING_R = 10 ;\n\nItem.prototype._TYPE_POWER = 0 ;\nItem.prototype._TYPE_SCORE = 1 ;\n\n\n__copyParentMethod(Item, Element, 'init');\nItem.prototype.init = function(params, image, type) {\n  this.Element_init(params, image);\n  this.type = type;\n  this.indexX = this.type; // TODO: temporal.\n  this.width = this._WIDTH;\n  this.height = this._HEIGHT;\n  this.collisionWidth = this._COLLISION_WIDTH;\n  this.collisionHeight = this._COLLISION_HEIGHT;\n  this.target = null;\n  this._initView();\n};\n\n\nItem.prototype._generateView = function() {\n  return new ItemView(this);\n};\n\n\n/**\n * TODO: temporal\n */\n__copyParentMethod(Item, Element, 'runStep');\nItem.prototype.runStep = function() {\n  if(this.target && this.count % this._HOMING_SPAN == 0)\n    this._calculateHomingPoint();\n  this.Element_runStep();\n};\n\n\nItem.prototype.setTarget = function( element ) {\n  this.target = element ;\n} ;\n\n\nItem.prototype.isPower = function() {\n  return this.type == this._TYPE_POWER;\n};\n\n\nItem.prototype.isScore = function() {\n  return this.type == this._TYPE_SCORE;\n};\n\n\n/**\n * TODO: temporal\n */\nItem.prototype.checkLoss = function( ) {\n  if( this.isDead( ) )\n    return true ;\n\n  if( this.x < 0 || this.x >= this.maxX ||\n                    this.y >= this.maxY )\n    return true ;\n  return false ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nItem.prototype._calculateHomingPoint = function( ) {\n  var ax = this.target.getX( ) - this.getX( ) ;\n  var ay = this.target.getY( ) - this.getY( ) ;\n  var t = this._calculateTheta( this.Math.atan2( ay, ax ) ) ;\n  this.vector.theta = t ;\n  this.vector.r = this._HOMING_R ;\n  return ;\n} ;\n\n\n\n// TODO: remove the followings because they complicate the design.\nItemManager.prototype.Item = Item.prototype;\n"
  },
  {
    "path": "source/LoadingState.js",
    "content": "function LoadingState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n  this.loadImageNum = 0 ;\n  this.loadSoundNum = 0 ;\n  this.loadBgmNum = 0 ;\n}\n__inherit( LoadingState, GameState ) ;\n\n\nLoadingState.prototype.init = function( params ) {\n  this._loadImages( ) ;\n  this._loadSEs( ) ;\n  this._loadBGMs( ) ;\n} ;\n\n\nLoadingState.prototype.runStep = function( ) {\n  this._checkLoadCompletion( ) ;\n} ;\n\n\nLoadingState.prototype._checkLoadCompletion = function( ) {\n\n  if( this.loadImageNum < this.game.images.length )\n    return ;\n  if( this.loadSoundNum < this.game.sounds.length )\n    return ;\n  if( this.loadBgmNum < this.game.bgms.length )\n    return ;\n\n  this.game.notifyLoadingConclusion( ) ;\n\n} ;\n\n\nLoadingState.prototype._loadImages = function( ) {\n  var self = this ;\n  for( var key in Game._IMGS ) {\n    this.game.images[ key ] = new Image( ) ;\n    this.game.images[ key ].src = Game._IMGS[ key ] ;\n    this.game.images[ key ].onload = function( ) {\n      self.loadImageNum++ ;\n    } ;\n  }\n} ;\n\n\nLoadingState.prototype._loadSEs = function( ) {\n  var self = this ;\n  for( var key in Game._SES ) {\n    this.game.sounds[ key ] = new Audio( Game._SES[ key ] ) ;\n    this.game.sounds[ key ].addEventListener( 'canplay', function( e ) {\n      self.loadSoundNum++ ;\n    } ) ;\n    this.game.sounds[ key ].load( ) ;\n  }\n} ;\n\n\nLoadingState.prototype._loadBGMs = function( ) {\n  var self = this ;\n  for( var key in Game._BGMS ) {\n    this.game.bgms[ key ] = new Audio( Game._BGMS[ key ] ) ;\n    this.game.bgms[ key ].addEventListener( 'loadstart', function( e ) {\n      self.loadBgmNum++ ;\n    } ) ;\n    this.game.bgms[ key ].load( ) ;\n  }\n} ;\n\n\n\nLoadingState.prototype.updateDisplay = function( surface ) {\n  surface.save( ) ;\n  this.game.clear( surface ) ; // TODO: temporal\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n  surface.textAlign = 'right' ;\n  surface.fillText( 'loading...', 180, 200 ) ;\n  surface.fillText( ( this.loadImageNum  + this.loadSoundNum  + this.loadBgmNum ) + '/' +\n                    ( this.game.images.length + this.game.sounds.length + this.game.bgms.length ), 200, 240 ) ;\n  surface.restore( ) ;\n} ;\n"
  },
  {
    "path": "source/MoveVector.js",
    "content": "function MoveVectorManager( ) {\n  this.elements = [ ] ;\n  this.factory = null ;\n  this._initFactory( ) ;\n}\n\nMoveVectorManager.prototype._NUM = 2000;\n\n\nMoveVectorManager.prototype._initFactory = function() {\n  this.factory = new MoveVectorFactory(this._NUM);\n};\n\n\nMoveVectorManager.prototype.reset = function( ) {\n  for(var i = 0, len = this.elements.length; i < len; i++) {\n    this.factory.free(this.elements[i]);\n  }\n  this.elements.length = 0;\n};\n\n\nMoveVectorManager.prototype.create = function( params ) {\n  return this.factory.create( params ) ;\n} ;\n\n\nMoveVectorManager.prototype.free = function( element ) {\n  this.factory.free( element ) ;\n} ;\n\n\n\nfunction MoveVectorFactory( num ) {\n  this.num = num ;\n  this.freelist = null ;\n  this._initFreelist( ) ;\n}\n\n\nMoveVectorFactory.prototype._initFreelist = function( ) {\n  this.freelist = new MoveVectorFreeList( this.num ) ;\n} ;\n\n\nMoveVectorFactory.prototype.create = function( params ) {\n  var vector = this.freelist.get( ) ;\n  vector.init( params ) ;\n  return vector ;\n} ;\n\n\nMoveVectorFactory.prototype.free = function( vector ) {\n  this.freelist.free( vector ) ;\n} ;\n\n\n/**\n * TODO: list may should be Linked list if num is large.\n */\nfunction MoveVectorFreeList( num ) {\n  FreeList.call( this, num ) ;\n}\n__inherit( MoveVectorFreeList, FreeList ) ;\n\n\n/**\n * Child class must override this method.\n */\nMoveVectorFreeList.prototype._generateElement = function( ) {\n  return new MoveVector( ) ;\n} ;\n\n\n\n/**\n *\n */\nfunction MoveVector( ) {\n  this.r       = 0 ;  // TODO: should be \"v\"elocity?\n  this.theta   = 90 ;\n  this.w       = 0 ;\n  this.ra      = 0 ;\n  this.wa      = 0 ;\n  this.raa     = 0 ;\n  this.waa     = 0 ;\n  this.trange  = null ;\n  this.rrange  = null ;\n  this.wrange  = null ;\n  this.rarange = null ;\n  this.warange = null ;\n  this.element = null ;\n  this.reflectCount = 0 ;\n}\n\n// only for reference\nMoveVector.prototype.Math = Math;\nMoveVector.prototype.Randomizer = __randomizer;\n\n\nMoveVector.prototype.init = function( params ) {\n  this.r       = params.r       !== void 0 ? params.r       : 0 ;\n  this.theta   = params.theta   !== void 0 ? params.theta   : 90 ;\n  this.w       = params.w       !== void 0 ? params.w       : 0 ;\n  this.ra      = params.ra      !== void 0 ? params.ra      : 0 ;\n  this.wa      = params.wa      !== void 0 ? params.wa      : 0 ;\n  this.raa     = params.raa     !== void 0 ? params.raa     : 0 ;\n  this.waa     = params.waa     !== void 0 ? params.waa     : 0 ;\n  this.trange  = params.trange  !== void 0 ? params.trange  : null ;\n  this.rrange  = params.rrange  !== void 0 ? params.rrange  : null ;\n  this.wrange  = params.wrange  !== void 0 ? params.wrange  : null ;\n  this.rarange = params.rarange !== void 0 ? params.rarange : null ;\n  this.warange = params.warange !== void 0 ? params.warange : null ;\n  this.element = null ;\n  this.reflectCount = 0 ;\n\n  if(params.rrandom !== void 0)\n    this.r = this._getRandomValue( params.rrandom ) ;\n  if(params.trandom !== void 0)\n    this.theta = this._getRandomValue( params.trandom ) ;\n  if(params.wrandom !== void 0)\n    this.w = this._getRandomValue( params.wrandom ) ;\n} ;\n\n\n/**\n * TODO: temporal\n * How to handle floating point...?\n */\nMoveVector.prototype._getRandomValue = function( range ) {\n  var differ = range.max - range.min ;\n  return ((this.Randomizer.random() * differ) | 0) + range.min ;\n} ;\n\n\nMoveVector.prototype.setHomingElement = function( e ) {\n  this.element = e ;\n} ;\n\n\nMoveVector.prototype.runStep = function( ) {\n  this.theta += this.w ;\n  this.r     += this.ra ;\n  this.w     += this.wa ;\n  this.ra    += this.raa ;\n  this.wa    += this.waa ;\n  this.theta = this._beInRange( this.theta, this.trange ) ;\n  this.r     = this._beInRange( this.r,     this.rrange ) ;\n  this.w     = this._beInRange( this.w,     this.wrange ) ;\n  this.ra    = this._beInRange( this.ra,    this.rarange ) ;\n  this.wa    = this._beInRange( this.wa,    this.warange ) ;\n} ;\n\n\nMoveVector.prototype._beInRange = function( value, range ) {\n  if(range === null)\n    return value;\n\n  if(range.max !== void 0 && value > range.max)\n    value = range.max ;\n  if(range.min !== void 0 && value < range.min)\n    value = range.min\n  return value;\n};\n\n\nMoveVector.prototype._getRadian = function( ) {\n  return this.theta / 180 * this.Math.PI ;\n} ;\n\n\nMoveVector.prototype.moveX = function( ) {\n  return this.r * this.Math.cos( this._getRadian( ) ) ;\n} ;\n\n\nMoveVector.prototype.moveY = function( ) {\n  return this.r * this.Math.sin( this._getRadian( ) ) ;\n} ;\n\n\nMoveVector.prototype.reflect = function( ) {\n  this.theta += 180 ;\n  this.reflectCount++ ;\n} ;\n\nMoveVector.prototype.reflectX = function( ) {\n  this.theta = 180 - this.theta ;\n  this.reflectCount++ ;\n} ;\n\n\nMoveVector.prototype.reflectY = function( ) {\n  this.theta = 360 - this.theta ;\n  this.reflectCount++ ;\n} ;\n\n\nMoveVector.prototype.getReflectCount = function( ) {\n  return this.reflectCount ;\n} ;\n\n\n"
  },
  {
    "path": "source/OpeningState.js",
    "content": "function OpeningState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n\n  this.initialized = false ;\n\n  this.state = OpeningState._STATE_LOGO ;\n  this.states = [ ] ;\n  this.states[ OpeningState._STATE_LOGO ]  = new LogoState( this ) ;\n  this.states[ OpeningState._STATE_TITLE ] = new TitleState( this ) ;\n}\n__inherit( OpeningState, GameState ) ;\n\nOpeningState._STATE_LOGO  = 0x0 ;\nOpeningState._STATE_TITLE = 0x1 ;\n\n\nOpeningState.prototype.init = function( ) {\n  if( this.initialized )\n    this.notifyLogoConclusion( ) ;\n  this.initialized = true ;\n} ;\n\n\nOpeningState.prototype.runStep = function( ) {\n  this.states[ this.state ].runStep( ) ;\n} ;\n\n\nOpeningState.prototype.updateDisplay = function( surface ) {\n  this.game.clear( surface ) ;\n  this.states[ this.state ].updateDisplay( surface ) ;\n} ;\n\n\nOpeningState.prototype.handleKeyDown = function( e ) {\n  this.states[ this.state ].handleKeyDown( e ) ;\n} ;\n\n\nOpeningState.prototype.handleKeyUp = function( e ) {\n} ;\n\n\nOpeningState.prototype.notifyLogoConclusion = function( ) {\n  this.state = OpeningState._STATE_TITLE ;\n  this.states[ this.state ].init( ) ;\n} ;\n\n\nOpeningState.prototype.notifyTitleConclusion = function() {\n  if(! this.isMultiPlay() || this.isConnected()) {\n    this.game.notifyOpeningConclusion();\n  } else {\n    // TODO: temporal\n    window.alert('connect to begin the game.');\n  }\n};\n\n\nOpeningState.prototype.notifyReplaySelectBegin = function() {\n  if(this.isMultiPlay()) {\n    // TODO: temporal\n    window.alert('cannot choose replay for multi play.');\n  } else {\n    this.game.notifyReplaySelectBegin();\n  }\n};\n\n\nOpeningState.prototype.getImage = function( key ) {\n  return this.game.getImage( key ) ;\n} ;\n\n\nOpeningState.prototype.soundEffect = function( key ) {\n  this.game.soundEffect( key ) ;\n} ;\n\n\nOpeningState.prototype.soundBGM = function( key ) {\n  this.game.soundBGM( key ) ;\n} ;\n\n\n\nOpeningAbstractState = function( opening ) {\n  this.opening = opening ;\n}\n\n\nOpeningAbstractState.prototype.init = function( ) {\n} ;\n\n\nOpeningAbstractState.prototype.runStep = function( ) {\n} ;\n\n\nOpeningAbstractState.prototype.handleKeyDown = function( e ) {\n} ;\n\n\nOpeningAbstractState.prototype.updateDisplay = function( surface ) {\n} ;\n\n\nOpeningAbstractState.prototype.getImage = function( key ) {\n  return this.opening.getImage( key ) ;\n} ;\n\n\nOpeningAbstractState.prototype.soundEffect = function( key ) {\n  this.opening.soundEffect( key ) ;\n} ;\n\n\nOpeningAbstractState.prototype.soundBGM = function( key ) {\n  this.opening.soundBGM( key ) ;\n} ;\n\n\n\nLogoState = function( opening ) {\n  this.parent = OpeningAbstractState ;\n  this.parent.call( this, opening ) ;\n  this.count = 0 ;\n}\n__inherit( LogoState, OpeningAbstractState ) ;\n\nLogoState._GLOBALALPHA_SPAN = 100 ;\nLogoState._DISPLAY_SPAN = 300 ;\n\n\nLogoState.prototype.init = function( ) {\n  this.count = 0 ;\n} ;\n\n\nLogoState.prototype.runStep = function( ) {\n  this.count++ ;\n  if( this.count > LogoState._DISPLAY_SPAN )\n    this.opening.notifyLogoConclusion( ) ;\n} ;\n\n\nLogoState.prototype.handleKeyDown = function( e ) {\n  switch( e.keyCode ) {\n    case 90: // z\n      this.opening.notifyLogoConclusion( ) ;\n      break ;\n  } ;\n} ;\n\n\nLogoState.prototype.updateDisplay = function( surface ) {\n  this._displayBG( surface ) ;\n  this._displayMessage( surface ) ;\n} ;\n\n\nLogoState.prototype._displayBG = function( surface ) {\n  surface.save( ) ;\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n  surface.fillRect( 0, 0, this.opening.getWidth( ), this.opening.getHeight( ) ) ;\n  surface.restore( ) ;\n} ;\n\n\nLogoState.prototype._displayMessage = function( surface ) {\n  surface.save( ) ;\n\n  if( this.count < LogoState._GLOBALALPHA_SPAN )\n    surface.globalAlpha = this.count / LogoState._GLOBALALPHA_SPAN ;\n  else if( this.count > LogoState._DISPLAY_SPAN - LogoState._GLOBALALPHA_SPAN )\n    surface.globalAlpha = ( LogoState._DISPLAY_SPAN - this.count ) / LogoState._GLOBALALPHA_SPAN ;\n  else\n    surface.globalAlpha = 1.0 ;\n\n  surface.font = \"30px 'Comic Sans MS'\" ;\n  surface.textAlign = 'center' ;\n  surface.textBaseAlign = 'middle' ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.fillText( 'This is a fan STG of Toho-Project', this.opening.getWidth( ) / 2, 200 ) ;\n  surface.fillText( 'Presented by @superhoge', this.opening.getWidth( ) / 2, 300 ) ;\n\n  surface.restore( ) ;\n} ;\n\n\n\nTitleState = function( opening ) {\n  this.parent = OpeningAbstractState ;\n  this.parent.call( this, opening ) ;\n  this.count = 0 ;\n  this.state = 0 ;\n  this.index = 0 ;\n}\n__inherit( TitleState, OpeningAbstractState ) ;\n\nTitleState._WIDTH = 1280 ;\nTitleState._HEIGHT = 960 ;\n\nTitleState._GLOBALALPHA_SPAN = 100 ;\n\nTitleState._STATE_DISPLAYING = 0x0 ;\nTitleState._STATE_DISPLAYED  = 0x1 ;\n\n\nTitleState.prototype.init = function( ) {\n  this.count = 0 ;\n  this.index = 0 ;\n  this.state = TitleState._STATE_DISPLAYING ;\n  this.soundBGM( Game._BGM_TITLE ) ;\n} ;\n\n\nTitleState.prototype.runStep = function( ) {\n  if( this.state == TitleState._STATE_DISPLAYING &&\n      this.count >= TitleState._GLOBALALPHA_SPAN * 2 )\n    this.state = TitleState._STATE_DISPLAYED ;\n\n  this.count++ ;\n} ;\n\n\nTitleState.prototype.updateDisplay = function( surface ) {\n  this._displayBG( surface ) ;\n  this._displayImage( surface ) ;\n  this._displayMessage( surface ) ;\n  this._displayPressKey( surface ) ;\n} ;\n\n\nTitleState.prototype._displayBG = function( surface ) {\n  surface.save( ) ;\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n  surface.fillRect( 0, 0, this.opening.getWidth( ), this.opening.getHeight( ) ) ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.fillRect( 0, 50, this.opening.getWidth( ), this.opening.getHeight( ) - 100 ) ;\n  surface.restore( ) ;\n} ;\n\n\nTitleState.prototype._displayImage = function( surface ) {\n  surface.save( ) ;\n\n  if( this.count < TitleState._GLOBALALPHA_SPAN )\n    surface.globalAlpha = this.count / TitleState._GLOBALALPHA_SPAN ;\n  else\n    surface.globalAlpha = 1.0 ;\n\n  surface.drawImage( this.getImage( Game._IMG_TITLE_BG ),\n                     0,                 \n                     0,\n                     TitleState._WIDTH,\n                     TitleState._HEIGHT,\n                     0,\n                     0,\n                     this.opening.getWidth( ),\n                     this.opening.getHeight( ) ) ;\n  surface.restore( ) ;\n} ;\n\n\nTitleState.prototype._displayMessage = function( surface ) {\n  if( this.count < TitleState._GLOBALALPHA_SPAN )\n    return ;\n\n  surface.save( ) ;\n  surface.font = \"24px 'Comic Sans MS'\" ;\n  surface.textAlign = 'center' ;\n  surface.textBaseAlign = 'middle' ;\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n\n  if( this.count - TitleState._GLOBALALPHA_SPAN < TitleState._GLOBALALPHA_SPAN )\n    surface.globalAlpha = ( this.count - TitleState._GLOBALALPHA_SPAN ) / TitleState._GLOBALALPHA_SPAN ;\n  else\n    surface.globalAlpha = 1.0 ;\n\n  surface.fillText( 'Toho like STG JS', 120, 200 ) ;\n  surface.restore( ) ;\n} ;\n\n\nTitleState.prototype._displayPressKey = function( surface ) {\n  if( this.count < TitleState._GLOBALALPHA_SPAN * 2 )\n    return ;\n\n  surface.save( ) ;\n  surface.font = \"24px 'Comic Sans MS'\" ;\n  surface.textAlign = 'center' ;\n  surface.textBaseAlign = 'middle' ;\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n\n  if( this.index == 0 )\n    surface.globalAlpha = 1.0 ;\n  else\n    surface.globalAlpha = 0.2 ;\n  surface.fillText( 'Start', 120, 300 ) ;\n\n  if( this.index == 1 )\n    surface.globalAlpha = 1.0 ;\n  else\n    surface.globalAlpha = 0.2 ;\n  surface.fillText( 'Replay', 120, 340 ) ;\n\n  surface.restore( ) ;\n} ;\n\n\nTitleState.prototype.handleKeyDown = function( e ) {\n  switch( e.keyCode ) {\n    case 90: // z\n      this.soundEffect( Game._SE_SELECT ) ;\n      if( this.state == TitleState._STATE_DISPLAYED ) {\n        if( this.index == 0 )\n          this.opening.notifyTitleConclusion( ) ;\n        else\n          this.opening.notifyReplaySelectBegin( ) ;\n      } else {\n        this.state = TitleState._STATE_DISPLAYED ;\n        this.count = TitleState._GLOBALALPHA_SPAN * 2 ; // TODO: temporal\n      }\n      break ;\n    case 38: // up\n    case 40: // down\n      if( this.state == TitleState._STATE_DISPLAYED ) {\n        this.soundEffect( Game._SE_SELECT ) ;\n        if( this.index == 0 )\n          this.index = 1 ;\n        else\n          this.index = 0 ;\n      }\n      break ;\n    case 32: // space\n      break ;\n  } ;\n} ;\n\n\n"
  },
  {
    "path": "source/PostReplayState.js",
    "content": "function PostReplayState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n  this.count = 0 ;\n  this.index = 0 ;\n}\n__inherit( PostReplayState, GameState ) ;\n\nPostReplayState._STATE_SELECT               = 0x0 ;\nPostReplayState._STATE_REPLAY_POSTING       = 0x1 ;\nPostReplayState._STATE_REPLAY_POSTING_ERROR = 0x2 ;\n\nPostReplayState._DIR = 'http://gachapin.jp/stg/' ;\n\n\nPostReplayState.prototype.init = function( ) {\n  this.count = 0 ;\n  this.index = 0 ;\n  this.state = PostReplayState._STATE_SELECT ;\n} ;\n\n\n/**\n * TODO: temporal. implement error handling\n */\nPostReplayState.prototype._postReplay = function( ) {\n  var user = window.prompt( 'your name?' ) ;\n  if( ! user )\n    return ;\n  var xhr = new XMLHttpRequest( ) ;\n  xhr.open( 'POST', PostReplayState._DIR + 'post.cgi', true ) ;\n  var self = this ;\n  xhr.onload = function( ) {\n    self.game.notifyQuitStage( ) ; // TODO: temporal\n  } ;\n  xhr.onerror = function( e ) {\n    window.alert( e ) ;\n  } ;\n  // TODO: temporal\n  params = this.game.states[ Game._STATE_IN_STAGE ].exportPlayRecord( ) ;\n  params.user = user ;\n  xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' ) ;\n  xhr.send( this._encode( params ) ) ;\n  this.state = PostReplayState._STATE_REPLAY_POSTING ;\n} ;\n\n\nPostReplayState.prototype._encode = function( data ) {\n  var params = [];\n\n  for( var name in data ) {\n    var value = data[ name ];\n    var param = encodeURIComponent( name ).replace( /%20/g, '+' )\n        + '=' + encodeURIComponent( value ).replace( /%20/g, '+' );\n\n    params.push( param );\n  }\n\n  return params.join( '&' );\n} ;\n\n\nPostReplayState.prototype.runStep = function( ) {\n  this.count++ ;\n} ;\n\n\nPostReplayState.prototype.updateDisplay = function( surface ) {\n  this.game.clear( surface ) ;\n  this._displayBG( surface ) ;\n  this._displayMessage( surface ) ;\n  if( this.state == PostReplayState._STATE_SELECT )\n    this._displayQuestion( surface ) ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nPostReplayState.prototype._displayBG = function( surface ) {\n  surface.save( ) ;\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n  surface.fillRect( 0, 0, this.getWidth( ), this.getHeight( ) ) ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.fillRect( 0, 50, this.getWidth( ), this.getHeight( ) - 100 ) ;\n\n  surface.globalAlpha = 0.05 ;\n  surface.drawImage( this.game.getImage( Game._IMG_TITLE_BG ),\n                     0,                 \n                     0,\n                     TitleState._WIDTH,\n                     TitleState._HEIGHT,\n                     0,\n                     0,\n                     this.getWidth( ),\n                     this.getHeight( ) ) ;\n\n  surface.globalAlpha = 0.5 ;\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n  surface.fillRect( 0, 0, this.getWidth( ), this.getHeight( ) ) ;\n\n  surface.restore( ) ;\n} ;\n\n\nPostReplayState.prototype._displayMessage = function( surface ) {\n  surface.save( ) ;\n  surface.font = \"30px 'Comic Sans MS'\" ;\n  surface.textAlign = 'center' ;\n  surface.textBaseAlign = 'middle' ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.fillText( 'Replay Select', this.getWidth( ) / 2, 35 ) ;\n\n  // TODO: temporal\n  if( this.state == PostReplayState._STATE_REPLAY_POSTING ) {\n    surface.fillText( 'Saving...', this.getWidth( ) / 2, this.getHeight( ) / 2 ) ;\n  }\n\n  surface.restore( ) ;\n\n} ;\n\n\nPostReplayState.prototype._displayQuestion = function( surface ) {\n  surface.save( ) ;\n  surface.font = \"30px 'Comic Sans MS'\" ;\n  surface.textAlign = 'center' ;\n  surface.textBaseAlign = 'middle' ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.fillText( 'Will you save your replay?', this.getWidth( ) / 2, 100 ) ;\n\n  if( this.index == 0 )\n    surface.globalAlpha = 1.0 ;\n  else\n    surface.globalAlpha = 0.4 ;\n  surface.fillText( 'Yes', this.getWidth( ) / 2, 200 ) ;\n\n  if( this.index == 1 )\n    surface.globalAlpha = 1.0 ;\n  else\n    surface.globalAlpha = 0.4 ;\n  surface.fillText( 'No', this.getWidth( ) / 2, 250 ) ;\n\n  surface.restore( ) ;\n} ;\n\n\nPostReplayState.prototype.handleKeyDown = function( e ) {\n  switch( e.keyCode ) {\n    case 38: // up\n    case 40: // down\n      this._soundEffect( Game._SE_SELECT ) ;\n      if( this.index == 0 )\n        this.index = 1 ;\n      else\n        this.index = 0 ;\n      break ;\n    case 90: // z\n      this._soundEffect( Game._SE_SELECT ) ;\n      if( this.index == 0 )\n        this._postReplay( ) ;\n      else\n        this.game.notifyQuitStage( ) ; // TODO: temporal\n      break ;\n  } ;\n} ;\n\n\nPostReplayState.prototype.handleKeyUp = function( e ) {\n\n} ;\n"
  },
  {
    "path": "source/ReplaySelectState.js",
    "content": "function ReplaySelectState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n  this.count = 0 ;\n  this.index = 0 ;\n  this.list = [ ] ;\n}\n__inherit( ReplaySelectState, GameState ) ;\n\nReplaySelectState._STATE_PREPARE              = 0x0 ;\nReplaySelectState._STATE_LIST_LOADING         = 0x1 ;\nReplaySelectState._STATE_LIST_LOADING_ERROR   = 0x2 ;\nReplaySelectState._STATE_SELECT               = 0x3 ;\nReplaySelectState._STATE_REPLAY_LOADING       = 0x4 ;\nReplaySelectState._STATE_REPLAY_LOADING_ERROR = 0x5 ;\n\nReplaySelectState._DIR = 'http://gachapin.jp/stg/' ;\n\n\nReplaySelectState.prototype.init = function( ) {\n  this.count = 0 ;\n  this.index = 0 ;\n  this.list = [ ] ;\n  this.state = ReplaySelectState._STATE_PREPARE ;\n} ;\n\n\n/**\n * TODO: temporal. implement error handling\n */\nReplaySelectState.prototype.loadReplayList = function( ) {\n  var xhr = new XMLHttpRequest( ) ;\n  xhr.open( 'GET', ReplaySelectState._DIR + 'getlist.cgi', true ) ;\n  var self = this ;\n  xhr.onload = function( ) {\n    self.list = JSON.parse( xhr.responseText ).list ;\n    self.list.pop( ) ;\n    self.state = ReplaySelectState._STATE_SELECT ;\n  } ;\n  xhr.onerror = function( e ) {\n    window.alert( e ) ;\n  } ;\n  xhr.send( null ) ;\n  this.state = ReplaySelectState._STATE_LIST_LOADING ;\n} ;\n\n\n/**\n * TODO: temporal. implement error handling\n */\nReplaySelectState.prototype.loadReplay = function( index ) {\n  var xhr = new XMLHttpRequest( ) ;\n  xhr.open( 'GET', ReplaySelectState._DIR + 'get.cgi?id=' + this.list[ this.index ].id , true ) ;\n  var self = this ;\n  xhr.onload = function( ) {\n    var params = JSON.parse( xhr.responseText ) ;\n    self.game.notifyReplaySelectConclusion( params ) ;\n  } ;\n  xhr.onerror = function( e ) {\n    window.alert( e ) ;\n  } ;\n  xhr.send( null ) ;\n  this.state = ReplaySelectState._STATE_REPLAY_LOADING ;\n} ;\n\n\nReplaySelectState.prototype.runStep = function( ) {\n  if( this.state == ReplaySelectState._STATE_PREPARE ) {\n    this.loadReplayList( ) ;\n  }\n  this.count++ ;\n} ;\n\n\nReplaySelectState.prototype.updateDisplay = function( surface ) {\n  this.game.clear( surface ) ;\n  this._displayBG( surface ) ;\n  this._displayMessage( surface ) ;\n\n  switch( this.state ) {\n    case ReplaySelectState._STATE_PREPARE:\n      break ;\n    case ReplaySelectState._STATE_LIST_LOADING:\n      break ;\n    case ReplaySelectState._STATE_LIST_LOADING_ERROR:\n      break ;\n    case ReplaySelectState._STATE_SELECT:\n      this._displayList( surface ) ;\n      break ;\n    case ReplaySelectState._STATE_REPLAY_LOADING:\n      break ;\n    case ReplaySelectState._STATE_REPLAY_LOADING_ERROR:\n      break ;\n  }\n\n} ;\n\n\n/**\n * TODO: temporal\n */\nReplaySelectState.prototype._displayBG = function( surface ) {\n  surface.save( ) ;\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n  surface.fillRect( 0, 0, this.getWidth( ), this.getHeight( ) ) ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.fillRect( 0, 50, this.getWidth( ), this.getHeight( ) - 100 ) ;\n\n  surface.globalAlpha = 0.05 ;\n  surface.drawImage( this.game.getImage( Game._IMG_TITLE_BG ),\n                     0,                 \n                     0,\n                     TitleState._WIDTH,\n                     TitleState._HEIGHT,\n                     0,\n                     0,\n                     this.getWidth( ),\n                     this.getHeight( ) ) ;\n\n  surface.globalAlpha = 0.5 ;\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n  surface.fillRect( 0, 0, this.getWidth( ), this.getHeight( ) ) ;\n\n  surface.restore( ) ;\n} ;\n\n\nReplaySelectState.prototype._displayMessage = function( surface ) {\n  surface.save( ) ;\n  surface.font = \"30px 'Comic Sans MS'\" ;\n  surface.textAlign = 'center' ;\n  surface.textBaseAlign = 'middle' ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.fillText( 'Replay Select', this.getWidth( ) / 2, 35 ) ;\n\n  // TODO: temporal\n  if( this.state == ReplaySelectState._STATE_LIST_LOADING ||\n      this.state == ReplaySelectState._STATE_REPLAY_LOADING ) {\n    surface.fillText( 'Loading...', this.getWidth( ) / 2, this.getHeight( ) / 2 ) ;\n  }\n\n  surface.restore( ) ;\n\n} ;\n\n\nReplaySelectState.prototype._displayList = function( surface ) {\n  var h = 100 ;\n  var w = 50 ;\n  surface.save( ) ;\n  surface.font = \"16px 'Comic Sans MS'\" ;\n  surface.textAlign = 'left' ;\n  surface.textBaseAlign = 'middle' ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  for( var i = 0; i < this.list.length; i++ ) {\n    if( i == this.index )\n      surface.globalAlpha = 1.0 ;\n    else\n      surface.globalAlpha = 0.4 ;\n    surface.fillText( this._buildReplayStrings( this.list[ i ] ), w, h + 20 * i ) ;\n  }\n  surface.restore( ) ;\n} ;\n\n\nReplaySelectState.prototype._buildReplayStrings = function( params ) {\n  var buffer = '' ;\n  buffer += params.id + ': ' + params.user + ' ' ;\n  if( params.characterIndex == 0 ) {\n    buffer += 'Reimu' ;\n  } else {\n    buffer += 'Marisa' ;\n  }\n  buffer += ' ' + this._toStringsFromDate( params.datetime ) ;\n  return buffer ;\n} ;\n\n\nReplaySelectState.prototype._toStringsFromDate = function( s ) {\n  var date = new Date( s ) ;\n  return [\n           date.getMonth( ) + 1,\n           date.getDate( ),\n           date.getFullYear( ),\n         ].join( '/' ) + ' ' +\n         [\n           date.getHours( ),\n           date.getMinutes( ),\n           date.getSeconds( ),\n         ].join( ':' ) ;\n} ;\n\n\nReplaySelectState.prototype.handleKeyDown = function( e ) {\n  switch( e.keyCode ) {\n    case 38: // up\n      this.index-- ;\n      if( this.index < 0 )\n        this.index = 0 ;\n      this._soundEffect( Game._SE_SELECT ) ;\n      break ;\n    case 40: // down\n      this.index++ ;\n      if( this.index >= this.list.length )\n        this.index = this.list.length - 1 ;\n      this._soundEffect( Game._SE_SELECT ) ;\n      break ;\n    case 88: // x\n      this.game.notifyLoadingConclusion( ) ; // TODO: temporal\n      break ;\n    case 90: // z\n      this.loadReplay( ) ;\n      this._soundEffect( Game._SE_SELECT ) ;\n      break ;\n  } ;\n} ;\n\n\nReplaySelectState.prototype.handleKeyUp = function( e ) {\n\n} ;\n"
  },
  {
    "path": "source/SpellCard.js",
    "content": "/**\n * no plan to port this class to WebGL so far cuz\n * it cannot be performance critical.\n */\nfunction SpellCardManager( gameState ) {\n  this.parent = ElementManager ;\n  this.parent.call( this, gameState ) ;\n} ;\n__inherit( SpellCardManager, ElementManager ) ;\n\n\nSpellCardManager.prototype._initFactory = function( ) {\n  this.factory = new SpellCardFactory( this.gameState, this.gameState.width, this.gameState.height ) ;\n} ;\n\n\nSpellCardManager.prototype.create = function( boss ) {\n  this.addElement( this.factory.create( boss ) ) ;\n} ;\n\n\n\nfunction SpellCardFactory( gameState, maxX, maxY ) {\n  this.parent = ElementFactory ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n} ;\n__inherit( SpellCardFactory, ElementFactory ) ;\n\nSpellCardFactory.prototype._NUM = 10 ;\nSpellCardFactory.prototype._FIGHTER_IMAGES = [ Game._IMG_STAND_REIMU, Game._IMG_STAND_MARISA ] ;\nSpellCardFactory.prototype._ENEMY_IMAGES   = [ Game._IMG_STAND_MOKOU, Game._IMG_STAND_RUMIA, Game._IMG_STAND_CHILNO ] ;\nSpellCardFactory.prototype._PARAMS = [\n  { 'x': 240, 'y': 240, 'v': { 'r': 3, 'theta':150, 'raa': -0.005, 'rrange': { 'min': 1 } } },\n  { 'x': 240, 'y': 240, 'v': { 'r': 3, 'theta': 30, 'raa': -0.005, 'rrange': { 'min': 1 } } },\n] ;\n\nSpellCardFactory.prototype._initFreelist = function() {\n  this.freelist = new SpellCardFreeList(this._NUM, this.gameState); \n};\n\n\n/**\n *\n */\nSpellCardFactory.prototype.create = function( element ) {\n  var params = element instanceof Fighter ? this._PARAMS[0] : this._PARAMS[1];\n  var card = this.freelist.get();\n  card.init(params, this._getImage(element), element);\n  return card;\n};\n\n\nSpellCardFactory.prototype._getImage = function( element ) {\n  var image ;\n  var vector = null ;\n  if( element instanceof Fighter ) {\n    vector = { 'r': 3, 'theta':150, 'raa': -0.005, 'rrange': { 'min': 1 } } ;\n    image = this.gameState.getImage( this._FIGHTER_IMAGES[ element.characterIndex ] ) ;\n    image.width = 400 ;\n  } else {\n    vector = { 'r': 3, 'theta': 30, 'raa': -0.005, 'rrange': { 'min': 1 } } ;\n    // TODO: temporary\n    if( element.character == 'rumia' ) {\n      image = this.gameState.getImage( this._ENEMY_IMAGES[ 1 ] ) ;\n      image.width = 600 ;\n    } else if( element.character == 'chilno' ) {\n      image = this.gameState.getImage( this._ENEMY_IMAGES[ 2 ] ) ;\n      image.width = 550 ;\n    } else {\n      image = this.gameState.getImage( this._ENEMY_IMAGES[ 0 ] ) ;\n      image.width = 512 ;\n    }\n  }\n  return image ;\n} ;\n\n\n\nfunction SpellCardFreeList( num, gameState ) {\n  this.parent = ElementFreeList ;\n  this.parent.call( this, num, gameState ) ;\n}\n__inherit( SpellCardFreeList, ElementFreeList ) ;\n\n\nSpellCardFreeList.prototype._generateElement = function( ) {\n  return new SpellCard( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;\n} ;\n\n\n\n/**\n * This class shows Spell card background.\n * That is character image and spellcard name strings.\n */\nfunction SpellCard( gameState, maxX, maxY ) {\n  this.parent = Element ;\n  this.parent.call( this, gameState, maxX, maxY ) ;\n  this.boss = null ;\n  this.baseX = 0 ;\n  this.baseY = 0 ;\n}\n__inherit( SpellCard, Element ) ;\n\nSpellCard.prototype._HEIGHT = 600 ;\n\n\n__copyParentMethod(SpellCard, Element, 'init');\nSpellCard.prototype.init = function(params, image, boss) {\n  this.Element_init(params, image);\n  this.boss = boss;\n\n  this.width = image.width;\n  this.height = this._HEIGHT;\n  this.collisionWidth = this.width;\n  this.collisionHeight = this.height;\n  this.indexX = 0;\n  this.indexY = 0;\n  this.baseX = this.getX();\n  this.baseY = this.getY();\n};\n\n\n/**\n * still uses display() method.\n * TODO: temporal\n */\n__copyParentMethod(SpellCard, Element, 'display');\nSpellCard.prototype.display = function(surface) {\n  surface.save();\n  surface.globalAlpha = 0.4;\n  this.Element_display(surface);\n  this.displaySpellCardName(surface);\n  surface.restore();\n//  surface.fillText( x + ':' + y, x, y ) ;\n};\n\n\nSpellCard.prototype.displaySpellCardName = function(surface) {\n  surface.save();\n  surface.fillStyle = 'rgb(255, 255, 255)';\n  surface.textAlign = 'center';\n  surface.font = '16px Arial';\n  surface.globalAlpha = 0.8;\n  var x = this.baseX + (this.getX() - this.baseX) / 4;\n  var y = this.baseY + (this.getY() - this.baseY) / 4 + 150;\n  surface.fillText('Spell Card: ' + this.boss.spellCard, x, y);\n  surface.restore();\n};\n\n\n/**\n * TODO: temporal\n */\nSpellCard.prototype.checkLoss = function( ) {\n  return this.count > 100 ? true : false ;\n} ;\n\n"
  },
  {
    "path": "source/StaffRollState.js",
    "content": "function StaffRollState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n  this.count = 0 ;\n  this.finished = false ;\n}\n__inherit( StaffRollState, GameState ) ;\n\n\nStaffRollState._MESSAGE_SPEED = 1 ;\n\n\nStaffRollState.prototype.init = function( ) {\n  this.finished = false ;\n  this._soundBGM( Game._BGM_ENDING ) ;\n} ;\n\n\nStaffRollState.prototype.runStep = function( ) {\n  this.count++ ;\n} ;\n\n\nStaffRollState.prototype.updateDisplay = function( surface ) {\n  this.game.clear( surface ) ;\n  this._displayBG( surface ) ;\n  this._displayMessage( surface ) ;\n} ;\n\n\nStaffRollState.prototype._displayBG = function( surface ) {\n  surface.save( ) ;\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n  surface.fillRect( 0, 0, this.getWidth( ), this.getHeight( ) ) ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.fillRect( 0, 50, this.getWidth( ), this.getHeight( ) - 100 ) ;\n\n  surface.globalAlpha = 0.05 ;\n  surface.drawImage( this.game.getImage( Game._IMG_TITLE_BG ),\n                     0,                 \n                     0,\n                     TitleState._WIDTH,\n                     TitleState._HEIGHT,\n                     0,\n                     0,\n                     this.getWidth( ),\n                     this.getHeight( ) ) ;\n\n  surface.restore( ) ;\n} ;\n\n\nStaffRollState.prototype._displayMessage = function( surface ) {\n\n  var messages = [ ] ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( 'Staff' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( 'Game Engine' ) ;\n  messages.push( '@superhoge' ) ;\n  messages.push( '' ) ;\n  messages.push( 'Anything except for' ) ;\n  messages.push( 'Graphics and Sound' ) ;\n  messages.push( '@superhoge' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( 'Original is' ) ;\n  messages.push( 'Touhou Project' ) ;\n  messages.push( 'Team Shanghai Alice' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( 'Presented by' ) ;\n  messages.push( 'Toho-like JS project' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( '' ) ;\n  messages.push( 'And you.' ) ;\n\n  surface.save( ) ;\n  surface.font = '30pt Calibri' ;\n  surface.textAlign = 'center' ;\n  surface.textBaseline = 'middle' ;\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n\n  var dh = 50 ;\n  var max = ( this.getHeight( ) / 2 + dh * messages.length ) / StaffRollState._MESSAGE_SPEED ;\n  var count = ( this.count > max ) ? max : this.count ;\n\n  // TODO: temporal\n  if( count >= max )\n    this.finished = true ;\n\n  var h = this.getHeight( ) - count * StaffRollState._MESSAGE_SPEED ;\n\n  for( var i = 0; i < messages.length; i++ ) {\n    surface.fillText( messages[ i ], this.getWidth( ) / 2, h + dh * i ) ;\n  }\n\n  surface.restore( ) ;\n} ;\n\n\nStaffRollState.prototype.handleKeyDown = function( e ) {\n  switch( e.keyCode ) {\n    case 90: // z\n      if( ! this.finished )\n        return ;\n      this._soundEffect( Game._SE_SELECT ) ;\n      this.game.notifyQuitStage( true ) ; // TODO: temporal\n      break ;\n  } ;\n} ;\n\n\nStaffRollState.prototype.handleKeyUp = function( e ) {\n} ;\n"
  },
  {
    "path": "source/StageState.js",
    "content": "function StageState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n\n  this.fighter              = null; // me\n  this.fighter2             = null; // other\n  this.fighterManager       = null;\n  this.fighterOptionManager = null ;\n  this.bulletManager        = null ;\n  this.bombManager          = null ;\n  this.enemyManager         = null ;\n  this.enemyBulletManager   = null ;\n  this.effectManager        = null ;\n  this.bossManager          = null ;\n  this.itemManager          = null ;\n  this.spellCardManager     = null ;\n  this.spellCard            = null ;\n  this.backgroundManager    = null;\n\n  this.params = __stageParams ; // TODO: temporal\n  this.stageIndex = 0 ;\n  this.count = 0 ;\n  this.animationCount = 0 ;\n  this.replayCount = 0 ;\n  this.oldTime = 0 ;\n  this.graze = 0;\n  this.score = 0 ;\n  this.viewScore = 0 ;\n  this.players = 3 ;\n  this.bombs = 2 ;\n  this.bombCount = 0 ;\n  this.bossSpellCount = 0 ;\n  this.pending = 0 ;\n  this.bgScale = 1 ;\n  this.didContinue = false ;\n\n  this.initialized = false ; // TODO: temporal\n  this.playRecords = [ ] ;\n  this.autoplayIndex = 0 ;\n  this.autoplayParams = [ ] ;\n  this.baseCharacterIndex = 0 ;\n  this.baseCharacterIndex2 = 0 ;\n  this.seed = null ;\n  this.viewFromFighter = false;\n\n  this.state = this._STATE_SHOOTING ;\n//  this.state = this._STATE_TALK ;\n//  this.state = this._STATE_CLEAR ;\n\n  this.states = [ ] ;\n  this.states[ this._STATE_SHOOTING ]  = new ShootingState( this ) ;\n  this.states[ this._STATE_TALK ]      = new TalkState( this ) ;\n  this.states[ this._STATE_CLEAR ]     = new ClearState( this ) ;\n  this.states[ this._STATE_GAME_OVER ] = new GameOverState( this ) ;\n\n  this.keyFlag = 0;\n  this.keyFlags = new KeyFlagQueue();\n  this.keyFlagHistories = new KeyFlagQueue();\n\n  this.keyFlag2 = 0;\n  this.keyFlags2 = new KeyFlagQueue();\n\n  this.syncCount = 0;\n  this.lag = this._BUTTON_LAG;\n\n  this.waitingForOther = false;\n\n}\n__inherit( StageState, GameState ) ;\n\n// only for reference\nStageState.prototype.Randomizer = __randomizer;\n\nStageState.prototype._BUTTON_LAG = 1;\nStageState.prototype._BUTTON_HISTORY = 4;\n\nStageState.prototype._BUTTON_LEFT  = 0x01;\nStageState.prototype._BUTTON_UP    = 0x02;\nStageState.prototype._BUTTON_RIGHT = 0x04;\nStageState.prototype._BUTTON_DOWN  = 0x08;\nStageState.prototype._BUTTON_Z     = 0x10;\nStageState.prototype._BUTTON_X     = 0x20;\nStageState.prototype._BUTTON_SHIFT = 0x40;\nStageState.prototype._BUTTON_SPACE = 0x80;\n\nStageState.prototype._FLAG_FIGHTER_DEAD    =    0x1 ;\nStageState.prototype._FLAG_BOSS_EXIST      =    0x2 ;\nStageState.prototype._FLAG_BOSS_SPELLCARD  =    0x4 ;\nStageState.prototype._FLAG_BOMB            =    0x8 ;\nStageState.prototype._FLAG_STAGE_TITLE     =   0x10 ;\nStageState.prototype._FLAG_SE_ENEMY_DAMAGE =   0x20 ;\nStageState.prototype._FLAG_SE_ENEMY_VANISH =   0x40 ;\nStageState.prototype._FLAG_SE_SHOT         =   0x80 ;\nStageState.prototype._FLAG_SE_ENEMY_SHOT   =  0x100 ;\nStageState.prototype._FLAG_SE_DEAD         =  0x200 ;\nStageState.prototype._FLAG_SE_GRAZE        =  0x400 ;\nStageState.prototype._FLAG_SE_POWERUP      =  0x800 ;\nStageState.prototype._FLAG_SE_POWER_EFFECT = 0x1000 ;\nStageState.prototype._FLAG_AUTO_PLAY       = 0x2000 ;\n\nStageState.prototype._BOMB_SPAN = 100 ;\nStageState.prototype._BOSS_SPELL_SPAN = 100 ;\nStageState.prototype._STAGE_TITLE_SPAN = 300 ;\n\nStageState.prototype._STATE_SHOOTING  = 0x1 ;\nStageState.prototype._STATE_TALK      = 0x2 ;\nStageState.prototype._STATE_CLEAR     = 0x3 ;\nStageState.prototype._STATE_GAME_OVER = 0x4 ;\n\n\nStageState.prototype.init = function( params ) {\n  this.state = this._STATE_SHOOTING ;\n\n  if(params.lag !== void 0)\n    this.lag = params.lag;\n\n  this.keyFlag = 0;\n  this.keyFlag2 = 0;\n  this.keyFlags.free();\n  this.keyFlags2.free();\n  this.keyFlagHistories.free();\n\n  for(var i = 0; i < this.lag; i++) {\n    this.keyFlags.push(0);\n    this.keyFlags2.push(0);\n    this.keyFlagHistories.push(0);\n  }\n\n  this.syncCount = 0;\n  this.waitingForOther = false;\n  this.viewFromFighter = false;\n\n  if( ! this.initialized ) {\n    this._initBackground();\n    this._initFighter( ) ;\n    this._initEnemies( ) ;\n    this._initBullets( ) ;\n    this._initBomb( ) ;\n    this._initEnemyBullets( ) ;\n    this._initItems( ) ;\n    this._initSpellCards( ) ;\n    this.initialized = true ;\n  } else {\n    this.reset( ) ;\n  }\n  if( params.autoplay ) {\n    this.setFlag( this._FLAG_AUTO_PLAY ) ;\n    this.autoplayParams = params.autoplayParams.params ;\n    this.seed = params.autoplayParams.seed ;\n    this.baseCharacterIndex = params.autoplayParams.characterIndex ;\n  } else {\n    this.clearFlag( this._FLAG_AUTO_PLAY ) ;\n    this.seed = params.seed;\n    this.baseCharacterIndex = params.characterIndex ;\n    this.baseCharacterIndex2 = params.characterIndex2;\n  }\n  this.fighter.setCharacterIndex(this.baseCharacterIndex);\n  if(this.game.isMultiPlay()) {\n    this.fighter2.setCharacterIndex(this.baseCharacterIndex2);\n  }\n  this.Randomizer.seed( this.seed ) ;\n  this._soundBGM( Game._BGM_1 ) ;\n  this.sendMessageToServer(GameSocket._STATE_BEGIN_GAME);\n} ;\n\n\nStageState.prototype._initBackground = function() {\n  this.backgroundManager = new BackgroundManager(this);\n  this.backgroundManager.initDrawer(this.game.bgLayer, null);\n};\n\n/**\n * TODO: temporal\n */\nStageState.prototype._initFighter = function() {\n  this.fighterManager = new FighterManager(this);\n\n // TODO: temporal\n  if(this.game.isMultiPlay()) {\n    this.fighter = this.fighterManager.getMe(this.game.isMaster());\n    this.fighter2 = this.fighterManager.getOther(this.game.isMaster());\n  } else {\n    this.fighter = this.fighterManager.getFighter();\n  }\n\n  this.fighterManager.initDrawer(this.game.bgLayer, null);\n  this.fighterOptionManager = new FighterOptionManager(\n                                    this, this.fighterManager.elements);\n  this.fighterOptionManager.initDrawer(this.game.bgLayer, null);\n};\n\n\nStageState.prototype._initEnemies = function( ) {\n  this.enemyManager = new EnemyManager( this, __enemiesParams ) ;\n  this.bossManager = new BossManager( this, __bossesParams ) ;\n  this.effectManager = new EffectManager( this ) ;\n\n  this.enemyManager.initDrawer(this.game.bgLayer, null);\n  this.bossManager.initDrawer(this.game.bgLayer, null);\n  this.effectManager.initDrawer(this.game.bgLayer, null);\n} ;\n\n\nStageState.prototype._initBullets = function() {\n  this.bulletManager = new BulletManager(this, __bulletsParams);\n  this.bulletManager.initDrawer(this.game.bgLayer, null);\n};\n\n\nStageState.prototype._initBomb = function() {\n  this.bombManager = new BombManager(this);\n  this.bombManager.initDrawer(this.game.bgLayer, null);\n};\n\n\nStageState.prototype._initEnemyBullets = function() {\n  this.enemyBulletManager = new EnemyBulletManager(this, __enemyBulletsParams);\n  this.enemyBulletManager.initDrawer(this.game.bgLayer, null);\n};\n\n\nStageState.prototype._initItems = function() {\n  this.itemManager = new ItemManager(this);\n  this.itemManager.initDrawer(this.game.bgLayer, null);\n};\n\n\nStageState.prototype._initSpellCards = function( ) {\n  this.spellCardManager = new SpellCardManager( this ) ;\n} ;\n\n\nStageState.prototype._start = function() {\n  this.peer.send({id: this._PEER_ID_START, seed: this.seed});\n};\n\n\nStageState.prototype.runStep = function( ) {\n  if( this.isFlagSet( this._FLAG_AUTO_PLAY ) &&\n      this.autoplayIndex < this.autoplayParams.length ) {\n    this._actAsRecord( ) ;\n  // TODO: temporal\n  } else if(! this.isFlagSet(this._FLAG_AUTO_PLAY)) {\n    this.keyFlags.push(this.keyFlag);\n    this.keyFlagHistories.push(this.keyFlag);\n    this.keyFlagHistories.shiftUntilLengthIs(this._BUTTON_HISTORY);\n    this._deployKeyFlag(this.keyFlags.shift(), this.fighter);\n    if(this.game.isMultiPlay()) {\n      this._deployKeyFlag(this.keyFlags2.shift(), this.fighter2);\n    }\n  }\n  this.replayCount++;\n  this.syncCount++;\n\n  // TODO: temporal\n  if( this.state == this._STATE_SHOOTING ) {\n    this._updateBGScale( ) ;\n\n    this.enemyManager.runStep( ) ;\n    this.effectManager.runStep( ) ;\n    this.bossManager.runStep( ) ;\n    this.enemyBulletManager.runStep( ) ;\n    this.itemManager.runStep( ) ;\n    this.fighterManager.runStep( ) ;\n    this.fighterOptionManager.runStep( ) ;\n    this.bulletManager.runStep( ) ;\n    this.bombManager.runStep( ) ;\n    this.spellCardManager.runStep( ) ;\n\n    this.enemyBulletManager.checkGrazeWithFighters(this.fighterManager.elements);\n\n    this.bulletManager.checkCollisionWithEnemies(this.enemyManager.elements);\n    this.enemyManager.checkCollisionWithFighters(this.fighterManager.elements);\n    this.enemyBulletManager.checkCollisionWithFighters(this.fighterManager.elements);\n    this.itemManager.checkCollisionWithFighters(this.fighterManager.elements);\n    if( this.bossManager.existBoss()) {\n      this.bulletManager.checkCollisionWithBoss(this.bossManager.getBoss());\n      this.bossManager.checkCollisionWithFighters(this.fighterManager.elements);\n    }\n\n    this.enemyManager.checkLoss( ) ;\n    this.effectManager.checkLoss( ) ;\n    this.bulletManager.checkLoss( ) ;\n    this.bombManager.checkLoss( ) ;\n    this.enemyBulletManager.checkLoss( ) ;\n    this.itemManager.checkLoss( ) ;\n    this.bossManager.checkLoss( ) ;\n    this.spellCardManager.checkLoss( ) ;\n\n    this._soundEffectDependsOnFlag( ) ;\n\n    // TODO: temporal\n    if( this.isFlagSet( this._FLAG_FIGHTER_DEAD ) &&\n        ! this.fighter.isFlagSet( this.fighter._FLAG_UNHITTABLE ) )\n      this.clearFlag( this._FLAG_FIGHTER_DEAD ) ;\n    if( this.isFlagSet( this._FLAG_BOMB ) &&\n        this.count > this.bombCount + this._BOMB_SPAN )\n      this.clearFlag( this._FLAG_BOMB ) ;\n\n    // TODO: temporal\n    if( this.isFlagSet( this._FLAG_BOSS_SPELLCARD ) &&\n        this.count > this.bossSpellCount + this._BOSS_SPELL_SPAN )\n      this.clearFlag( this._FLAG_BOSS_SPELLCARD ) ;\n\n    if( this.isFlagSet( this._FLAG_BOSS_EXIST ) )\n      this.pending++ ;\n\n    if( this.count < this._STAGE_TITLE_SPAN ) {\n      this.setFlag( this._FLAG_STAGE_TITLE ) ;\n    } else {\n      this.clearFlag( this._FLAG_STAGE_TITLE ) ;\n    }\n  }\n\n  if(this.score > this.viewScore) {\n    this.viewScore += 1000;\n    if(this.viewScore > this.score)\n      this.viewScore = this.score;\n  }\n  this.states[ this.state ].runStep( ) ;\n  this.backgroundManager.runStep();\n\n  this.animationCount++ ;\n\n  // TODO: temporal\n  // this member should be moved to ShootingState?\n  if( this.state == this._STATE_SHOOTING ) {\n    this.count++ ;\n  }\n\n  // TODO: temporal\n  if(this.game.isMultiPlay())\n    this._sync();\n\n  // TODO: temporal\n  this.keyFlag = this.states[this.state].resetButton(this.keyFlag);\n} ;\n\n\n// TODO: temporal\nStageState.prototype.doRunNextStep = function() {\n  return this.game.isMultiPlay() ? false : true;\n};\n\n\n/**\n * TODO: temporal. Should be in Background?\n */\nStageState.prototype._updateBGScale = function( ) {\n  if( ! this.params[ this.stageIndex ].bgScale )\n    return ;\n  if( this.isFlagSet( this._FLAG_BOSS_EXIST ) )\n    return ;\n\n  for( var i = 0; i < this.params[ this.stageIndex ].bgScale.length; i++ ) {\n    var value = this.params[ this.stageIndex ].bgScale[ i ] ;\n    if( this.count >= value.beginCount + this.pending &&\n        this.count <  value.endCount   + this.pending ) {\n      if( value.a )\n        this.bgScale = value.a ;\n      if( value.d )\n        this.bgScale += value.d ;\n    }\n  }\n} ;\n\n\n/**\n * TODO: temporal\n */\nStageState.prototype._soundEffectDependsOnFlag = function( ) {\n  var game = Game;\n  if( this.isFlagSet( this._FLAG_SE_ENEMY_VANISH ) ) {\n    this._soundEffect( game._SE_ENEMY_VANISH ) ;\n    this.clearFlag( this._FLAG_SE_ENEMY_VANISH ) ;\n    if( this.isFlagSet( this._FLAG_SE_ENEMY_DAMAGE ) ) {\n      this.clearFlag( this._FLAG_SE_ENEMY_DAMAGE ) ;\n    }\n  }\n  if( this.isFlagSet( this._FLAG_SE_ENEMY_DAMAGE ) ) {\n    this._soundEffect( game._SE_ENEMY_DAMAGE ) ;\n    this.clearFlag( this._FLAG_SE_ENEMY_DAMAGE ) ;\n  }\n  if( this.isFlagSet( this._FLAG_SE_SHOT ) ) {\n    this._soundEffect( game._SE_SHOT ) ;\n    this.clearFlag( this._FLAG_SE_SHOT ) ;\n  }\n  if( this.isFlagSet( this._FLAG_SE_ENEMY_SHOT ) ) {\n    this._soundEffect( game._SE_ENEMY_SHOT ) ;\n    this.clearFlag( this._FLAG_SE_ENEMY_SHOT ) ;\n  }\n  if( this.isFlagSet( this._FLAG_SE_DEAD ) ) {\n    this._soundEffect( game._SE_DEAD ) ;\n    this.clearFlag( this._FLAG_SE_DEAD ) ;\n  }\n  if( this.isFlagSet( this._FLAG_SE_GRAZE ) ) {\n    this._soundEffect( game._SE_GRAZE ) ;\n    this.clearFlag( this._FLAG_SE_GRAZE ) ;\n  }\n  if( this.isFlagSet( this._FLAG_SE_POWERUP ) ) {\n    this._soundEffect( game._SE_POWERUP ) ;\n    this.clearFlag( this._FLAG_SE_POWERUP ) ;\n  }\n  if( this.isFlagSet( this._FLAG_SE_POWER_EFFECT ) ) {\n    this._soundEffect( game._SE_POWER_EFFECT ) ;\n    this.clearFlag( this._FLAG_SE_POWER_EFFECT ) ;\n  }\n} ;\n\n\n/**\n * Order is important.\n */\nStageState.prototype.updateDisplay = function( surface ) {\n  this.game.clear( surface ) ;\n  this.game.bgLayer.clear();\n  this._displayBG();\n  this._displayElements( surface ) ;\n  this._displayBossVital( surface ) ;\n  this._displayStageTitle( surface ) ;\n\n  this.states[ this.state ].updateDisplay( surface ) ;\n\n  this._drawSide( surface ) ;\n\n} ;\n\n\n/**\n * TODO: temporal\n */\nStageState.prototype._displayBG = function() {\n  var darken = false;\n  if(this.isFlagSet(this._FLAG_BOMB) || this.spellCard) {\n    darken = true;\n  }\n  this.backgroundManager.draw(this.game.bgLayer, darken);\n};\n\n\nStageState.prototype._displayBossVital = function( surface ) {\n  if( ! this.isFlagSet( this._FLAG_BOSS_EXIST ) )\n    return ;\n\n  surface.save( ) ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n//  surface.globalAlpha = 0.2 ;\n//  surface.fillRect( 50, 15, 380 * 1, 5 ) ;\n  surface.globalAlpha = 0.8 ;\n  surface.fillRect( 50, 15, 380 * this.bossManager.getBoss( ).vital / this.bossManager.getBoss( ).maxVital, 5 ) ;\n\n  // TODO: temporal\n  if( this.spellCard ) {\n    surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n    surface.globalAlpha = 0.4 ;\n    surface.fillRect( 50, 22, 380, 24 ) ;\n    surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n    surface.textAlign = 'right' ;\n    surface.textBaseAlign = 'middle' ;\n    surface.font = '16px Arial' ;\n    surface.globalAlpha = 0.8 ;\n    surface.fillText( 'Spell Card: ' + this.spellCard, 420, 40 ) ;\n  }\n\n  surface.restore( ) ;\n} ;\n\n\n/**\n * The order is important.\n */\nStageState.prototype._displayElements = function( surface ) {\n  this.bulletManager.draw(this.game.bgLayer);\n  this.fighterManager.draw(this.game.bgLayer);\n  this.fighterOptionManager.draw(this.game.bgLayer);\n  this.bombManager.draw(this.game.bgLayer);\n  this.enemyManager.draw(this.game.bgLayer);\n  this.bossManager.draw(this.game.bgLayer);\n  this.effectManager.draw(this.game.bgLayer);\n  this.enemyBulletManager.draw(this.game.bgLayer);\n  this.itemManager.draw(this.game.bgLayer);\n  this.spellCardManager.display(surface);\n} ;\n\n\nStageState.prototype._displayStageTitle = function( surface ) {\n  if( ! this.isFlagSet( this._FLAG_STAGE_TITLE ) )\n    return ;\n\n  surface.save( ) ;\n\n  var alpha = 1.0 ;\n  if( this.count < 100 )\n    alpha = 0.01 * this.count ;\n  else if( this.count > this._STAGE_TITLE_SPAN - 100 )\n    alpha = 0.01 * ( this._STAGE_TITLE_SPAN - this.count ) ;\n\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n  surface.globalAlpha = alpha * 0.2 ;\n  surface.fillRect( 0, 170, 480, 100 ) ;\n\n  surface.globalAlpha = alpha ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.textAlign = 'left' ;\n  surface.font = '16px Arial' ;\n  surface.fillText( 'Stage' + ( this.stageIndex + 1 ), 100, 210 ) ;\n  surface.textAlign = 'right' ;\n  surface.fillText( this.params[ this.stageIndex ].title, 380, 250 ) ;\n  surface.fillRect( 100, 225, 280, 1 ) ;\n  surface.restore( ) ;\n} ;\n\n\n/**\n * TODO: remove strings?\n */\nStageState.prototype._drawSide = function(surface) {\n  surface.save();\n  surface.fillStyle = 'rgb(0, 0, 0)' ;\n  surface.fillRect(this.getWidth(), 0, Game._SIDE_WIDTH, this.getHeight());\n  surface.fillStyle = 'rgb(255, 255, 255)';\n  surface.fillRect(this.getWidth(), 0, 2, this.getHeight());\n  surface.drawImage(this._getFaceImage(), this.getWidth() + 30, 330, 100, 100);\n\n  surface.font = '16px Arial';\n  surface.fillText('Toho-like STG JS', this.getWidth( ) + 15, 70);\n  surface.fillText('for debug', this.getWidth( ) + 15, 210);\n\n  surface.textAlign = 'right';\n  surface.fillText('Score:', this.getWidth() + 70,  100);\n  surface.fillText(this.viewScore, this.getWidth() + 140, 100);\n  surface.fillText('Power:', this.getWidth() + 70, 120);\n  surface.fillText(this.fighter.getPower(), this.getWidth() + 140, 120);\n  surface.fillText('Graze:', this.getWidth() + 70, 140);\n  surface.fillText(this.graze, this.getWidth() + 140, 140);\n  surface.fillText('Players:', this.getWidth() + 70, 160);\n  surface.fillText(this.players, this.getWidth() + 140, 160);\n  surface.fillText('Bomb:', this.getWidth() + 70, 180);\n  surface.fillText(this.bombs, this.getWidth() + 140, 180);\n\n  surface.fillText(this.count, this.getWidth() + 80, 230);\n  surface.fillText(this.bulletManager.getNum(), this.getWidth() + 80, 250);\n  surface.fillText(this.enemyManager.getNum(), this.getWidth() + 80, 270);\n  surface.fillText(this.enemyBulletManager.getNum(), this.getWidth() + 80, 290);\n  surface.fillText(this.itemManager.getNum(), this.getWidth() + 80, 310);\n\n  surface.fillText(parseInt(this.bgScale*1000), this.getWidth() + 140, 230);\n  surface.fillText(this.effectManager.getNum(), this.getWidth() + 140, 250);\n\n  surface.restore();\n};\n\n\nStageState.prototype._getFaceImage = function( ) {\n  switch( this.fighter.characterIndex ) {\n    case 0:\n      if( this.isFlagSet( this._FLAG_BOMB ) )\n        return this.getImage( Game._IMG_REIMU_FACE_4 ) ;\n      if( this.isFlagSet( this._FLAG_FIGHTER_DEAD ) )\n        return this.getImage( Game._IMG_REIMU_FACE_3 ) ;\n      if( this.fighter.isFlagSet( this.fighter._FLAG_SHOT ) )\n        return this.getImage( Game._IMG_REIMU_FACE_2 ) ;\n      return this.getImage( Game._IMG_REIMU_FACE_1 ) ;\n//    case 1:\n    default:\n      if( this.isFlagSet( this._FLAG_BOMB ) )\n        return this.getImage( Game._IMG_MARISA_FACE_4 ) ;\n      if( this.isFlagSet( this._FLAG_FIGHTER_DEAD ) )\n        return this.getImage( Game._IMG_MARISA_FACE_3 ) ;\n      if( this.fighter.isFlagSet( this.fighter._FLAG_SHOT ) )\n        return this.getImage( Game._IMG_MARISA_FACE_2 ) ;\n      return this.getImage( Game._IMG_MARISA_FACE_1 ) ;\n  }\n} ;\n\n\nStageState.prototype.handleKeyDown = function( e ) {\n  // TODO: temporal\n  if(e.keyCode == 89) // y\n    this.viewFromFighter = ~this.viewFromFighter;\n\n  if( this.isFlagSet( this._FLAG_AUTO_PLAY ) )\n    return ;\n//  this.states[ this.state ].handleKeyDown( e ) ;\n  this.keyFlag = this._pushButton(e, this.keyFlag);\n} ;\n\n\nStageState.prototype.handleKeyUp = function( e ) {\n  if( this.isFlagSet( this._FLAG_AUTO_PLAY ) )\n    return ;\n//  this.states[ this.state ].handleKeyUp( e ) ;\n  this.keyFlag = this._releaseButton(e, this.keyFlag);\n} ;\n\n\n/**\n * TODO: temporal\n */\nStageState.prototype._actAsRecord = function( ) {\n  while( this.replayCount >= this.autoplayParams[ this.autoplayIndex ].count ) {\n    for( var key in this.autoplayParams[ this.autoplayIndex ] ) {\n      if( key == 'count' )\n        continue ;\n      var e = { } ;\n      e.keyCode = this._toCharCode( key ) ;\n      if( this.autoplayParams[ this.autoplayIndex ][ key ] ) {\n        this.states[ this.state ].handleKeyDown(e, this.fighter);\n      } else {\n        this.states[ this.state ].handleKeyUp(e, this.fighter);\n      }\n    }\n    this.autoplayIndex++ ;\n    if( this.autoplayIndex >= this.autoplayParams.length )\n      break ;\n  }\n} ;\n\n\nStageState.prototype._toCharCode = function( str ) {\n  switch( str ) {\n    case 's':\n      return 16 ;\n    case 'sp':\n      return 32 ;\n    case 'l':\n      return 37 ;\n    case 'u':\n      return 38 ;\n    case 'r':\n      return 39 ;\n    case 'd':\n      return 40 ;\n    case 'x':\n      return 88 ;\n    case 'z':\n      return 90 ;\n//    default:\n//      throw Error( ) ;\n  }\n} ;\n\n\n/**\n * TODO: temporal\n */\nStageState.prototype.reset = function( ) {\n\n  this.stageIndex = 0 ;\n  this.count = 0 ;\n  this.animationCount = 0 ;\n  this.replayCount = 0 ;\n  this.oldTime = 0 ;\n  this.graze = 0;\n  this.score = 0 ;\n  this.viewScore = 0 ;\n  this.players = 3 ;\n  this.bombs = 2 ;\n  this.bombCount = 0 ;\n  this.bossSpellCount = 0 ;\n  this.pending = 0 ;\n  this.bgScale = 1 ;\n\n  this.playRecords = [ ] ;\n  this.autoplayIndex = 0 ;\n\n  this.spellCard = null ;\n  this.didContinue = false ;\n\n  this.fighterManager.reset( ) ;\n  this.fighterOptionManager.reset( ) ;\n  this.enemyManager.reset( ) ;\n  this.effectManager.reset( ) ;\n  this.bossManager.reset( ) ;\n  this.bombManager.reset( ) ;\n  this.bulletManager.reset( ) ;\n  this.enemyBulletManager.reset( ) ;\n  this.effectManager.reset( ) ;\n  this.itemManager.reset( ) ;\n  this.spellCardManager.reset( ) ;\n  this.backgroundManager.reset();\n\n  this.states[ this._STATE_TALK ].reset( ) ; // TODO: temporal\n\n  this.flags = 0 ;\n\n} ;\n\n\n/**\n * @param record Array\n */\nStageState.prototype.putKeyOnRecord = function( record ) {\n  if( this.didContinue )\n    return ;\n  var h = { 'count': this.replayCount } ;\n  for( var i = 0; i < record.length; i++ )\n    h[ record[ i ] ] = true ;\n  this.playRecords.push( h ) ;\n} ;\n\n\n/**\n * @param record Array\n */\nStageState.prototype.putKeyOffRecord = function( record ) {\n  if( this.didContinue )\n    return ;\n  var h = { 'count': this.replayCount } ;\n  for( var i = 0; i < record.length; i++ )\n    h[ record[ i ] ] = false ;\n  this.playRecords.push( h ) ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nStageState.prototype.exportPlayRecord = function( ) {\n  var params = { } ;\n  params.characterIndex = this.baseCharacterIndex ;\n  params.seed = this.seed ;\n  params.user = 'user' ; // TODO: temporal\n  params.datetime = new Date( ).getTime( ) ;\n\n  var buffer = '' ;\n  buffer += '[\\n' ;\n  for( var i = 0; i < this.playRecords.length; i++ ) {\n    var b = '{' ;\n    var initialized = false ;\n    for( var key in this.playRecords[ i ] ) {\n      if( initialized )\n        b += ', ' ;\n      b += '\"' + key + '\": ' + this.playRecords[ i ][ key ] ;\n      initialized = true ;\n    }\n    b += '}' ;\n    buffer += '    ' + b ;\n    if( i != this.playRecords.length - 1 )\n      buffer += ',\\n' ;\n    else\n      buffer += '\\n' ;\n  }\n  buffer += ']' ;\n\n  params.params = buffer ;\n  return params ;\n} ;\n\n\nStageState.prototype.sendMessageToServer = function(key) {\n  this.game.sendMessageToServer(key);\n};\n\n\nStageState.prototype.notifyFighterGotPowerItem = function( fighter, item ) {\n  this.setFlag( this._FLAG_SE_GRAZE ) ;\n  this.score += 100 ;\n  fighter.incrementPower( 1 ) ;\n} ;\n\n\nStageState.prototype.notifyFighterGotScoreItem = function( fighter, item ) {\n  this.setFlag( this._FLAG_SE_GRAZE ) ;\n  this.score += 1000 ;\n} ;\n\n\nStageState.prototype.notifyFighterPowerUp = function( ) {\n  this.setFlag( this._FLAG_SE_POWERUP ) ;\n} ;\n\n\nStageState.prototype.notifyFighterDoShot = function( fighter ) {\n  if( this.count % 5 != 0 )\n    return ;\n\n  this.bulletManager.create( fighter ) ;\n  this.setFlag( this._FLAG_SE_SHOT ) ;\n} ;\n\n\nStageState.prototype.notifyEnemyDoShot = function( enemy, shot ) {\n  this.enemyBulletManager.create( enemy, shot ) ;\n} ;\n\n\nStageState.prototype.notifyEnemyDidShot = function( enemy, shot ) {\n  if( ! this.isFlagSet( this._FLAG_BOMB ) &&\n      ! this.isFlagSet( this._FLAG_BOSS_SPELLCARD ) )\n    this.setFlag( this._FLAG_SE_ENEMY_SHOT ) ;\n} ;\n\n\nStageState.prototype.notifyBulletHit = function( bullet, enemy ) {\n  this.effectManager.createDamageEffect( enemy ) ;\n  this.setFlag( this._FLAG_SE_ENEMY_DAMAGE ) ;\n  this.score += 10 ;\n} ;\n\n\nStageState.prototype.notifyGraze = function(fighter, bullet) {\n  this.setFlag(this._FLAG_SE_GRAZE);\n  this.graze += 1;\n  bullet.graze -= 1; // TODO: should be in EnemyBullet?\n  this.score += 100;\n  this.effectManager.createGraze(fighter, bullet);\n};\n\n\n/**\n * TODO: temporal\n */\nStageState.prototype.notifyFighterDoBomb = function( fighter ) {\n  if( this.bombs <= 0 )\n    return ;\n  if( this.isFlagSet( this._FLAG_BOMB ) )\n    return ;\n  this.bombs-- ;\n  this.bombCount = this.count ;\n  this.setFlag( this._FLAG_BOMB ) ;\n  this.enemyManager.bomb( fighter ) ;\n  this.enemyBulletManager.bomb( fighter ) ;\n  this.itemManager.beHomingAll( fighter ) ;\n  this.spellCardManager.create( fighter ) ;\n  this.bombManager.create( fighter ) ;\n  this.setFlag( this._FLAG_SE_POWER_EFFECT ) ;\n} ;\n\n\nStageState.prototype.notifyEnemyVanished = function( bullet, enemy ) {\n  this.setFlag( this._FLAG_SE_ENEMY_VANISH ) ;\n  // TODO: temporal\n  if( enemy.powerItem )\n    this.itemManager.createPowerItem(enemy);\n  else if( enemy.scoreItem )\n    this.itemManager.createScoreItem(enemy);\n  this.effectManager.createExplosion(enemy);\n  this.notifyDoEffect( enemy, 'shockwave', null ) ;\n  this.score += 100 ;\n} ;\n\n\nStageState.prototype.notifyBossVanished = function( boss ) {\n  this.enemyBulletManager.beItem(this.fighterManager.getClosestFighter(boss)); // TODO: temporal\n  this.setFlag( this._FLAG_SE_ENEMY_VANISH ) ;\n  this.spellCard = null ;\n\n  this.clearFlag( this._FLAG_BOSS_EXIST ) ;\n  this.score += boss.score ;\n\n  // TODO: temporal\n  if(this.stageIndex == 0 && this.bossManager.index == 1)\n    this.sendMessageToServer(GameSocket._STATE_DESTROY_STAGE1_MID_BOSS);\n  else if(this.stageIndex == 0 && this.bossManager.index == 2)\n    this.sendMessageToServer(GameSocket._STATE_DESTROY_STAGE1_BIG_BOSS);\n  else if(this.stageIndex == 1 && this.bossManager.index == 1)\n    this.sendMessageToServer(GameSocket._STATE_DESTROY_STAGE2_MID_BOSS);\n  else if(this.stageIndex == 1 && this.bossManager.index == 2)\n    this.sendMessageToServer(GameSocket._STATE_DESTROY_STAGE2_BIG_BOSS);\n} ;\n\n\nStageState.prototype.notifyBossVanishEnd = function( boss ) {\n  if( boss.vanishedTalk ) {\n    this.state = this._STATE_TALK ;\n    this.fighterManager.beNeutral( ) ;\n    // TODO: temporal. consider if desync can occur.\n    for(var i = 0; i < this.lag; i++) {\n      this.keyFlags.set(i, this.states[this.state].resetButton(this.keyFlags.get(i)));\n    }\n    for(var i = 0; i < this._BUTTON_HISTORY; i++) {\n      this.keyFlags2.set(i, this.states[this.state].resetButton(this.keyFlags2.get(i)));\n      this.keyFlagHistories.set(i, this.states[this.state].resetButton(this.keyFlagHistories.get(i)));\n    }\n  }\n//  this.state = this._STATE_CLEAR ;\n} ;\n\n\n/**\n * TODO: temporal. especially name is temporal.\n */\nStageState.prototype.notifyBeginTalk = function() {\n  this.state = this._STATE_TALK;\n  this.fighterManager.beNeutral();\n  // TODO: temporal. consider if desync can occur.\n  for(var i = 0; i < this.lag; i++) {\n    this.keyFlags.set(i, this.states[this.state].resetButton(this.keyFlags.get(i)));\n  }\n  for(var i = 0; i < this._BUTTON_HISTORY; i++) {\n    this.keyFlags2.set(i, this.states[this.state].resetButton(this.keyFlags2.get(i)));\n    this.keyFlagHistories.set(i, this.states[this.state].resetButton(this.keyFlagHistories.get(i)));\n  }\n};\n\n\n/**\n * TODO: temporal\n */\nStageState.prototype.notifyFighterDead = function( fighter, element ) {\n\n  this.setFlag( this._FLAG_FIGHTER_DEAD ) ;\n  this.setFlag( this._FLAG_SE_DEAD ) ;\n  this.effectManager.createExplosion(fighter);\n  this.notifyDoEffect(fighter, 'shockwave', null);\n  fighter.setFlag( fighter._FLAG_UNHITTABLE ) ;\n  fighter.deadCount = fighter.count ;\n\n  if( this.players <= 0 ) {\n    this.sendMessageToServer(GameSocket._STATE_GAME_OVER);\n    // TODO: temporal\n    if( this.isFlagSet( this._FLAG_AUTO_PLAY ) ) {\n      this.game.notifyQuitStage( ) ;\n      return ;\n    }\n    this.state = this._STATE_GAME_OVER ;\n    this.states[ this.state ].init( ) ;\n    fighter.beNeutral( ) ;\n    // TODO: temporal. consider if desync can occur.\n    for(var i = 0; i < this.lag; i++) {\n      this.keyFlags.set(i, this.states[this.state].resetButton(this.keyFlags.get(i)));\n    }\n    for(var i = 0; i < this._BUTTON_HISTORY; i++) {\n      this.keyFlags2.set(i, this.states[this.state].resetButton(this.keyFlags2.get(i)));\n      this.keyFlagHistories.set(i, this.states[this.state].resetButton(this.keyFlagHistories.get(i)));\n    }\n    return ;\n  }\n\n  this.bombs = 2 ;\n  this.players-- ;\n  fighter.state = fighter._STATE_ALIVE ;\n  fighter.beDefaultPosition( ) ;\n  fighter.deadCount = fighter.count ;\n\n  this.sendMessageToServer(GameSocket._STATE_DEAD);\n\n} ;\n\n\n/**\n * TODO: temporal\n */\nStageState.prototype.notifyDoEffect = function( element, type, params ) {\n  if(type == 'shockwave' && params)\n    this.effectManager.createBigShockWave( element, type, params ) ;\n  else\n    this.effectManager.create( element, type, params ) ;\n} ;\n\n\nStageState.prototype.notifyBossAppeared = function( boss ) {\n} ;\n\n\nStageState.prototype.notifyBossStageChanged = function( boss ) {\n//  this.enemyBulletManager.removeBulletsOfEnemy( boss ) ;\n  this.enemyBulletManager.beItem(this.fighterManager.getClosestFighter(boss)); // TODO: temporal\n} ;\n\n\n/**\n * TODO: temporal\n */\nStageState.prototype.notifyBeScoreItem = function(fighter, element) {\n  this.itemManager.createHoming(fighter, element);\n};\n\n\nStageState.prototype.notifyBossBecameActive = function( boss ) {\n  this.state = this._STATE_SHOOTING ;\n  if( boss.spellCard ) {\n    this.spellCardManager.create( boss ) ;\n    this.setFlag( this._FLAG_SE_POWER_EFFECT ) ;\n    this.spellCard = boss.spellCard ;\n    this.bossSpellCount = this.count ;\n    this.setFlag( this._FLAG_BOSS_SPELLCARD ) ;\n  }\n  this.setFlag( this._FLAG_BOSS_EXIST ) ;\n} ;\n\n\nStageState.prototype.notifyBossBeginTalk = function( boss ) {\n  // TODO: temporal\n  if( boss.appearedTalk ) {\n    this.state = this._STATE_TALK ;\n    this.fighterManager.beNeutral( ) ;\n    // TODO: temporal. consider if desync can occur.\n    for(var i = 0; i < this.lag; i++) {\n      this.keyFlags.set(i, this.states[this.state].resetButton(this.keyFlags.get(i)));\n    }\n    for(var i = 0; i < this._BUTTON_HISTORY; i++) {\n      this.keyFlags2.set(i, this.states[this.state].resetButton(this.keyFlags2.get(i)));\n      this.keyFlagHistories.set(i, this.states[this.state].resetButton(this.keyFlagHistories.get(i)));\n    }\n  } else {\n    this.notifyBossBecameActive( boss ) ;\n  }\n} ;\n\n\nStageState.prototype.notifyBossMovedNextStage = function( boss ) {\n  this.clearFlag( this._FLAG_BOSS_SPELLCARD ) ; // Just in case.\n  this.setFlag( this._FLAG_SE_ENEMY_VANISH ) ;\n  this.spellCard = null ;\n  this.notifyDoEffect( boss, 'shockwave', {\n    'w': 5,\n    'g': 5,\n    'a': 0.1,\n    'b': 20,\n    'endCount': 50\n  } ) ;\n} ;\n\n\nStageState.prototype.notifyContinue = function( ) {\n  this.didContinue = true ;\n  this.bombs = 2 ;\n  this.players = 3; // TODO: template\n  this.fighterManager.recoverWhenContinue();\n  this.state = this._STATE_SHOOTING ;\n} ;\n\n\nStageState.prototype.notifyQuit = function( ) {\n  this.game.notifyQuitStage( true ) ;\n} ;\n\n\nStageState.prototype.notifyGoNextStage = function( ) {\n  this.state = this._STATE_SHOOTING ;\n  this.count = 0 ;\n  this.animationCount = 0 ;\n  this.pending = 0 ;\n  this.enemyManager.goNextStage( ) ;\n  this.bossManager.goNextStage( ) ;\n  this.backgroundManager.goNextStage();\n} ;\n\n\nStageState.prototype.notifyGameClear = function( ) {\n  // TODO: temporal\n  if( this.isFlagSet( this._FLAG_AUTO_PLAY ) ) {\n    this.game.notifyQuitStage( ) ;\n  } else {\n    this.game.notifyGameClear( ) ;\n  }\n} ;\n\n\nStageState.prototype.notifyStageClear = function( ) {\n  this.clearFlag( this._FLAG_BOSS_SPELLCARD ) ; // Just in case.\n  this.state = this._STATE_CLEAR ;\n  this.states[ this.state ].init( ) ; // TODO: temporal\n  this.viewScore = this.score ;\n} ;\n\n\n/**\n * TODO: rename\n */\nStageState.prototype.isBossExist = function() {\n  return this.isFlagSet(this._FLAG_BOSS_EXIST);\n};\n\n\n/**\n * TODO: rename\n */\nStageState.prototype.isBombExist = function() {\n  return this.isFlagSet(this._FLAG_BOMB);\n};\n\n\n/**\n * TODO: temporal\n */\nStageState.prototype.getWidth = function( ) {\n  return this.game.width - Game._SIDE_WIDTH ;\n} ;\n\n\nStageState.prototype._pushButton = function(e, flag) {\n  switch(e.keyCode) {\n    case 16: // shift\n      flag |= this._BUTTON_SHIFT;\n      break;\n    case 32: // space\n      flag |= this._BUTTON_SPACE;\n      break;\n    case 37: // left\n      flag |= this._BUTTON_LEFT;\n      break;\n    case 38: // up\n      flag |= this._BUTTON_UP;\n      break;\n    case 39: // right\n      flag |= this._BUTTON_RIGHT;\n      break;\n    case 40: // down\n      flag |= this._BUTTON_DOWN;\n      break;\n    // TODO: temporal\n    case 88: // x\n      flag |= this._BUTTON_X;\n      break;\n    case 90: // z\n      flag |= this._BUTTON_Z;\n      break;\n  };\n  return flag;\n};\n\n\nStageState.prototype._releaseButton = function(e, flag) {\n  switch(e.keyCode) {\n    case 16: // shift\n      flag &= ~this._BUTTON_SHIFT;\n      break;\n    case 32: // space\n      flag &= ~this._BUTTON_SPACE;\n      break;\n    case 37: // left\n      flag &= ~this._BUTTON_LEFT;\n      break;\n    case 38: // up\n      flag &= ~this._BUTTON_UP;\n      break;\n    case 39: // right\n      flag &= ~this._BUTTON_RIGHT;\n      break;\n    case 40: // down\n      flag &= ~this._BUTTON_DOWN;\n      break;\n    case 88: // x\n      flag &= ~this._BUTTON_X;\n      break;\n    case 90: // z\n      flag &= ~this._BUTTON_Z;\n      break;\n  };\n  return flag;\n};\n\n\n// TODO: temporal\nStageState.prototype._deployKeyFlag = function(flag, fighter) {\n  var e = {};\n\n  e.keyCode = 16;\n  if(flag & this._BUTTON_SHIFT) {\n    this.states[this.state].handleKeyDown(e, fighter);\n  } else {\n    this.states[this.state].handleKeyUp(e, fighter);\n  }\n\n  e.keyCode = 32;\n  if(flag & this._BUTTON_SPACE) {\n    this.states[this.state].handleKeyDown(e, fighter);\n  } else {\n    this.states[this.state].handleKeyUp(e, fighter);\n  }\n\n  e.keyCode = 37;\n  if(flag & this._BUTTON_LEFT) {\n    this.states[this.state].handleKeyDown(e, fighter);\n  } else {\n    this.states[this.state].handleKeyUp(e, fighter);\n  }\n\n  e.keyCode = 38;\n  if(flag & this._BUTTON_UP) {\n    this.states[this.state].handleKeyDown(e, fighter);\n  } else {\n    this.states[this.state].handleKeyUp(e, fighter);\n  }\n\n  e.keyCode = 39;\n  if(flag & this._BUTTON_RIGHT) {\n    this.states[this.state].handleKeyDown(e, fighter);\n  } else {\n    this.states[this.state].handleKeyUp(e, fighter);\n  }\n\n  e.keyCode = 40;\n  if(flag & this._BUTTON_DOWN) {\n    this.states[this.state].handleKeyDown(e, fighter);\n  } else {\n    this.states[this.state].handleKeyUp(e, fighter);\n  }\n\n  e.keyCode = 88;\n  if(flag & this._BUTTON_X) {\n    this.states[this.state].handleKeyDown(e, fighter);\n  } else {\n    this.states[this.state].handleKeyUp(e, fighter);\n  }\n\n  e.keyCode = 90;\n  if(flag & this._BUTTON_Z) {\n    this.states[this.state].handleKeyDown(e, fighter);\n  } else {\n    this.states[this.state].handleKeyUp(e, fighter);\n  }\n\n};\n\n\nStageState.prototype._SYNC_CONTAINER = {m: null, a: null};\nStageState.prototype._sync = function() {\n  var c = this._SYNC_CONTAINER;\n  c.m = this.keyFlagHistories.min;\n  c.a = this.keyFlagHistories.getValues();\n  this.game.sync(c);\n  this._runNextStepIfPossible();\n};\n\n\nStageState.prototype.receiveFromPeer = function(data) {\n  this.keyFlags2.insertValues(data.m, data.a);\n  if(this.waitingForOther)\n    this._runNextStepIfPossible();\n};\n\n\nStageState.prototype._runNextStepIfPossible = function() {\n  if(this.keyFlags2.hasValueOfCount(this.syncCount)) {\n    this.waitingForOther = false;\n    this.game.runNextStep();\n  } else {\n    this.waitingForOther = true;\n  }\n};\n\n\nStageState.prototype.doLookAtFromViewpointTarget = function() {\n  return this.viewFromFighter;\n};\n\n\nStageState.prototype.getViewpointTarget = function() {\n  return this.fighter;\n};\n\n\n\n/**\n * TODO: optimize and rename\n */\nfunction KeyFlagQueue() {\n  this.min = 0;\n  this.max = -1;\n  this.values = [];\n}\n\nKeyFlagQueue.prototype._NONE = -1;\n\n\nKeyFlagQueue.prototype.free = function() {\n  this.min = 0;\n  this.max = -1;\n  this.values.length = 0;\n};\n\n\nKeyFlagQueue.prototype.getLength = function() {\n  return this.values.length;\n};\n\n\nKeyFlagQueue.prototype.get = function(index) {\n  return this.values[index];\n};\n\n\nKeyFlagQueue.prototype.set = function(index, flag) {\n  if(index < this.values.length)\n    this.values[index] = flag;\n};\n\n\nKeyFlagQueue.prototype.push = function(value) {\n  this.values[this.values.length] = value;\n  this.max++;\n};\n\n\nKeyFlagQueue.prototype.shift = function() {\n  var value = this.values[0];\n  for(var i = 0; i < this.values.length-1; i++) {\n    this.values[i] = this.values[i+1];\n  }\n  this.values.length--;\n  this.min++;\n  return value;\n};\n\n\nKeyFlagQueue.prototype.hasValueOfCount = function(count) {\n  while(true) {\n    if(this.getLength() == 0)\n      return false;\n    if(this.min == count)\n      return (this.values[0] != this._NONE) ? true : false;\n    if(this.min > count)\n      return false;\n    this.shift();\n  }\n};\n\n\n/**\n * TODO: optimize and check the logic\n */\nKeyFlagQueue.prototype.insertValues = function(min, values) {\n  for(var i = this.getLength(); this.max < min - 1; i++) {\n    this.values[i] = this._NONE;\n    this.max++;\n  }\n\n  var n = this.min - min >= 0 ? this.min - min : 0;\n  for(var i = n, len = values.length; i < len; i++) {\n    this.values[min - this.min + i] = values[i];\n    if(min + i > this.max)\n      this.max++;\n  }\n};\n\n\nKeyFlagQueue.prototype.shiftUntilLengthIs = function(count) {\n  while(this.getLength() > count) {\n    this.shift();\n  }\n};\n\n\nKeyFlagQueue.prototype.getValues = function() {\n  return this.values;\n};\n\n\n\nfunction StageAbstractState( stage ) {\n  this.stage = stage ;\n}\n\n\nStageAbstractState.prototype.runStep = function( ) {\n\n} ;\n\n\nStageAbstractState.prototype.handleKeyDown = function( e ) {\n} ;\n\n\nStageAbstractState.prototype.handleKeyUp = function( e ) {\n} ;\n\n\nStageAbstractState.prototype.updateDisplay = function( surface ) {\n} ;\n\n\nStageAbstractState.prototype._soundEffect = function( key ) {\n  this.stage._soundEffect( key ) ;\n} ;\n\n\nStageAbstractState.prototype.getImage = function( key ) {\n  return this.stage.getImage( key ) ;\n} ;\n\n\nStageAbstractState.prototype.resetButton = function(flag) {\n  return 0;\n};\n\n\n/**\n * @param record Array\n */\nStageAbstractState.prototype._putKeyOnRecord = function( record ) {\n  if( record.length > 0 )\n    this.stage.putKeyOnRecord( record ) ;\n} ;\n\n\n/**\n * @param record Array\n */\nStageAbstractState.prototype._putKeyOffRecord = function( record ) {\n  if( record.length > 0 )\n    this.stage.putKeyOffRecord( record ) ;\n} ;\n\n\n\nfunction ShootingState(stage) {\n  this.parent = StageAbstractState;\n  this.parent.call(this, stage);\n}\n__inherit(ShootingState, StageAbstractState);\n\n\n\nShootingState.prototype.handleKeyDown = function(e, fighter) {\n  var p = [];\n  switch(e.keyCode) {\n    case 16: // shift\n      if(fighter.setFlag(fighter._FLAG_SLOW))\n        p.push('s');\n      break;\n    case 32: // space\n      fighter.changeCharacter();\n      p.push('sp');\n      break;\n    case 37: // left\n      if(fighter.setFlag(fighter._FLAG_MOVE_LEFT))\n        p.push('l') ;\n      break;\n    case 38: // up\n      if(fighter.setFlag(fighter._FLAG_MOVE_UP))\n        p.push('u');\n      break;\n    case 39: // right\n      if(fighter.setFlag(fighter._FLAG_MOVE_RIGHT))\n        p.push('r');\n      break;\n    case 40: // down\n      if(fighter.setFlag(fighter._FLAG_MOVE_DOWN))\n        p.push('d');\n      break;\n    // TODO: temporal\n    case 88: // x\n      this.stage.notifyFighterDoBomb(fighter);\n      p.push('x');\n      break;\n    case 90: // z\n      if(fighter.setFlag(fighter._FLAG_SHOT))\n        p.push('z');\n      break;\n  };\n  this._putKeyOnRecord(p);\n};\n\n\nShootingState.prototype.handleKeyUp = function(e, fighter) {\n  var p = [];\n  switch(e.keyCode) {\n    case 16: // shift\n      if(fighter.clearFlag(fighter._FLAG_SLOW))\n        p.push('s');\n      break;\n    case 37: // left\n      if(fighter.clearFlag(fighter._FLAG_MOVE_LEFT))\n        p.push('l');\n      break;\n    case 38: // up\n      if(fighter.clearFlag(fighter._FLAG_MOVE_UP))\n        p.push('u');\n      break;\n    case 39: // right\n      if(fighter.clearFlag(fighter._FLAG_MOVE_RIGHT))\n        p.push('r');\n      break;\n    case 40: // down\n      if(fighter.clearFlag(fighter._FLAG_MOVE_DOWN))\n        p.push('d');\n      break;\n    case 90: // z\n      if(fighter.clearFlag(fighter._FLAG_SHOT))\n        p.push('z');\n      break;\n  } ;\n  this._putKeyOffRecord(p);\n};\n\n\nShootingState.prototype.updateDisplay = function( surface ) {\n} ;\n\n\nShootingState.prototype.resetButton = function(flag) {\n  flag &= ~this.stage._BUTTON_SPACE;\n  flag &= ~this.stage._BUTTON_X;\n  return flag;\n};\n\n\n\nfunction TalkState( stage ) {\n  this.parent = StageAbstractState ;\n  this.parent.call( this, stage ) ;\n  this.stageIndex = 0 ;\n  this.sceneIndex = 0 ;\n  this.index = 0 ;\n  this.params = __talkParams ;\n}\n__inherit( TalkState, StageAbstractState ) ;\n\n\nTalkState.prototype.reset = function( ) {\n  this.stageIndex = 0 ;\n  this.sceneIndex = 0 ;\n  this.index = 0 ;\n} ;\n\n\nTalkState.prototype.handleKeyDown = function( e ) {\n  var p = [ ] ;\n  switch( e.keyCode ) {\n    case 32: // space\n      p.push( 'sp' ) ;\n      this.stage.fighter.changeCharacter( ) ;\n      break ;\n    case 90: // z\n      p.push( 'z' ) ;\n      this.index++ ;\n      // TODO: temporal\n      if( this.index >= this.params[ this.stageIndex ][ this.sceneIndex ][ this.stage.fighter.characterIndex ].length ) {\n        this.sceneIndex++ ;\n        this.index = 0 ;\n        if( this.sceneIndex >= this.params[ this.stageIndex ].length ) {\n          this.stage.notifyStageClear( ) ;\n          this.stageIndex++ ;\n          this.sceneIndex = 0 ;\n        } else {\n          this.stage.notifyBossBecameActive( this.stage.bossManager.getBoss( ) ) ;\n        }\n      }\n      break ;\n  } ;\n  this._putKeyOnRecord( p ) ;\n} ;\n\n\nTalkState.prototype.handleKeyUp = function( e ) {\n} ;\n\n\nTalkState.prototype.updateDisplay = function( surface ) {\n  this._displayStandUp( surface, this.params[ this.stageIndex ][ this.sceneIndex ][ this.stage.fighter.characterIndex ][ this.index ].left,  120,  0 ) ;\n  this._displayStandUp( surface, this.params[ this.stageIndex ][ this.sceneIndex ][ this.stage.fighter.characterIndex ][ this.index ].right, 360,  0 ) ;\n  this._displaySerifWindow( surface ) ;\n  this._displaySerif( surface ) ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nTalkState.prototype._displayStandUp = function( surface, params, w, dw ) {\n  if( ! params )\n    return ;\n\n  surface.save( ) ;\n  if( params.active ) {\n    surface.globalAlpha = 1.0 ;\n    w += dw ;\n  } else {\n    surface.globalAlpha = 0.5 ;\n  }\n  var p = this._getStandUp( params.character ) ;\n  surface.drawImage( p.image,\n                     w - p.width * 0.75 / 2,\n                     50,\n                     p.width  * 0.75,\n                     p.height * 0.75 ) ;\n  surface.restore( ) ;\n} ;\n\n\nTalkState.prototype._getStandUp = function( key ) {\n  var image ;\n  var width ;\n  var height ;\n  switch( key ) {\n    case 'reimu':\n      image = this.stage.getImage( Game._IMG_STAND_REIMU ) ;\n      width = 400 ;\n      height = 600 ;\n      break ;\n    case 'marisa':\n      image = this.stage.getImage( Game._IMG_STAND_MARISA ) ;\n      width = 400 ;\n      height = 600 ;\n      break ;\n    case 'mokou':\n      image = this.stage.getImage( Game._IMG_STAND_MOKOU ) ;\n      width = 512 ;\n      height = 600 ;\n      break ;\n    case 'rumia':\n      image = this.stage.getImage( Game._IMG_STAND_RUMIA ) ;\n      width = 600 ;\n      height = 600 ;\n      break ;\n    case 'chilno':\n      image = this.stage.getImage( Game._IMG_STAND_CHILNO ) ;\n      width = 550 ;\n      height = 600 ;\n      break ;\n    default:\n      // TODO: throw exception?\n      break ;\n  }\n  return { 'image': image, 'width': width, 'height': height } ;\n} ;\n\n\nTalkState.prototype._displaySerifWindow = function( surface ) {\n  surface.save( ) ;\n  surface.fillStyle = 'rgb( 50, 50, 50 )' ;\n  surface.globalAlpha = 0.7 ;\n  surface.fillRect( 50, 350, 380, 100 ) ;\n  surface.restore( ) ;\n} ;\n\n\nTalkState.prototype._displaySerif = function( surface ) {\n  surface.save( ) ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.textAlign = 'left' ;\n  surface.font = '16px Arial' ;\n  var array = this.params[ this.stageIndex ][ this.sceneIndex ][ this.stage.fighter.characterIndex ][ this.index ].serif.split( '\\n' ) ;\n  for( var i = 0; i < array.length; i++ ) {\n    surface.fillText( array[ i ], 60, 380 + i * 20) ;\n  }\n  surface.restore( ) ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nfunction ClearState( stage ) {\n  this.parent = StageAbstractState ;\n  this.parent.call( this, stage ) ;\n  this.count = 0 ;\n}\n__inherit( ClearState, StageAbstractState ) ;\n\nClearState._MOVE_SPEED = 20 ;\n\n\n/**\n * TODO: temporal\n */\nClearState.prototype.init = function( ) {\n  this.count = 0 ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nClearState.prototype.runStep = function( ) {\n  this.count++ ;\n} ;\n\n\nClearState.prototype.handleKeyDown = function( e ) {\n  var p = [ ] ;\n  switch( e.keyCode ) {\n    case 32: // space\n      p.push( 'sp' ) ;\n      this.stage.fighter.changeCharacter( ) ;\n      break ;\n    case 90: // z\n      p.push( 'z' ) ;\n      // TODO: temporal\n      if( this.count < this.stage.getHeight( ) / ClearState._MOVE_SPEED )\n        return ;\n      this._toNextStage(  )\n      break ;\n  } ;\n  this._putKeyOnRecord( p ) ;\n} ;\n\n\nClearState.prototype.handleKeyUp = function( e ) {\n} ;\n\n\nClearState.prototype.updateDisplay = function( surface ) {\n\n  var base = this.stage.getHeight( ) - this.count * ClearState._MOVE_SPEED ;;\n  if( base < 0 )\n    base = 0 ;\n\n  surface.save( ) ;\n  var pattern = surface.createPattern( this.getImage( Game._IMG_SCORE_BACK ), '' ) ;\n  surface.fillStyle = pattern ;\n  surface.fillRect( 0, base, this.stage.getWidth( ), this.stage.getHeight( ) ) ;\n\n  surface.fillStyle = 'rgb( 30, 30, 30 )' ;\n  surface.globalAlpha = 0.8 ;\n  surface.fillRect( 50, base + 50, 380, 380 ) ;\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.textAlign = 'left' ;\n  surface.font = '16px Arial' ;\n  surface.fillText( 'Stage' + ( this.stage.stageIndex + 1 ) + ' Clear',\n                    100, base + 100 ) ;\n  surface.restore( ) ;\n\n} ;\n\n\n/**\n * TODO: temporal\n */\nClearState.prototype._toNextStage = function( ) {\n  this.stage.stageIndex++ ;\n  if( this.stage.stageIndex >= __enemiesParams.length ) {\n    this.stage.notifyGameClear( ) ;\n  } else {\n    this.stage.notifyGoNextStage( ) ;\n  }\n} ;\n\n\n/**\n * TODO: temporal\n */\nfunction GameOverState( stage ) {\n  this.parent = StageAbstractState ;\n  this.parent.call( this, stage ) ;\n  this.index = 0 ;\n}\n__inherit( GameOverState, StageAbstractState ) ;\n\n\nGameOverState.prototype.init = function( ) {\n  this.index = 0 ;\n} ;\n\n\n/**\n * TODO: temporal\n */\nGameOverState.prototype.runStep = function( ) {\n} ;\n\n\nGameOverState.prototype.handleKeyDown = function( e ) {\n  switch( e.keyCode ) {\n    case 38: // up\n    case 40: // down\n      this._soundEffect( Game._SE_SELECT ) ;\n      this.index = ( this.index == 0 ) ? 1 : 0 ;\n      break ;\n    case 90: // z\n      this._soundEffect( Game._SE_SELECT ) ;\n      if( this.index == 0 )\n        this.stage.notifyContinue( ) ;\n      else\n        this.stage.notifyQuit( ) ;\n      break ;\n  } ;\n} ;\n\n\nGameOverState.prototype.handleKeyUp = function( e ) {\n} ;\n\n\nGameOverState.prototype.updateDisplay = function( surface ) {\n  surface.save( ) ;\n\n  surface.fillStyle = 'rgb( 0, 0, 0 )' ;\n  surface.globalAlpha = 0.5 ;\n  surface.fillRect( 0, 170, 480, 100 ) ;\n\n  surface.fillStyle = 'rgb( 255, 255, 255 )' ;\n  surface.textAlign = 'center' ;\n  surface.textBaseAlign = 'middle' ;\n  surface.font = '16px Arial' ;\n  if( this.index == 0 ) {\n    surface.globalAlpha = 1.0 ;\n  } else {\n    surface.globalAlpha = 0.2 ;\n  }\n  surface.fillText( 'Continue', 240, 200 ) ;\n  if( this.index == 0 ) {\n    surface.globalAlpha = 0.2 ;\n  } else {\n    surface.globalAlpha = 1.0 ;\n  }\n  surface.fillText( 'Quit',     240, 240 ) ;\n  surface.restore( ) ;\n} ;\n\n\n"
  },
  {
    "path": "utility/Draw.js",
    "content": "/**\n *\n */\nfunction __drawComplexRect( surface, image, p, width, height,\n                            ax, ay, awidth, aheight ) {\n\n  if( ! width )\n    width = image.width ;\n  if( ! height )\n    height = image.height ;\n  if( ! ax )\n    ax = 0 ;\n  if( ! ay )\n    ay = 0 ;\n  if( ! awidth )\n    awidth = width ;\n  if( ! aheight )\n    aheight = height ;\n\n  surface.save( ) ;\n  surface.beginPath( ) ;\n  surface.moveTo( p[0].x, p[0].y ) ;\n  surface.lineTo( p[1].x, p[1].y ) ;\n  surface.lineTo( p[3].x, p[3].y ) ;\n  surface.lineTo( p[2].x, p[2].y ) ;\n  surface.closePath( ) ;\n  surface.clip( ) ;\n\n  var t1 = ( p[1].x - p[0].x ) / width ;\n  var t2 = ( p[1].y - p[0].y ) / width ;\n  var t3 = ( p[2].x - p[0].x ) / height ;\n  var t4 = ( p[2].y - p[0].y ) / height ;\n  var t5 = p[0].x ;\n  var t6 = p[0].y ;\n\t\t\n  surface.setTransform( t1, t2, t3, t4, t5, t6 ) \n  surface.drawImage( image, ax, ay, awidth, aheight, 0, 0, width, height ) ;\n  surface.restore( ) ;\n\n  surface.save( ) ;\n  surface.beginPath( ) ;\n  surface.moveTo( p[1].x, p[1].y ) ;\n  surface.lineTo( p[2].x, p[2].y ) ;\n  surface.lineTo( p[3].x, p[3].y ) ;\n  surface.closePath( ) ;\n  surface.clip( ) ;\n\n  var t1 = ( p[3].x - p[2].x ) / width ;\n  var t2 = ( p[3].y - p[2].y ) / width ;\n  var t3 = ( p[3].x - p[1].x ) / height ;\n  var t4 = ( p[3].y - p[1].y ) / height ;\n  var t5 = p[2].x ;\n  var t6 = p[2].y ;\n\t\t\n  surface.setTransform( t1, t2, t3, t4, t5, t6 ) \n  surface.drawImage( image, ax, ay, awidth, aheight, 0, 0, width, -height ) ;\n  surface.restore( ) ;\n}\n\n\nfunction __toBase64Pdf( image ) {\n  var canvas = document.createElement( 'canvas' ) ;\n  var context = canvas.getContext( '2d' ) ;\n  context.drawImage( image, 0, 0 ) ;\n  return canvas.toDataURL( 'image/png' ) ;\n}\n"
  },
  {
    "path": "utility/FreeList.js",
    "content": "/**\n * This class manages object resources to reduce GC.\n */\nfunction FreeList( num ) {\n  this.num = num ;\n  this.head = null ;\n  this.tail = null ;\n  this.list = [ ] ;\n  this._init( ) ;\n}\n\n\nFreeList.prototype._init = function( ) {\n  // Just in case.\n  if( this.num <= 0 )\n    return ;\n  for( var i = 0; i < this.num; i++ ) {\n    var element = this._generateElement( ) ;\n    element.listId = i ;\n    this.list.push( { 'element': element, 'listForw': null, 'available': true } ) ;\n    if( i > 0 )\n      this.list[ i - 1 ].listForw = this.list[ i ] ;\n  }\n  this.head = this.list[ 0 ] ;\n  this.tail = this.list[ this.num - 1 ] ;\n} ;\n\n\n/**\n * Child class must override this method.\n */\nFreeList.prototype._generateElement = function( ) {\n  return { } ;\n} ;\n\n\n/**\n * TODO: must implement the object shortage handler.\n * TODO: verify the functionality.\n */\nFreeList.prototype.get = function( ) {\n  if( this.head == null ) {\n    window.alert( 'ran out of object resources.' ) ;\n    console.log(this);\n    throw new Error( 'ran out of object resources.' ) ;\n  }\n  var head = this.head ;\n  this.head = head.listForw ;\n  head.available = false ;\n  head.listForw = null ;\n  if( this.head == null )\n    this.tail = null ;\n  return head.element ;\n} ;\n\n\nFreeList.prototype.free = function( element ) {\n  this.list[ element.listId ].available = true ;\n  if( this.tail != null )\n    this.tail.listForw = this.list[ element.listId ] ;\n  this.tail = this.list[ element.listId ] ;\n  if( this.head == null )\n    this.head = this.tail ;\n} ;\n\n"
  },
  {
    "path": "utility/Inherit.js",
    "content": "/**\n *\n */\nfunction __inherit( child, parent ) {\n  var getPrototype = function( p ) {\n    if( Object.create ) {\n      return Object.create( p ) ;\n    }\n    function f( ) { } ;\n    f.prototype = p ;\n    return new f( ) ;\n  } ;\n  child.prototype = getPrototype( parent.prototype ) ;\n  child.prototype.constructor = child ;\n}\n\n\nfunction __copyParentMethod(child, parent, methodName) {\n  var parentName = parent.name;\n  var name = parentName + '_' + \n               ((methodName[0] == '_') ? methodName.slice(1) : methodName);\n  child.prototype[name] = parent.prototype[methodName];\n}\n"
  },
  {
    "path": "utility/Peer.js",
    "content": "/**\n * TODO: optimize\n */\nfunction Peer(room, wsURL, receiver) {\n  this.room = room;\n  this.peopleInTheRoom = 0;\n  this.ws = new WebSocket(wsURL);\n  this.receiver = receiver;\n\n  this.pc = null;\n  this.channel = null;\n\n  var self = this;\n  this.gotSDPFunc = function(sdp) {self._gotSDP(sdp);};\n  this.onIceCandidateFunc = function(event) {self._onIceCandidate(event);};\n  this.onDataChannelFunc = function(event) {self._onDataChannel(event);};\n  this.onMessageFunc = function(event) {self._onMessage(event);};\n  this.onOpenFunc = function(event) {self._onOpen(event);};\n  this.onCloseFunc = function(event) {self._onClose(event);};\n  this.onErrorFunc = function(event) {self._onError(event);};\n  this.dummySendFunc = function() { self._keepSendDummy(); };\n\n  this.ws.onmessage = function(event) {self._gotSignal(event);};\n  this.ws.onopen = function(event) {self._wsReady(event);};\n\n  this.interval = null;\n  this.peerConnected = false;\n}\n\n// must be same as the server side ones.\nPeer.prototype._PEER_ID_DUMMY       = -1;\nPeer.prototype._PEER_ID_NOTICE_ROOM = 0;\nPeer.prototype._PEER_ID_SYNC        = 1;\n\nPeer.prototype._ICE_SERVERS = [\n{url:'stun:stun01.sipphone.com'},\n{url:'stun:stun.ekiga.net'},\n{url:'stun:stun.fwdnet.net'},\n{url:'stun:stun.ideasip.com'},\n{url:'stun:stun.iptel.org'},\n{url:'stun:stun.rixtelecom.se'},\n{url:'stun:stun.schlund.de'},\n{url:'stun:stun.l.google.com:19302'},\n{url:'stun:stun1.l.google.com:19302'},\n{url:'stun:stun2.l.google.com:19302'},\n{url:'stun:stun3.l.google.com:19302'},\n{url:'stun:stun4.l.google.com:19302'},\n{url:'stun:stunserver.org'},\n{url:'stun:stun.softjoys.com'},\n{url:'stun:stun.voiparound.com'},\n{url:'stun:stun.voipbuster.com'},\n{url:'stun:stun.voipstunt.com'},\n{url:'stun:stun.voxgratia.org'},\n{url:'stun:stun.xten.com'},\n{\n\turl: 'turn:numb.viagenie.ca',\n\tcredential: 'muazkh',\n\tusername: 'webrtc@live.com'\n},\n{\n\turl: 'turn:192.158.29.39:3478?transport=udp',\n\tcredential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',\n\tusername: '28224511:1379330808'\n},\n{\n\turl: 'turn:192.158.29.39:3478?transport=tcp',\n\tcredential: 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',\n\tusername: '28224511:1379330808'\n}\n];\n\nPeer.prototype._DUMMY_SPAN = 1000 * 20;\nPeer.prototype._DUMMY_DATA = JSON.stringify({_pid: Peer.prototype._PEER_ID_DUMMY});\n\n\nPeer.prototype.log = function(data) {\n//  console.log(data);\n};\n\n\nPeer.prototype._wsReady = function(event) {\n  if(this.receiver.notifyWsReady !== void 0)\n    this.receiver.notifyWsReady(event);\n  this._noticeRoom();\n  this._keepSendDummy();\n};\n\n\nPeer.prototype._noticeRoom = function() {\n  var str = JSON.stringify({_pid: this._PEER_ID_NOTICE_ROOM, room: this.room});\n  this.ws.send(str);\n};\n\n\nPeer.prototype.sendSignal = function(params) {\n  var str = JSON.stringify(params);\n  this.ws.send(str);\n  this.log(str);\n};\n\n\nPeer.prototype._gotSignal = function(event) {\n  var params = JSON.parse(event.data);\n\n  if(params._pid === void 0) {\n    switch(params.type) {\n      case 'offer':\n        this._gotOffer(params);\n        break;\n      case 'answer':\n        this._gotAnswer(params);\n        break;\n      case 'candidate':\n        this._gotCandidate(params);\n        break;\n    }\n  } else {\n    if(params._pid == Peer.prototype._PEER_ID_NOTICE_ROOM) {\n      this.peopleInTheRoom = params.num;\n      if(this.receiver.notifyRoomUpdate !== void 0)\n        this.receiver.notifyRoomUpdate(this.peopleInTheRoom);\n    }\n  }\n  this.log(params);\n};\n\n\nPeer.prototype.createPeerConnection = function() {\n  var servers = {'iceServers': this._ICE_SERVERS};\n\n  this.pc = new webkitRTCPeerConnection(servers);\n  this.pc.onicecandidate = this.onIceCandidateFunc;\n};\n\n\nPeer.prototype._onIceCandidate = function(event) {\n  if(event.candidate) {\n    var params = {type: 'candidate',\n                  sdpMLineIndex: event.candidate.sdpMLineIndex,\n                  candidate: event.candidate.candidate};\n    this.sendSignal(params);\n  }\n};\n\n\nPeer.prototype.offer = function() {\n  this.channel = this.pc.createDataChannel('mychannel',\n                                           {reliable: false});\n  this.channel.onmessage = this.onMessageFunc;\n  this.channel.onopen = this.onOpenFunc;\n  this.channel.onclose = this.onCloseFunc;\n  // TODO: temporal\n  this.channel.onerror = function(e) {\n    window.alert(e);\n    console.log(e);\n  };\n  this.pc.createOffer(this.gotSDPFunc, this.onErrorFunc);\n};\n\n\nPeer.prototype._gotSDP = function(sdp) {\n  this.pc.setLocalDescription(sdp);\n  this.sendSignal(sdp);\n};\n\n\nPeer.prototype._gotOffer = function(msg) {\n  this.pc.ondatachannel = this.onDataChannelFunc;\n  this._setRemoteDescription(msg);\n  this.pc.createAnswer(this.gotSDPFunc, this.onErrorFunc);\n};\n\n\nPeer.prototype._gotAnswer = function(msg) {\n  this._setRemoteDescription(msg);\n};\n\n\nPeer.prototype._gotCandidate = function(msg) {\n  var candidate = new RTCIceCandidate(msg);\n  this.pc.addIceCandidate(candidate);\n};\n\n\nPeer.prototype._setRemoteDescription = function(msg) {\n  this.pc.setRemoteDescription(new RTCSessionDescription(msg));\n};\n\n\nPeer.prototype._onDataChannel = function(event) {\n  this.channel = event.channel;\n  this.channel.onmessage = this.onMessageFunc;\n  this.channel.onopen = this.onOpenFunc;\n  this.channel.onclose = this.onCloseFunc;\n};\n\n\nPeer.prototype._onOpen = function(event) {\n  this.peerConnected = true;\n  this.ws.close(1000); // TODO: consider more\n  if(this.receiver.notifyOpenPeer !== void 0)\n    this.receiver.notifyOpenPeer(event);\n};\n\n\nPeer.prototype._onClose = function(event) {\n  this.peerConnected = false;\n  if(this.receiver.notifyClosePeer !== void 0)\n    this.receiver.notifyClosePeer(event);\n};\n\n\nPeer.prototype._onError = function(event) {\n  window.alert(event);\n};\n\n\nPeer.prototype._onMessage = function(event) {\n  this.log(event.data);\n  this.receiver.receiveFromPeer(JSON.parse(event.data));\n};\n\n\nPeer.prototype.send = function(data) {\n  this.channel.send(JSON.stringify(data));\n};\n\n\nPeer.prototype._keepSendDummy = function() {\n  this.ws.send(this._DUMMY_DATA);\n  this._setIntervalForDummy();\n};\n\n\nPeer.prototype._setIntervalForDummy = function() {\n  if(! this.ws || this.peerConnected)\n    return;\n  this.interval = setTimeout(this.dummySendFunc, this._DUMMY_SPAN);\n};\n"
  },
  {
    "path": "utility/Random.js",
    "content": "function Randomizer() {\n};\n\nRandomizer.prototype._xors = {\n  x: 123456789,\n  y: 362436069,\n  z: 521288629,\n  w: 88675123\n};\n\nRandomizer.prototype._effective = 0x7fffffff ;\n\n\nRandomizer.prototype.seed = function(seed) {\n  this._xors.x = 123456789;\n  this._xors.y = 362436069;\n  this._xors.z = 521288629;\n  this._xors.w = seed;\n};\n\n\nRandomizer.prototype.random = function() {\n  var xors = this._xors;\n  var effective = this._effective;\n\n  var t  = xors.x ^ (xors.x << 11);\n  xors.x = xors.y;\n  xors.y = xors.z;\n  xors.z = xors.w;\n  xors.w = (xors.w ^ (xors.w >> 19)) ^ (t ^ (t >> 8));\n  return (xors.w % effective) / effective;\n};\n\nvar __randomizer = new Randomizer();\n\n\n"
  },
  {
    "path": "utility/WebGL.js",
    "content": "function Layer(canvas) {\n  this.canvas = canvas;\n  this.gl = this._initGl(canvas);\n  this.gl.clearColor(0.0, 0.0, 0.0, 1.0);\n  this.shader = this._initShader(this.gl);\n  this.mvMatrix = mat4.create();\n  this.pMatrix = mat4.create();\n\n  // These are for one texture drawing.\n  // TODO: remove magic numbers.\n  this.vArray = this.createFloatArray(12);\n  this.cArray = this.createFloatArray(8);\n  this.iArray = this.createUintArray(6);\n  this.aArray = this.createFloatArray(16);\n  this.vBuffer = this.gl.createBuffer();\n  this.cBuffer = this.gl.createBuffer();\n  this.iBuffer = this.gl.createBuffer();\n  this.aBuffer = this.gl.createBuffer();\n};\n\nLayer.prototype.mat4 = mat4; // only for reference.\n\nLayer.prototype._NAMES = ['webgl', 'experimental-webgl'];\n\nLayer.prototype._BLEND_ALPHA     = 0;\nLayer.prototype._BLEND_ALPHA2    = 1;\nLayer.prototype._BLEND_ADD_ALPHA = 2;\n\nLayer.prototype._SHADERS = {};\n\nLayer.prototype._SHADERS['shader-vs'] = {};\nLayer.prototype._SHADERS['shader-vs'].type = 'x-shader/x-vertex';\nLayer.prototype._SHADERS['shader-vs'].src = '\\\n  attribute vec3 aVertexPosition;\\\n  attribute vec2 aTextureCoordinates;\\\n  attribute vec4 aColor;\\\n\\\n  uniform mat4 uMVMatrix;\\\n  uniform mat4 uPMatrix;\\\n\\\n  varying vec2 vTextureCoordinates;\\\n  varying vec4 vColor;\\\n  void main() {\\\n    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\\\n    vTextureCoordinates = aTextureCoordinates;\\\n    vColor = aColor;\\\n  }\\\n';\n\nLayer.prototype._SHADERS['shader-fs'] = {};\nLayer.prototype._SHADERS['shader-fs'].type = 'x-shader/x-fragment';\nLayer.prototype._SHADERS['shader-fs'].src = '\\\n  precision mediump float;\\\n  varying vec2 vTextureCoordinates;\\\n  uniform sampler2D uSampler;\\\n  varying vec4 vColor;\\\n  void main() {\\\n    vec4 textureColor = texture2D(uSampler, vTextureCoordinates);\\\n    gl_FragColor = textureColor * vColor;\\\n  }\\\n';\n\n\nLayer.prototype._initGl = function(canvas) {\n  var names = this._NAMES;\n  var context = null;\n  for(var i = 0; i < names.length; i++) {\n    try {\n      context = canvas.getContext(names[i]);\n    } catch(e) {\n      if(context)\n        break;\n    }\n  }\n  if(context) {\n    context.viewportWidth = canvas.width;\n    context.viewportHeight = canvas.height;\n  } else {\n    alert(\"Failed to create WebGL context!\");\n  }\n  return context;\n};\n\n\nLayer.prototype._compileShaderFromDOM = function(gl, id) {\n  var script = document.getElementById(id);\n\n  if(!script)\n    return null;\n\n  var source = '';\n  var currentChild = script.firstChild;\n  while(currentChild) {\n    if(currentChild.nodeType == 3) { // 3 corresponds to TEXT_NODE\n      source += currentChild.textContent;\n    }\n    currentChild = currentChild.nextSibling;\n  }\n\n  return this._compileShader(gl, source, script.type);\n};\n\n\nLayer.prototype._compileShader = function(gl, source, type) {\n  var shader;\n  if(type == 'x-shader/x-fragment') {\n    shader = gl.createShader(gl.FRAGMENT_SHADER);\n  } else if(type == 'x-shader/x-vertex') {\n    shader = gl.createShader(gl.VERTEX_SHADER);\n  } else {\n    return null;\n  }\n\n  gl.shaderSource(shader, source);\n  gl.compileShader(shader);\n\n  if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n    alert(gl.getShaderInfoLog(shader));\n    return null;\n  }\n  return shader;\n};\n\n\nLayer.prototype._initVertexShader = function(gl) {\n  var params = this._SHADERS['shader-vs'];\n  return this._compileShader(gl, params.src, params.type);\n};\n\n\nLayer.prototype._initFragmentShader = function(gl) {\n  var params = this._SHADERS['shader-fs'];\n  return this._compileShader(gl, params.src, params.type);\n};\n\n\nLayer.prototype._initShader = function(gl) {\n  var vertexShader = this._initVertexShader(gl);\n  var fragmentShader = this._initFragmentShader(gl);\n\n  var shader = gl.createProgram();\n  gl.attachShader(shader, vertexShader);\n  gl.attachShader(shader, fragmentShader);\n  gl.linkProgram(shader);\n\n  if(!gl.getProgramParameter(shader, gl.LINK_STATUS)) {\n    alert(\"Failed to setup shaders\");\n  }\n\n  gl.useProgram(shader);\n\n  shader.vertexPositionAttribute =\n    gl.getAttribLocation(shader, 'aVertexPosition');\n  gl.enableVertexAttribArray(shader.vertexPositionAttribute);\n\n  shader.textureCoordAttribute = \n    gl.getAttribLocation(shader, 'aTextureCoordinates');\n  gl.enableVertexAttribArray(shader.textureCoordAttribute);\n\n  shader.colorAttribute =\n    gl.getAttribLocation(shader, 'aColor');\n  gl.enableVertexAttribArray(shader.colorAttribute);\n\n  shader.pMatrixUniform =\n    gl.getUniformLocation(shader, 'uPMatrix');\n  shader.mvMatrixUniform =\n    gl.getUniformLocation(shader, 'uMVMatrix');\n\n  shader.uSamplerUniform =\n    gl.getUniformLocation(shader, 'uSampler');\n\n  return shader;\n}\n\n\nLayer.prototype.setMatrixUniforms = function(gl) {\n  gl.uniformMatrix4fv(this.shader.pMatrixUniform, false, this.pMatrix);\n  gl.uniformMatrix4fv(this.shader.mvMatrixUniform, false, this.mvMatrix);\n}\n\n\nLayer.prototype.viewport = function() {\n  this.gl.viewport(0, 0, this.gl.viewportWidth, this.gl.viewportHeight);\n};\n\n\nLayer.prototype.clear = function() {\n  this.gl.clear(this.gl.COLOR_BUFFER_BIT);\n};\n\n\nLayer.prototype.perspective = function(theta, near, far) {\n  this.mat4.perspective(theta, this.gl.viewportWidth / this.gl.viewportHeight,\n                   near, far, this.pMatrix);\n};\n\n\nLayer.prototype.ortho = function(near, far) {\n  this.mat4.ortho(0, this.gl.viewportWidth, -this.gl.viewportHeight, 0,\n             near, far, this.pMatrix);\n};\n\n\nLayer.prototype.lookAt = function(eye, center, up) {\n  this.mat4.lookAt(eye, center, up, this.mvMatrix);\n};\n\n\nLayer.prototype.identity = function() {\n  this.mat4.identity(this.mvMatrix);\n};\n\n\n/**\n * pre_multiplied argument is a last resort.\n */\nLayer.prototype.generateTexture = function(image) {\n  var gl = this.gl;\n  var texture = gl.createTexture();\n  gl.bindTexture(gl.TEXTURE_2D, texture);\n//  gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\n//  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);\n  gl.bindTexture(gl.TEXTURE_2D, null);\n  return texture;\n};\n\n\nLayer.prototype.draw = function(texture, vBuffer, cBuffer, iBuffer, aBuffer,\n                                blend) {\n  var gl = this.gl;\n  var shader = this.shader;\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);\n  gl.vertexAttribPointer(shader.vertexPositionAttribute,\n                         vBuffer.itemSize, gl.FLOAT, false, 0, 0);\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, aBuffer);\n  gl.vertexAttribPointer(shader.colorAttribute,\n                         aBuffer.itemSize, gl.FLOAT, false, 0, 0);\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);\n  gl.vertexAttribPointer(shader.textureCoordAttribute,\n                         cBuffer.itemSize, gl.FLOAT, false, 0, 0);\n\n  gl.activeTexture(gl.TEXTURE0);\n  gl.bindTexture(gl.TEXTURE_2D, texture);\n  gl.uniform1i(shader.uSamplerUniform, 0);\n\n  var param1;\n  var param2;\n  switch(blend) {\n    case this._BLEND_ALPHA2:\n      param1 = gl.ONE;\n      param2 = gl.ONE_MINUS_SRC_ALPHA;\n      break;\n    case this._BLEND_ADD_ALPHA:\n      param1 = gl.SRC_ALPHA;\n      param2 = gl.ONE;\n      break;\n//  case this._BLEND_ALPHA:\n//  case null:\n    default:\n      param1 = gl.SRC_ALPHA;\n      param2 = gl.ONE_MINUS_SRC_ALPHA;\n      break;\n  }\n  gl.blendFuncSeparate(param1, param2, gl.ONE, gl.ONE);\n\n//  gl.enable(gl.DEPTH_TEST);\n//  gl.depthFunc(gl.LEQUAL);\n  gl.disable(gl.DEPTH_TEST);\n  gl.enable(gl.BLEND);\n\n  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, iBuffer);\n  this.setMatrixUniforms(gl);\n  gl.drawElements(gl.TRIANGLES, iBuffer.numItems, gl.UNSIGNED_SHORT, 0);\n};\n\n\n/**\n * TODO: gl.bufferSubData and pratial update could improve\n *       CPU-GPU transfer performance.\n */\nLayer.prototype.pourArrayBuffer = function(buffer, array, itemSize, numItems) {\n  var gl = this.gl;\n  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n  gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);\n  buffer.itemSize = itemSize;\n  buffer.numItems = numItems;\n};\n\n\nLayer.prototype.pourElementArrayBuffer = function(buffer, array, itemSize,\n                                                  numItems) {\n  var gl = this.gl;\n  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);\n  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, array, gl.STATIC_DRAW);\n  buffer.itemSize = itemSize;\n  buffer.numItems = numItems;\n};\n\n\nLayer.prototype.createFloatArray = function(num) {\n  return new Float32Array(num);\n};\n\n\nLayer.prototype.createUintArray = function(num) {\n  return new Uint16Array(num);\n};\n\n\nLayer.prototype.createBuffer = function() {\n  return this.gl.createBuffer();\n};\n\n\n/**\n * This method is to easily draw one texture.\n * I wanna use image, not texture.\n * But cannot do that cuz of performance reason.\n */\nLayer.prototype.drawOneTexture = function(texture, x, y, z, w, h, d, a, blend) {\n  y = -y;\n\n  this.vArray[0]  = x-w/2;\n  this.vArray[1]  = y-h/2;\n  this.vArray[2]  = z;\n  this.vArray[3]  = x+w/2;\n  this.vArray[4]  = y-h/2;\n  this.vArray[5]  = z;\n  this.vArray[6]  = x+w/2;\n  this.vArray[7]  = y+h/2;\n  this.vArray[8]  = z;\n  this.vArray[9]  = x-w/2;\n  this.vArray[10] = y+h/2;\n  this.vArray[11] = z;\n  this.pourArrayBuffer(this.vBuffer, this.vArray, 3, 4);\n\n  this.cArray[0] = 0.0;\n  this.cArray[1] = 1.0;\n  this.cArray[2] = 1.0;\n  this.cArray[3] = 1.0;\n  this.cArray[4] = 1.0;\n  this.cArray[5] = 0.0;\n  this.cArray[6] = 0.0;\n  this.cArray[7] = 0.0;\n  this.pourArrayBuffer(this.cBuffer, this.cArray, 2, 4);\n\n  this.iArray[0] = 0;\n  this.iArray[1] = 1;\n  this.iArray[2] = 2;\n  this.iArray[3] = 0;\n  this.iArray[4] = 2;\n  this.iArray[5] = 3;\n  this.pourElementArrayBuffer(this.iBuffer, this.iArray, 1, 6);\n\n  this.aArray[0] = d;\n  this.aArray[1] = d;\n  this.aArray[2] = d;\n  this.aArray[3] = a;\n  this.aArray[4] = d;\n  this.aArray[5] = d;\n  this.aArray[6] = d;\n  this.aArray[7] = a;\n  this.aArray[8] = d;\n  this.aArray[9] = d;\n  this.aArray[10] = d;\n  this.aArray[11] = a;\n  this.aArray[12] = d;\n  this.aArray[13] = d;\n  this.aArray[14] = d;\n  this.aArray[15] = a;\n  this.pourArrayBuffer(this.aBuffer, this.aArray, 4, 4);\n\n  this.draw(texture, this.vBuffer, this.cBuffer, this.iBuffer, this.aBuffer,\n            blend);\n};\n\n\nLayer.prototype.calculateSquareValue = function(num) {\n  return Layer.calculateSquareValue(num);\n};\n\n\n/**\n * Static method.\n */\nLayer.calculateSquareValue = function(num) {\n  var val = 1;\n  while(num > val) {\n    val = val << 1;\n  }\n  return val;\n};\n"
  },
  {
    "path": "webgl_test.html",
    "content": "<!DOCTYPE HTML>\n<html lang=\"en\">\n<head>\n<title></title>\n<meta charset=\"utf-8\">\n<script type=\"text/javascript\" src=\"lib/glMatrix-0.9.5.min.js\"></script>\n<script type=\"text/javascript\" src=\"utility/Inherit.js\"></script>\n<script type=\"text/javascript\">\n\nvar mainLayer;\nvar bgLayer;\n\nvar fighter;\nvar fighterManager;\nvar fightersDrawer;\n\nvar bulletManager;\nvar bulletsDrawer;\n\nvar background;\nvar backgroundManager;\nvar backgroundsDrawer;\n\n\nvar smallNum = 100;\nvar middleNum = 50;\nvar largeNum = 10;\n\nvar bulletsNum = smallNum + middleNum + largeNum;\n\nvar r = 0;\nvar prevTime;\nvar fps = null;\nvar keys = {\n  'up': false,\n  'down': false,\n  'left': false,\n  'right': false,\n  'x': false,\n  'z': false\n};\n\n\nfunction Layer(canvas) {\n  this.canvas = canvas;\n  this.gl = this._initGl(canvas);\n  this.gl.clearColor(0.0, 0.0, 0.0, 1.0);\n  this.shader = this._initShader(this.gl);\n  this.mvMatrix = mat4.create();\n  this.pMatrix = mat4.create();\n  this.count = 0;\n};\n\nLayer.prototype._NAMES = ['webgl', 'experimental-webgl'];\n\nLayer.prototype._SHADERS = {};\n\nLayer.prototype._SHADERS['shader-vs'] = {};\nLayer.prototype._SHADERS['shader-vs'].type = 'x-shader/x-vertex';\nLayer.prototype._SHADERS['shader-vs'].src = '\\\n  attribute vec3 aVertexPosition;\\\n  attribute vec2 aTextureCoordinates;\\\n  attribute vec4 aColor;\\\n\\\n  uniform mat4 uMVMatrix;\\\n  uniform mat4 uPMatrix;\\\n\\\n  varying vec2 vTextureCoordinates;\\\n  varying vec4 vColor;\\\n\\\n  void main() {\\\n    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\\\n    vTextureCoordinates = aTextureCoordinates;\\\n    vColor = aColor;\\\n  }\\\n';\n\nLayer.prototype._SHADERS['shader-fs'] = {};\nLayer.prototype._SHADERS['shader-fs'].type = 'x-shader/x-fragment';\nLayer.prototype._SHADERS['shader-fs'].src = '\\\n  precision mediump float;\\\n  varying vec2 vTextureCoordinates;\\\n  uniform sampler2D uSampler;\\\n  varying vec4 vColor;\\\n  uniform float uFighterX;\\\n  uniform float uFighterY;\\\n  uniform int uTime;\\\n  uniform bool uLight;\\\n\\\n  vec2 getPosition(int unitAngle, int uTime, int i) {\\\n    float ax = abs(mod(float(uTime*2), 240.0) - 120.0);\\\n    float ay = abs(mod(float(uTime*3), 240.0) - 120.0);\\\n    float rad = radians(float(unitAngle * i + uTime*8));\\\n    float x = uFighterX + ax * cos(rad);\\\n    float y = uFighterY + ay * sin(rad);\\\n    return vec2(x, y);\\\n  }\\\n\\\n  const int num = 8;\\\n  const int unitAngle = 360 / num;\\\n  void main() {\\\n    vec4 textureColor = texture2D(uSampler, vTextureCoordinates);\\\n    if(uLight) {\\\n      float color = 0.0;\\\n      for(int i = 0; i < num; i++) {\\\n        vec2 pos = getPosition(unitAngle, uTime, i);\\\n        float dist = length(gl_FragCoord.xy - pos) * 1.5;\\\n        color += 5.0 / dist;\\\n      }\\\n      gl_FragColor = textureColor * vColor * vec4(vec3(color), 1.0);\\\n    } else {\\\n      gl_FragColor = textureColor * vColor;\\\n    }\\\n  }\\\n';\n\n\nLayer.prototype._initGl = function(canvas) {\n  var names = this._NAMES;\n  var context = null;\n  for(var i = 0; i < names.length; i++) {\n    try {\n      context = canvas.getContext(names[i]);\n    } catch(e) {\n      if(context)\n        break;\n    }\n  }\n  if(context) {\n    context.viewportWidth = canvas.width;\n    context.viewportHeight = canvas.height;\n  } else {\n    alert(\"Failed to create WebGL context!\");\n  }\n  return context;\n};\n\n\nLayer.prototype._compileShaderFromDOM = function(gl, id) {\n  var script = document.getElementById(id);\n\n  if(!script)\n    return null;\n\n  var source = '';\n  var currentChild = script.firstChild;\n  while(currentChild) {\n    if(currentChild.nodeType == 3) { // 3 corresponds to TEXT_NODE\n      source += currentChild.textContent;\n    }\n    currentChild = currentChild.nextSibling;\n  }\n\n  return this._compileShader(gl, source, script.type);\n};\n\n\nLayer.prototype._compileShader = function(gl, source, type) {\n  var shader;\n  if(type == 'x-shader/x-fragment') {\n    shader = gl.createShader(gl.FRAGMENT_SHADER);\n  } else if(type == 'x-shader/x-vertex') {\n    shader = gl.createShader(gl.VERTEX_SHADER);\n  } else {\n    return null;\n  }\n\n  gl.shaderSource(shader, source);\n  gl.compileShader(shader);\n\n  if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n    alert(gl.getShaderInfoLog(shader));\n    return null;\n  }\n  return shader;\n};\n\n\nLayer.prototype._initVertexShader = function(gl) {\n  var params = this._SHADERS['shader-vs'];\n  return this._compileShader(gl, params.src, params.type);\n};\n\n\nLayer.prototype._initFragmentShader = function(gl) {\n  var params = this._SHADERS['shader-fs'];\n  return this._compileShader(gl, params.src, params.type);\n};\n\n\nLayer.prototype._initShader = function(gl) {\n  var vertexShader = this._initVertexShader(gl);\n  var fragmentShader = this._initFragmentShader(gl);\n\n  var shader = gl.createProgram();\n  gl.attachShader(shader, vertexShader);\n  gl.attachShader(shader, fragmentShader);\n  gl.linkProgram(shader);\n\n  if(!gl.getProgramParameter(shader, gl.LINK_STATUS)) {\n    alert(\"Failed to setup shaders\");\n  }\n\n  gl.useProgram(shader);\n\n  shader.vertexPositionAttribute =\n    gl.getAttribLocation(shader, 'aVertexPosition');\n  gl.enableVertexAttribArray(shader.vertexPositionAttribute);\n\n  shader.textureCoordAttribute = \n    gl.getAttribLocation(shader, 'aTextureCoordinates');\n  gl.enableVertexAttribArray(shader.textureCoordAttribute);\n\n  shader.colorAttribute =\n    gl.getAttribLocation(shader, 'aColor');\n  gl.enableVertexAttribArray(shader.colorAttribute);\n\n  shader.pMatrixUniform =\n    gl.getUniformLocation(shader, 'uPMatrix');\n  shader.mvMatrixUniform =\n    gl.getUniformLocation(shader, 'uMVMatrix');\n\n  shader.uSamplerUniform =\n    gl.getUniformLocation(shader, 'uSampler');\n\n  shader.uTime = gl.getUniformLocation(shader, 'uTime');\n  shader.uLight = gl.getUniformLocation(shader, 'uLight');\n  shader.uFighterX = gl.getUniformLocation(shader, 'uFighterX');\n  shader.uFighterY = gl.getUniformLocation(shader, 'uFighterY');\n\n  return shader;\n}\n\n\nLayer.prototype.setMatrixUniforms = function(gl) {\n  gl.uniformMatrix4fv(this.shader.pMatrixUniform, false, this.pMatrix);\n  gl.uniformMatrix4fv(this.shader.mvMatrixUniform, false, this.mvMatrix);\n};\n\n\nLayer.prototype.setUniformTime = function() {\n  this.gl.uniform1i(this.shader.uTime, this.count);\n  this.count += 1;\n};\n\n\nLayer.prototype.setUniformFighterPosition = function(fighter) {\n  this.gl.uniform1f(this.shader.uFighterX, 240+fighter.x);\n  this.gl.uniform1f(this.shader.uFighterY, 240-fighter.y);\n};\n\n\nLayer.prototype.setUniformLight = function(flag) {\n  this.gl.uniform1i(this.shader.uLight, flag);\n};\n\n\nLayer.prototype.viewport = function() {\n  this.gl.viewport(0, 0, this.gl.viewportWidth, this.gl.viewportHeight);\n};\n\n\nLayer.prototype.clear = function() {\n  this.gl.clear(this.gl.COLOR_BUFFER_BIT);\n};\n\n\nLayer.prototype.perspective = function(theta, near, far) {\n  mat4.perspective(theta, this.gl.viewportWidth / this.gl.viewportHeight,\n                   near, far, this.pMatrix);\n};\n\n\nLayer.prototype.ortho = function(near, far) {\n  mat4.ortho(-this.gl.viewportWidth/2,\n              this.gl.viewportWidth/2,\n             -this.gl.viewportHeight/2,\n              this.gl.viewportHeight/2,\n              near, far, this.pMatrix);\n};\n\n\n\nfunction Element() {\n  this.x = 0;\n  this.y = 0;\n  this.z = 0;\n  this.w = 0;\n  this.h = 0;\n  this.theta = null;\n  this.xIndex = 0;\n  this.yIndex = 0;\n  this.count = 0;\n  this.view = null;\n  this.imageW = 256; // TODO: temporal\n  this.imageH = 256; // TODO: temporal\n};\n\nElement.prototype.Math = Math;\n\nElement.prototype.init = function() {\n  this._initView();\n};\n\n\nElement.prototype._initView = function() {\n  this.view = this._generateView();\n  this.view.init();\n};\n\n\nElement.prototype._generateView = function() {\n  return new ElementView(this);\n};\n\n\nElement.prototype.runStep = function() {\n  this.count++;\n};\n\n\nElement.prototype.getX = function() {\n  return this.x;\n};\n\n\nElement.prototype.getY = function() {\n  return this.y;\n};\n\n\nElement.prototype.getZ = function() {\n  return this.z;\n};\n\n\nElement.prototype.getWidth = function() {\n  return this.w;\n};\n\n\nElement.prototype.getHeight = function() {\n  return this.h;\n};\n\n\nElement.prototype.getTheta = function() {\n  return this.theta;\n};\n\n\nElement.prototype.getRadian = function() {\n  return this._theta2Radian(this.getTheta());\n};\n\n\nElement.prototype.getATheta = function() {\n  return 270-this.theta;\n};\n\n\nElement.prototype.getARadian = function() {\n  return this._theta2Radian(this.getATheta());\n};\n\n\nElement.prototype._theta2Radian = function(theta) {\n  return theta * this.Math.PI / 180;\n};\n\n\nElement.prototype._radian2Theta = function(radian) {\n  return radian * 180 / this.Math.PI;\n};\n\n\nElement.prototype.getView = function() {\n  return this.view;\n};\n\n\nElement.prototype.getImageXIndex = function() {\n  return this.xIndex;\n};\n\n\nElement.prototype.getImageYIndex = function() {\n  return this.yIndex;\n};\n\n\nElement.prototype.getImageWidth = function() {\n  return this.imageW;\n};\n\n\nElement.prototype.getImageHeight = function() {\n  return this.imageH;\n};\n\n\n\nfunction ElementManager() {\n  this.elements = [];\n  this.maxLength = 1000;\n};\n\n\nElementManager.prototype.clear = function() {\n  this.elements.length = 0;\n};\n\n\nElementManager.prototype.get = function(index) {\n  return this.elements[index];\n};\n\n\nElementManager.prototype.add = function(element) {\n  this.elements.push(element);\n};\n\n\nElementManager.prototype.getMaxLength = function() {\n  return this.maxLength;\n};\n\n\nElementManager.prototype.getLength = function() {\n  return this.elements.length;\n};\n\n\nElementManager.prototype.runStep = function() {\n  for(var i = 0; i < this.getLength(); i++)\n    this.get(i).runStep();\n};\n\n\n\nfunction ElementView(element) {\n  this.element = element;\n  this.a = 1.0;\n  this.vertices = [];\n  this.coordinates = [];\n  this.indices = [];\n  this.colors = [];\n  this.sVertices = [];\n  this.vertices.length = this._V_SIZE;\n  this.coordinates.length = this._C_SIZE;\n  this.indices.length = this._I_SIZE;\n  this.colors.length = this._A_SIZE;\n  this.sVertices.length = this._V_SIZE;\n};\n\nElementView.prototype.Math = Math;\n\nElementView.prototype._V_ITEM_SIZE = 3;\nElementView.prototype._V_ITEM_NUM = 4;\nElementView.prototype._V_SIZE = ElementView.prototype._V_ITEM_SIZE *\n                                  ElementView.prototype._V_ITEM_NUM;\n\nElementView.prototype._C_ITEM_SIZE = 2;\nElementView.prototype._C_ITEM_NUM = 4;\nElementView.prototype._C_SIZE = ElementView.prototype._C_ITEM_SIZE *\n                                  ElementView.prototype._C_ITEM_NUM;\n\nElementView.prototype._I_ITEM_SIZE = 1;\nElementView.prototype._I_ITEM_NUM = 6;\nElementView.prototype._I_SIZE = ElementView.prototype._I_ITEM_SIZE *\n                                  ElementView.prototype._I_ITEM_NUM;\n\nElementView.prototype._A_ITEM_SIZE = 4;\nElementView.prototype._A_ITEM_NUM = 4;\nElementView.prototype._A_SIZE = ElementView.prototype._A_ITEM_SIZE *\n                                  ElementView.prototype._A_ITEM_NUM;\n\n\nElementView.prototype.init = function() {\n  this._initVertices();\n  this._initCoordinates();\n  this._initIndices();\n  this._initColors();\n};\n\n\nElementView.prototype._initVertices = function() {\n  var w = this.element.getWidth()/2;\n  var h = this.element.getHeight()/2;\n\n  this.vertices[0]  = -w;\n  this.vertices[1]  = -h;\n  this.vertices[2]  = -1.0;\n  this.vertices[3]  =  w;\n  this.vertices[4]  = -h;\n  this.vertices[5]  = -1.0;\n  this.vertices[6]  =  w;\n  this.vertices[7]  =  h;\n  this.vertices[8]  = -1.0;\n  this.vertices[9]  = -w;\n  this.vertices[10] =  h;\n  this.vertices[11] = -1.0;\n};\n\n\nElementView.prototype._initCoordinates = function() {\n  var w = this.element.getWidth()/this.element.getImageWidth();\n  var h = this.element.getHeight()/this.element.getImageHeight();\n\n  var x1 = w * this.element.getImageXIndex();\n  var y1 = h * this.element.getImageYIndex();\n  var x2 = x1 + w;\n  var y2 = y1 + h;\n\n  this.coordinates[0] = x1;\n  this.coordinates[1] = y2;\n  this.coordinates[2] = x2;\n  this.coordinates[3] = y2;\n  this.coordinates[4] = x2;\n  this.coordinates[5] = y1;\n  this.coordinates[6] = x1;\n  this.coordinates[7] = y1;\n};\n\n\nElementView.prototype._initIndices = function() {\n  this.indices[0] = 0;\n  this.indices[1] = 1;\n  this.indices[2] = 2;\n\n  this.indices[3] = 0;\n  this.indices[4] = 2;\n  this.indices[5] = 3;\n};\n\n\nElementView.prototype._initColors = function() {\n  this.colors[0] = 1.0;\n  this.colors[1] = 1.0;\n  this.colors[2] = 1.0;\n  this.colors[3] = 1.0;\n\n  this.colors[4] = 1.0;\n  this.colors[5] = 1.0;\n  this.colors[6] = 1.0;\n  this.colors[7] = 1.0;\n\n  this.colors[8] = 1.0;\n  this.colors[9] = 1.0;\n  this.colors[10] = 1.0;\n  this.colors[11] = 1.0;\n\n  this.colors[12] = 1.0;\n  this.colors[13] = 1.0;\n  this.colors[14] = 1.0;\n  this.colors[15] = 1.0;\n};\n\n\nElementView.prototype.saveVertices = function() {\n  for(var i = 0; i < this._V_SIZE; i++) {\n    this.sVertices[i] = this.vertices[i];\n  }\n};\n\n\nElementView.prototype.restoreVertices = function() {\n  for(var i = 0; i < this._V_SIZE; i++) {\n    this.vertices[i] = this.sVertices[i];\n  }\n};\n\n\nElementView.prototype.translate = function() {\n  for(var i = 0; i < this._V_ITEM_NUM; i++) {\n    this.vertices[i*this._V_ITEM_SIZE+0] += this.element.getX();\n    this.vertices[i*this._V_ITEM_SIZE+1] -= this.element.getY();\n    this.vertices[i*this._V_ITEM_SIZE+2] += this.element.getZ();\n  }\n};\n\n\nElementView.prototype.rotate = function() {\n  var radian = this.element.getARadian();\n  for(var i = 0; i < this._V_ITEM_NUM; i++) {\n    var x = this.vertices[i*this._V_ITEM_SIZE+0];\n    var y = this.vertices[i*this._V_ITEM_SIZE+1];\n\n    this.vertices[i*this._V_ITEM_SIZE+0] =\n      x * this.Math.cos(radian) - y * this.Math.sin(radian);\n    this.vertices[i*this._V_ITEM_SIZE+1] =\n      x * this.Math.sin(radian) + y * this.Math.cos(radian);\n  }\n};\n\n\nElementView.prototype.animate = function() {\n};\n\n\n\nfunction ElementsDrawer(elementManager, gl, image) {\n  this.elementManager = elementManager;\n  var maxLength = elementManager.getMaxLength();\n  this.vArray = new Float32Array(maxLength*12);\n  this.cArray = new Float32Array(maxLength*8);\n  this.iArray = new Uint16Array(maxLength*6);\n  this.aArray = new Float32Array(maxLength*16);\n  this.vBuffer = gl.createBuffer();\n  this.cBuffer = gl.createBuffer();\n  this.iBuffer = gl.createBuffer();\n  this.aBuffer = gl.createBuffer();\n  this.image = image;\n  this.texture = null;\n  this._initTexture(gl);\n};\n\n// only for reference\nElementsDrawer.prototype.ElementView = ElementView.prototype;\n\n\nElementsDrawer.prototype._initTexture = function(gl) {\n  this.texture = gl.createTexture();\n  gl.bindTexture(gl.TEXTURE_2D, this.texture)\n//  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,\n                this.image);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);\n  gl.bindTexture(gl.TEXTURE_2D, null);\n};\n\n\nElementsDrawer.prototype._pourVerticies = function(i, v) {\n  v.saveVertices();\n  v.rotate();\n  v.translate();\n  for(var j = 0; j < this.ElementView._V_SIZE; j++) {\n    this.vArray[i*this.ElementView._V_SIZE+j] = v.vertices[j];\n  }\n  v.restoreVertices();\n};\n\n\nElementsDrawer.prototype._pourCoordinates = function(i, v) {\n  for(var j = 0; j < this.ElementView._C_SIZE; j++) {\n    this.cArray[i*this.ElementView._C_SIZE+j] = v.coordinates[j];\n  }\n};\n\n\nElementsDrawer.prototype._pourIndices = function(i, v) {\n  // TODO: 4 is a magic number\n  this.iArray[i*this.ElementView._I_SIZE+0] = i*4 + v.indices[0];\n  this.iArray[i*this.ElementView._I_SIZE+1] = i*4 + v.indices[1];\n  this.iArray[i*this.ElementView._I_SIZE+2] = i*4 + v.indices[2];\n\n  this.iArray[i*this.ElementView._I_SIZE+3] = i*4 + v.indices[3];\n  this.iArray[i*this.ElementView._I_SIZE+4] = i*4 + v.indices[4];\n  this.iArray[i*this.ElementView._I_SIZE+5] = i*4 + v.indices[5];\n};\n\n\nElementsDrawer.prototype._pourColors = function(i, v) {\n  this.aArray[i*this.ElementView._A_SIZE+0] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+1] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+2] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+3] = v.a;\n\n  this.aArray[i*this.ElementView._A_SIZE+4] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+5] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+6] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+7] = v.a;\n\n  this.aArray[i*this.ElementView._A_SIZE+8] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+9] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+10] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+11] = v.a;\n\n  this.aArray[i*this.ElementView._A_SIZE+12] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+13] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+14] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+15] = v.a;\n};\n\n\nElementsDrawer.prototype._pourArray = function() {\n  var length = this.elementManager.getLength();\n\n  for(var i = 0; i < length; i++) {\n    var e = this.elementManager.get(i);\n    var v = e.getView();\n    v.animate();\n    this._pourVerticies(i, v);\n    this._pourCoordinates(i, v);\n    this._pourIndices(i, v);\n    this._pourColors(i, v);\n  }\n};\n\n\nElementsDrawer.prototype._pourBuffer = function(gl) {\n  var length = this.elementManager.getLength();\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, this.vBuffer);\n  gl.bufferData(gl.ARRAY_BUFFER, this.vArray, gl.STATIC_DRAW);\n  this.vBuffer.itemSize = this.ElementView._V_ITEM_SIZE;\n  this.vBuffer.numItems = length * this.ElementView._V_ITEM_NUM;\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, this.cBuffer);\n  gl.bufferData(gl.ARRAY_BUFFER, this.cArray, gl.STATIC_DRAW);\n  this.cBuffer.itemSize = this.ElementView._C_ITEM_SIZE;\n  this.cBuffer.numItems = length * this.ElementView._C_ITEM_NUM;\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, this.aBuffer);\n  gl.bufferData(gl.ARRAY_BUFFER, this.aArray, gl.STATIC_DRAW);\n  this.aBuffer.itemSize = this.ElementView._A_ITEM_SIZE;\n  this.aBuffer.numItems = length * this.ElementView._A_ITEM_NUM;\n\n  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.iBuffer);\n  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.iArray, gl.STATIC_DRAW);\n  this.iBuffer.itemSize = this.ElementView._I_ITEM_SIZE;\n  this.iBuffer.numItems = length * this.ElementView._I_ITEM_NUM;\n};\n\n\nElementsDrawer.prototype._draw = function(layer) {\n  var gl = layer.gl;\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, this.vBuffer);\n  gl.vertexAttribPointer(layer.shader.vertexPositionAttribute,\n                         this.vBuffer.itemSize, gl.FLOAT, false, 0, 0);\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, this.aBuffer);\n  gl.vertexAttribPointer(layer.shader.colorAttribute,\n                         this.aBuffer.itemSize, gl.FLOAT, false, 0, 0);\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, this.cBuffer);\n  gl.vertexAttribPointer(layer.shader.textureCoordAttribute,\n                         this.cBuffer.itemSize, gl.FLOAT, false, 0, 0);\n\n  gl.activeTexture(gl.TEXTURE0);\n  gl.bindTexture(gl.TEXTURE_2D, this.texture);\n  gl.uniform1i(layer.shader.uSamplerUniform, 0);\n\n  gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n  gl.enable(gl.BLEND);\n  gl.disable(gl.DEPTH_TEST);\n\n  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.iBuffer);\n  layer.setMatrixUniforms(gl);\n  gl.drawElements(gl.TRIANGLES, this.iBuffer.numItems, gl.UNSIGNED_SHORT, 0);\n};\n\n\nElementsDrawer.prototype._prepareDraw = function(layer) {\n};\n\n\nElementsDrawer.prototype.draw = function(layer) {\n  this._pourArray();\n  this._pourBuffer(layer.gl);\n  mat4.identity(layer.mvMatrix);\n  this._prepareDraw(layer);\n  this._draw(layer);\n};\n\n\n\nfunction Fighter() {\n  this.parent = Element;\n  this.parent.call(this);\n  this.w = 32;\n  this.h = 48;\n  this.theta = 270;\n};\n__inherit(Fighter, Element);\n\n\nFighter.prototype._generateView = function(gl, image) {\n  return new FighterView(this);\n};\n\n\nFighter.prototype.runStep = function() {\n  this.count++;\n};\n\n\n\nfunction FighterManager() {\n  this.parent = ElementManager;\n  this.parent.call(this);\n  this.maxLength = 2;\n};\n__inherit(FighterManager, ElementManager);\n\n\n\nfunction FighterView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(FighterView, ElementView);\n\n\nFighterView.prototype.animate = function() {\n  var num = ((this.element.count/4)%8) | 0;\n  this.element.xIndex = num;\n  this._initCoordinates();\n};\n\n\n\nfunction FightersDrawer(elementManager, gl, image) {\n  this.parent = ElementsDrawer;\n  this.parent.call(this, elementManager, gl, image);\n};\n__inherit(FightersDrawer, ElementsDrawer);\n\n\n\nfunction Bullet(type) {\n  this.parent = Element;\n  this.parent.call(this);\n  this.w = this._WIDTHS[type];\n  this.h = this._HEIGHTS[type];\n\n  var xRange = this._X_INDEX_RANGE[type];\n  var yRange = this._Y_INDEX_RANGE[type];\n  this.xIndex = this.Math.floor(this.Math.random()*(xRange[1]-xRange[0])) + xRange[0];\n  this.yIndex = this.Math.floor(this.Math.random()*(yRange[1]-yRange[0])) + yRange[0];\n\n  this.imageH = 512; // TODO: temporal\n\n  this.calculate();\n};\n__inherit(Bullet, Element);\n\nBullet.prototype.Math = Math;\n\nBullet.prototype._TYPE_SMALL = 0;\nBullet.prototype._TYPE_MIDDLE = 1;\nBullet.prototype._TYPE_LARGE = 2;\n\nBullet.prototype._WIDTHS = [16, 32, 64];\nBullet.prototype._HEIGHTS = [16, 32, 64];\nBullet.prototype._X_INDEX_RANGE = [[0, 15], [0, 7], [0, 3]];\nBullet.prototype._Y_INDEX_RANGE = [[1, 11], [8, 12], [7, 7]];\n\n\nBullet.prototype._generateView = function() {\n  return new BulletView(this);\n};\n\n\nBullet.prototype.calculate = function() {\n  this.theta = (this.Math.random()*359) | 0;\n  this.rad = this.theta * this.Math.PI/180;\n  this.v = ((this.Math.random()*10) | 0) + 1 ;\n};\n\n\nBullet.prototype.runStep = function() {\n  this.x += this.v * this.Math.cos(this.rad);\n  this.y += this.v * this.Math.sin(this.rad);\n\n  if(this.x < -240 || this.x > 240)\n    this.x = -this.x;\n  if(this.y < -240 || this.y > 240)\n    this.y = -this.y;\n\n  this.count++;\n//  if(this.count % 50 == 0)\n  if(((this.Math.random()*20) | 0) == 0)\n    this.calculate();\n};\n\n\n\nfunction BulletManager() {\n  this.parent = ElementManager;\n  this.parent.call(this);\n  this.maxLength = 5000;\n};\n__inherit(BulletManager, ElementManager);\n\n\n\nfunction BulletView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n  this.a = 1 - this.Math.floor(this.Math.random() * 2)/10;\n};\n__inherit(BulletView, ElementView);\n\nBulletView.prototype.Math = Math;\n\n\nfunction BulletsDrawer(elementManager, gl, image) {\n  this.parent= ElementsDrawer;\n  this.parent.call(this, elementManager, gl, image);\n};\n__inherit(BulletsDrawer, ElementsDrawer);\n\n\n\nfunction Background() {\n  this.parent = Element;\n  this.parent.call(this);\n  this.theta = 270;\n};\n__inherit(Background, Element);\n\n\nBackground.prototype._generateView = function() {\n  return new BackgroundView(this);\n};\n\n\n\nfunction BackgroundManager() {\n  this.parent = ElementManager;\n  this.parent.call(this);\n  this.maxLength = 2;\n};\n__inherit(BackgroundManager, ElementManager);\n\n\n\nfunction BackgroundView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(BackgroundView, ElementView);\n\n\n\nBackgroundView.prototype._initVertices = function() {\n  this.vertices[0] = 0.0;\n  this.vertices[1] = 0.0;\n  this.vertices[2] = 0.0;\n\n  this.vertices[3] = 1.0;\n  this.vertices[4] = 0.0;\n  this.vertices[5] = 0.0;\n\n  this.vertices[6] = 1.0;\n  this.vertices[7] = 4.0;\n  this.vertices[8] = 0.0;\n\n  this.vertices[9] = 0.0;\n  this.vertices[10] = 4.0;\n  this.vertices[11] = 0.0;\n};\n\n\nBackgroundView.prototype._initCoordinates = function() {\n  this.coordinates[0] = 0.0;\n  this.coordinates[1] = 4.0;\n\n  this.coordinates[2] = 1.0;\n  this.coordinates[3] = 4.0;\n\n  this.coordinates[4] = 1.0;\n  this.coordinates[5] = 0.0;\n\n  this.coordinates[6] = 0.0;\n  this.coordinates[7] = 0.0;\n};\n\n\n\nfunction BackgroundsDrawer(elementManager, gl, image) {\n  this.parent = ElementsDrawer;\n  this.parent.call(this, elementManager, gl, image);\n};\n__inherit(BackgroundsDrawer, ElementsDrawer);\n\nBackgroundsDrawer.prototype.Math = Math;\n\n\nBackgroundsDrawer.prototype._prepareDraw = function(layer) {\n  var e = this.elementManager.get(0);\n\n  mat4.rotate(layer.mvMatrix, this.Math.PI/180*50, [-1, 0, 0]);\n  mat4.translate(layer.mvMatrix, [-0.5, 0-(((e.count/2) | 0)%100)/100, -0.5]);\n};\n\n\n\nfunction drawFighter(layer) {\n  layer.ortho(0.1, 10.0);\n  fightersDrawer.draw(layer);\n};\n\n\nfunction drawBullets(layer) {\n  layer.ortho(0.1, 10.0);\n  bulletsDrawer.draw(layer);\n};\n\n\nfunction drawBackground(layer) {\n  layer.perspective(60, 0.1, 10.0);\n  backgroundsDrawer.draw(layer);\n};\n\n\nfunction draw() {\n  mainLayer.setUniformFighterPosition(fighter);\n  mainLayer.setUniformTime(mainLayer.gl);\n\n  bgLayer.viewport();\n  bgLayer.clear();\n  drawBackground(bgLayer);\n\n//  mainLayer.viewport();\n//  mainLayer.clear();\n  drawFighter(mainLayer);\n  drawBullets(mainLayer);\n}\n\n\nfunction calculateFps() {\n  if(r % 60 != 0)\n    return;\n  var newTime = Date.now();\n  if(prevTime) {\n    fps = (1000 * 60 / (newTime - prevTime)) | 0;\n    var div = document.getElementById('fps');\n    div.textContent = fps + 'fps';\n  }\n  prevTime = newTime;\n}\n\n\nfunction tick() {\n  if(done < 3) {\n    requestAnimationFrame(tick);\n    return;\n  }\n  handleMove();\n  fighterManager.runStep();\n  bulletManager.runStep();\n  backgroundManager.runStep();\n  draw();\n  calculateFps();\n  r+=1;\n  requestAnimationFrame(tick);\n}\n\n\nfunction handleKeydown(e) {\n  switch( e.keyCode ) {\n    case 37: // left\n      keys.left = true;\n      break;\n    case 38: // up\n      keys.up = true;\n      break;\n    case 39: // right\n      keys.right = true;\n      break;\n    case 40: // down\n      keys.down = true;\n      break;\n    case 88: // x\n      keys.x = true;\n      break;\n    case 90: // z\n      keys.z = true;\n      break;\n  };\n  e.preventDefault();\n};\n\n\nfunction handleKeyup(e) {\n  switch( e.keyCode ) {\n    case 37: // left\n      keys.left = false;\n      break;\n    case 38: // up\n      keys.up = false;\n      break;\n    case 39: // right\n      keys.right = false;\n      break;\n    case 40: // down\n      keys.down = false;\n      break;\n    case 88: // x\n      keys.x = false;\n      break;\n    case 90: // z\n      keys.z = false;\n      break;\n  };\n  e.preventDefault();\n};\n\n\nfunction handleMove() {\n  var d = 4;\n  if(keys.left)\n    fighter.x -= d;\n  if(keys.up)\n    fighter.y -= d;\n  if(keys.right)\n    fighter.x += d;\n  if(keys.down)\n    fighter.y += d;\n/*\n  if(keys.x)\n    fighter.z -= d;\n  if(keys.z)\n    fighter.z += d;\n*/\n\n  if(fighter.x < -240)\n    fighter.x = -240;\n  if(fighter.x > 240)\n    fighter.x = 240;\n\n  if(fighter.y < -240)\n    fighter.y = -240;\n  if(fighter.y > 240)\n    fighter.y = 240;\n\n};\n\n\nvar done = 0;\nfunction startup() {\n  var mainCanvas = document.getElementById(\"mainCanvas\");\n  mainLayer = new Layer(mainCanvas, 1.0);\n\n  var bgCanvas = document.getElementById(\"bgCanvas\");\n//  bgLayer = new Layer(bgCanvas);\n  bgLayer = mainLayer;\n\n  var fImage = new Image();\n  fImage.onload = function() {\n    fighterManager = new FighterManager();\n    fightersDrawer = new FightersDrawer(fighterManager, mainLayer.gl, fImage);\n    fighter = new Fighter();\n    fighter.init();\n    fighterManager.add(fighter);\n    done++;\n  };\n  fImage.src = 'image/reimu.png';\n\n  var bImage = new Image();\n  var bp = Bullet.prototype;\n  bImage.onload = function() {\n    bulletManager = new BulletManager();\n    bulletsDrawer = new BulletsDrawer(bulletManager, mainLayer.gl, bImage);\n    for(var i = 0; i < bulletsNum; i++) {\n      var type;\n      if(i < smallNum)\n        type = bp._TYPE_SMALL;\n      else if(i < smallNum+middleNum)\n        type = bp._TYPE_MIDDLE;\n      else\n        type = bp._TYPE_LARGE;\n\n      var b = new Bullet(type);\n      b.init();\n      bulletManager.add(b);\n    }\n    done++;\n  };\n  bImage.src = 'image/bullet_pack.png';\n\n  var bgImage = new Image();\n  bgImage.onload = function() {\n    backgroundManager = new BackgroundManager();\n    backgroundsDrawer = new BackgroundsDrawer(backgroundManager, bgLayer.gl,\n                                              bgImage);\n    background = new Background();\n    background.init();\n    backgroundManager.add(background);\n    done++;\n  };\n  bgImage.src = 'image/bg1.png';\n\n  tick();\n}\n\n\nfunction getNumFromInput(e) {\n  var num = e.selectedOptions[0].value | 0;\n  return num\n};\n\n\nfunction updateBullets() {\n\n  smallNum = document.getElementById(\"smallNum\").selectedOptions[0].value | 0;\n  middleNum = document.getElementById(\"middleNum\").selectedOptions[0].value | 0;\n  largeNum = document.getElementById(\"largeNum\").selectedOptions[0].value | 0;\n  bulletsNum = smallNum + middleNum + largeNum;\n\n  bulletManager.clear();\n  var bp = Bullet.prototype;\n  for(var i = 0; i < bulletsNum; i++) {\n      var type;\n      if(i < smallNum)\n        type = bp._TYPE_SMALL;\n      else if(i < smallNum+middleNum)\n        type = bp._TYPE_MIDDLE;\n      else\n        type = bp._TYPE_LARGE;\n\n      var b = new Bullet(type);\n      b.init();\n      bulletManager.add(b);\n  }\n};\n\n\nfunction updateLight() {\n  mainLayer.setUniformLight(document.getElementById('lightBool').checked);\n};\n\n\nwindow.onkeydown = handleKeydown;\nwindow.onkeyup = handleKeyup;\n\n</script>\n</head>\n\n<body onload=\"startup();\">\n<div id=\"canvasdiv\" style=\"position:relative; width:480px; height:480px\">\n<canvas id=\"mainCanvas\" width=\"480\" height=\"480\"\n style=\"z-index: 2; position:absolute;left0px;top0px;\"></canvas>\n<canvas id=\"bgCanvas\" width=\"480\" height=\"480\"\n style=\"z-index: 1; position:absolute;left0px;top0px;\"></canvas>\n</div>\n\n<div id=\"fps\"></div>\n\n<div>\nsmall\n<select id=\"smallNum\" onchange=\"updateBullets()\">\n<option>3000</option>\n<option>2000</option>\n<option>1000</option>\n<option>500</option>\n<option selected>100</option>\n<option>10</option>\n<option>1</option>\n<option>0</option>\n</select>\nmiddle\n<select id=\"middleNum\" onchange=\"updateBullets()\">\n<option>1000</option>\n<option>500</option>\n<option>100</option>\n<option selected>50</option>\n<option>10</option>\n<option>1</option>\n<option>0</option>\n</select>\nlarge\n<select id=\"largeNum\" onchange=\"updateBullets()\">\n<option>300</option>\n<option>200</option>\n<option>100</option>\n<option>50</option>\n<option selected>10</option>\n<option>1</option>\n<option>0</option>\n</select>\nlight\n<input id=\"lightBool\" onchange=\"updateLight()\" type=\"checkbox\">\n</div>\n\n<p>\nTurn your hardware acceleration on to use this benchmark.<br />\nSee &quot;chrome://gpu&quot; and &quot;chrome://flags&quot; on your chrome to check if your hardware acceleration is enabled.\n</p>\n\n<p>\nThanks\n</p>\n<ul>\n<li>Reimu    <a href=\"http://commons.nicovideo.jp/material/nc70557\">http://commons.nicovideo.jp/material/nc70557</a></li>\n<li>Bullet   <a href=\"http://commons.nicovideo.jp/material/nc74535\">http://commons.nicovideo.jp/material/nc74535</a></li>\n<li>BG       <a href=\"http://gi0.net/\">http://gi0.net/</a></li>\n</ul>\n\n<p>\nThis game is made by <a href=\"http://twitter.com/superhoge\">@suprehoge</a>\n</p>\n\n\n</body>\n</html>\n"
  },
  {
    "path": "webrtc_test.html",
    "content": "<!DOCTYPE HTML>\n<html lang=\"en\">\n<head>\n<title></title>\n<meta charset=\"utf-8\">\n<script type=\"text/javascript\" src=\"lib/glMatrix-0.9.5.min.js\"></script>\n<script type=\"text/javascript\" src=\"utility/Inherit.js\"></script>\n<script type=\"text/javascript\" src=\"utility/Peer.js\"></script>\n<script type=\"text/javascript\">\n\n//var wsURL = 'ws://localhost:5000';\nvar wsURL = 'wss://boiling-anchorage-5279.herokuapp.com/';\n\nvar mainLayer;\nvar bgLayer;\n\nvar fighter;\nvar fighter2;\nvar fighterManager;\nvar fightersDrawer;\n\nvar bulletManager;\nvar bulletsDrawer;\n\nvar background;\nvar backgroundManager;\nvar backgroundsDrawer;\n\n\nvar smallNum = 100;\nvar middleNum = 50;\nvar largeNum = 10;\n\nvar bulletsNum = smallNum + middleNum + largeNum;\n\nvar r = 0;\nvar prevTime;\nvar fps = null;\nvar keys = {\n  'up': false,\n  'down': false,\n  'left': false,\n  'right': false,\n  'x': false,\n  'z': false\n};\nvar keys2 = {\n  'up': false,\n  'down': false,\n  'left': false,\n  'right': false,\n  'x': false,\n  'z': false\n};\n\nvar connectButton, runButton;\nvar sync;\n\nfunction Layer(canvas) {\n  this.canvas = canvas;\n  this.gl = this._initGl(canvas);\n  this.gl.clearColor(0.0, 0.0, 0.0, 1.0);\n  this.shader = this._initShader(this.gl);\n  this.mvMatrix = mat4.create();\n  this.pMatrix = mat4.create();\n};\n\nLayer.prototype._NAMES = ['webgl', 'experimental-webgl'];\n\nLayer.prototype._SHADERS = {};\n\nLayer.prototype._SHADERS['shader-vs'] = {};\nLayer.prototype._SHADERS['shader-vs'].type = 'x-shader/x-vertex';\nLayer.prototype._SHADERS['shader-vs'].src = '\\\n  attribute vec3 aVertexPosition;\\\n  attribute vec2 aTextureCoordinates;\\\n  attribute vec4 aColor;\\\n\\\n  uniform mat4 uMVMatrix;\\\n  uniform mat4 uPMatrix;\\\n\\\n  varying vec2 vTextureCoordinates;\\\n  varying vec4 vColor;\\\n  void main() {\\\n    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);\\\n    vTextureCoordinates = aTextureCoordinates;\\\n    vColor = aColor;\\\n  }\\\n';\n\nLayer.prototype._SHADERS['shader-fs'] = {};\nLayer.prototype._SHADERS['shader-fs'].type = 'x-shader/x-fragment';\nLayer.prototype._SHADERS['shader-fs'].src = '\\\n  precision mediump float;\\\n  varying vec2 vTextureCoordinates;\\\n  uniform sampler2D uSampler;\\\n  varying vec4 vColor;\\\n  void main() {\\\n    vec4 textureColor = texture2D(uSampler, vTextureCoordinates);\\\n    gl_FragColor = textureColor * vColor;\\\n  }\\\n';\n\n\nLayer.prototype._initGl = function(canvas) {\n  var names = this._NAMES;\n  var context = null;\n  for(var i = 0; i < names.length; i++) {\n    try {\n      context = canvas.getContext(names[i]);\n    } catch(e) {\n      if(context)\n        break;\n    }\n  }\n  if(context) {\n    context.viewportWidth = canvas.width;\n    context.viewportHeight = canvas.height;\n  } else {\n    alert(\"Failed to create WebGL context!\");\n  }\n  return context;\n};\n\n\nLayer.prototype._compileShaderFromDOM = function(gl, id) {\n  var script = document.getElementById(id);\n\n  if(!script)\n    return null;\n\n  var source = '';\n  var currentChild = script.firstChild;\n  while(currentChild) {\n    if(currentChild.nodeType == 3) { // 3 corresponds to TEXT_NODE\n      source += currentChild.textContent;\n    }\n    currentChild = currentChild.nextSibling;\n  }\n\n  return this._compileShader(gl, source, script.type);\n};\n\n\nLayer.prototype._compileShader = function(gl, source, type) {\n  var shader;\n  if(type == 'x-shader/x-fragment') {\n    shader = gl.createShader(gl.FRAGMENT_SHADER);\n  } else if(type == 'x-shader/x-vertex') {\n    shader = gl.createShader(gl.VERTEX_SHADER);\n  } else {\n    return null;\n  }\n\n  gl.shaderSource(shader, source);\n  gl.compileShader(shader);\n\n  if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n    alert(gl.getShaderInfoLog(shader));\n    return null;\n  }\n  return shader;\n};\n\n\nLayer.prototype._initVertexShader = function(gl) {\n  var params = this._SHADERS['shader-vs'];\n  return this._compileShader(gl, params.src, params.type);\n};\n\n\nLayer.prototype._initFragmentShader = function(gl) {\n  var params = this._SHADERS['shader-fs'];\n  return this._compileShader(gl, params.src, params.type);\n};\n\n\nLayer.prototype._initShader = function(gl) {\n  var vertexShader = this._initVertexShader(gl);\n  var fragmentShader = this._initFragmentShader(gl);\n\n  var shader = gl.createProgram();\n  gl.attachShader(shader, vertexShader);\n  gl.attachShader(shader, fragmentShader);\n  gl.linkProgram(shader);\n\n  if(!gl.getProgramParameter(shader, gl.LINK_STATUS)) {\n    alert(\"Failed to setup shaders\");\n  }\n\n  gl.useProgram(shader);\n\n  shader.vertexPositionAttribute =\n    gl.getAttribLocation(shader, 'aVertexPosition');\n  gl.enableVertexAttribArray(shader.vertexPositionAttribute);\n\n  shader.textureCoordAttribute = \n    gl.getAttribLocation(shader, 'aTextureCoordinates');\n  gl.enableVertexAttribArray(shader.textureCoordAttribute);\n\n  shader.colorAttribute =\n    gl.getAttribLocation(shader, 'aColor');\n  gl.enableVertexAttribArray(shader.colorAttribute);\n\n  shader.pMatrixUniform =\n    gl.getUniformLocation(shader, 'uPMatrix');\n  shader.mvMatrixUniform =\n    gl.getUniformLocation(shader, 'uMVMatrix');\n\n  shader.uSamplerUniform =\n    gl.getUniformLocation(shader, 'uSampler');\n\n  return shader;\n}\n\n\nLayer.prototype.setMatrixUniforms = function(gl) {\n  gl.uniformMatrix4fv(this.shader.pMatrixUniform, false, this.pMatrix);\n  gl.uniformMatrix4fv(this.shader.mvMatrixUniform, false, this.mvMatrix);\n}\n\n\nLayer.prototype.viewport = function() {\n  this.gl.viewport(0, 0, this.gl.viewportWidth, this.gl.viewportHeight);\n};\n\n\nLayer.prototype.clear = function() {\n  this.gl.clear(this.gl.COLOR_BUFFER_BIT);\n};\n\n\nLayer.prototype.perspective = function(theta, near, far) {\n  mat4.perspective(theta, this.gl.viewportWidth / this.gl.viewportHeight,\n                   near, far, this.pMatrix);\n};\n\n\nLayer.prototype.ortho = function(near, far) {\n  mat4.ortho(-this.gl.viewportWidth/2,\n              this.gl.viewportWidth/2,\n             -this.gl.viewportHeight/2,\n              this.gl.viewportHeight/2,\n              near, far, this.pMatrix);\n};\n\n\n\nfunction Element() {\n  this.x = 0;\n  this.y = 0;\n  this.z = 0;\n  this.w = 0;\n  this.h = 0;\n  this.theta = null;\n  this.xIndex = 0;\n  this.yIndex = 0;\n  this.count = 0;\n  this.view = null;\n  this.imageW = 256; // TODO: temporal\n  this.imageH = 256; // TODO: temporal\n};\n\nElement.prototype.Math = Math;\n\nElement.prototype.init = function() {\n  this._initView();\n};\n\n\nElement.prototype._initView = function() {\n  this.view = this._generateView();\n  this.view.init();\n};\n\n\nElement.prototype._generateView = function() {\n  return new ElementView(this);\n};\n\n\nElement.prototype.runStep = function() {\n  this.count++;\n};\n\n\nElement.prototype.getX = function() {\n  return this.x;\n};\n\n\nElement.prototype.getY = function() {\n  return this.y;\n};\n\n\nElement.prototype.getZ = function() {\n  return this.z;\n};\n\n\nElement.prototype.getWidth = function() {\n  return this.w;\n};\n\n\nElement.prototype.getHeight = function() {\n  return this.h;\n};\n\n\nElement.prototype.getTheta = function() {\n  return this.theta;\n};\n\n\nElement.prototype.getRadian = function() {\n  return this._theta2Radian(this.getTheta());\n};\n\n\nElement.prototype.getATheta = function() {\n  return 270-this.theta;\n};\n\n\nElement.prototype.getARadian = function() {\n  return this._theta2Radian(this.getATheta());\n};\n\n\nElement.prototype._theta2Radian = function(theta) {\n  return theta * this.Math.PI / 180;\n};\n\n\nElement.prototype._radian2Theta = function(radian) {\n  return radian * 180 / this.Math.PI;\n};\n\n\nElement.prototype.getView = function() {\n  return this.view;\n};\n\n\nElement.prototype.getImageXIndex = function() {\n  return this.xIndex;\n};\n\n\nElement.prototype.getImageYIndex = function() {\n  return this.yIndex;\n};\n\n\nElement.prototype.getImageWidth = function() {\n  return this.imageW;\n};\n\n\nElement.prototype.getImageHeight = function() {\n  return this.imageH;\n};\n\n\n\nfunction ElementManager() {\n  this.elements = [];\n  this.maxLength = 1000;\n};\n\n\nElementManager.prototype.clear = function() {\n  this.elements.length = 0;\n};\n\n\nElementManager.prototype.get = function(index) {\n  return this.elements[index];\n};\n\n\nElementManager.prototype.add = function(element) {\n  this.elements.push(element);\n};\n\n\nElementManager.prototype.getMaxLength = function() {\n  return this.maxLength;\n};\n\n\nElementManager.prototype.getLength = function() {\n  return this.elements.length;\n};\n\n\nElementManager.prototype.runStep = function() {\n  for(var i = 0; i < this.getLength(); i++)\n    this.get(i).runStep();\n};\n\n\n\nfunction ElementView(element) {\n  this.element = element;\n  this.a = 1.0;\n  this.vertices = [];\n  this.coordinates = [];\n  this.indices = [];\n  this.colors = [];\n  this.sVertices = [];\n  this.vertices.length = this._V_SIZE;\n  this.coordinates.length = this._C_SIZE;\n  this.indices.length = this._I_SIZE;\n  this.colors.length = this._A_SIZE;\n  this.sVertices.length = this._V_SIZE;\n};\n\nElementView.prototype.Math = Math;\n\nElementView.prototype._V_ITEM_SIZE = 3;\nElementView.prototype._V_ITEM_NUM = 4;\nElementView.prototype._V_SIZE = ElementView.prototype._V_ITEM_SIZE *\n                                  ElementView.prototype._V_ITEM_NUM;\n\nElementView.prototype._C_ITEM_SIZE = 2;\nElementView.prototype._C_ITEM_NUM = 4;\nElementView.prototype._C_SIZE = ElementView.prototype._C_ITEM_SIZE *\n                                  ElementView.prototype._C_ITEM_NUM;\n\nElementView.prototype._I_ITEM_SIZE = 1;\nElementView.prototype._I_ITEM_NUM = 6;\nElementView.prototype._I_SIZE = ElementView.prototype._I_ITEM_SIZE *\n                                  ElementView.prototype._I_ITEM_NUM;\n\nElementView.prototype._A_ITEM_SIZE = 4;\nElementView.prototype._A_ITEM_NUM = 4;\nElementView.prototype._A_SIZE = ElementView.prototype._A_ITEM_SIZE *\n                                  ElementView.prototype._A_ITEM_NUM;\n\n\nElementView.prototype.init = function() {\n  this._initVertices();\n  this._initCoordinates();\n  this._initIndices();\n  this._initColors();\n};\n\n\nElementView.prototype._initVertices = function() {\n  var w = this.element.getWidth()/2;\n  var h = this.element.getHeight()/2;\n\n  this.vertices[0]  = -w;\n  this.vertices[1]  = -h;\n  this.vertices[2]  = -1.0;\n  this.vertices[3]  =  w;\n  this.vertices[4]  = -h;\n  this.vertices[5]  = -1.0;\n  this.vertices[6]  =  w;\n  this.vertices[7]  =  h;\n  this.vertices[8]  = -1.0;\n  this.vertices[9]  = -w;\n  this.vertices[10] =  h;\n  this.vertices[11] = -1.0;\n};\n\n\nElementView.prototype._initCoordinates = function() {\n  var w = this.element.getWidth()/this.element.getImageWidth();\n  var h = this.element.getHeight()/this.element.getImageHeight();\n\n  var x1 = w * this.element.getImageXIndex();\n  var y1 = h * this.element.getImageYIndex();\n  var x2 = x1 + w;\n  var y2 = y1 + h;\n\n  this.coordinates[0] = x1;\n  this.coordinates[1] = y2;\n  this.coordinates[2] = x2;\n  this.coordinates[3] = y2;\n  this.coordinates[4] = x2;\n  this.coordinates[5] = y1;\n  this.coordinates[6] = x1;\n  this.coordinates[7] = y1;\n};\n\n\nElementView.prototype._initIndices = function() {\n  this.indices[0] = 0;\n  this.indices[1] = 1;\n  this.indices[2] = 2;\n\n  this.indices[3] = 0;\n  this.indices[4] = 2;\n  this.indices[5] = 3;\n};\n\n\nElementView.prototype._initColors = function() {\n  this.colors[0] = 1.0;\n  this.colors[1] = 1.0;\n  this.colors[2] = 1.0;\n  this.colors[3] = 1.0;\n\n  this.colors[4] = 1.0;\n  this.colors[5] = 1.0;\n  this.colors[6] = 1.0;\n  this.colors[7] = 1.0;\n\n  this.colors[8] = 1.0;\n  this.colors[9] = 1.0;\n  this.colors[10] = 1.0;\n  this.colors[11] = 1.0;\n\n  this.colors[12] = 1.0;\n  this.colors[13] = 1.0;\n  this.colors[14] = 1.0;\n  this.colors[15] = 1.0;\n};\n\n\nElementView.prototype.saveVertices = function() {\n  for(var i = 0; i < this._V_SIZE; i++) {\n    this.sVertices[i] = this.vertices[i];\n  }\n};\n\n\nElementView.prototype.restoreVertices = function() {\n  for(var i = 0; i < this._V_SIZE; i++) {\n    this.vertices[i] = this.sVertices[i];\n  }\n};\n\n\nElementView.prototype.translate = function() {\n  for(var i = 0; i < this._V_ITEM_NUM; i++) {\n    this.vertices[i*this._V_ITEM_SIZE+0] += this.element.getX();\n    this.vertices[i*this._V_ITEM_SIZE+1] -= this.element.getY();\n    this.vertices[i*this._V_ITEM_SIZE+2] += this.element.getZ();\n  }\n};\n\n\nElementView.prototype.rotate = function() {\n  var radian = this.element.getARadian();\n  for(var i = 0; i < this._V_ITEM_NUM; i++) {\n    var x = this.vertices[i*this._V_ITEM_SIZE+0];\n    var y = this.vertices[i*this._V_ITEM_SIZE+1];\n\n    this.vertices[i*this._V_ITEM_SIZE+0] =\n      x * this.Math.cos(radian) - y * this.Math.sin(radian);\n    this.vertices[i*this._V_ITEM_SIZE+1] =\n      x * this.Math.sin(radian) + y * this.Math.cos(radian);\n  }\n};\n\n\nElementView.prototype.animate = function() {\n};\n\n\n\nfunction ElementsDrawer(elementManager, gl, image) {\n  this.elementManager = elementManager;\n  var maxLength = elementManager.getMaxLength();\n  this.vArray = new Float32Array(maxLength*12);\n  this.cArray = new Float32Array(maxLength*8);\n  this.iArray = new Uint16Array(maxLength*6);\n  this.aArray = new Float32Array(maxLength*16);\n  this.vBuffer = gl.createBuffer();\n  this.cBuffer = gl.createBuffer();\n  this.iBuffer = gl.createBuffer();\n  this.aBuffer = gl.createBuffer();\n  this.image = image;\n  this.texture = null;\n  this._initTexture(gl);\n};\n\n// only for reference\nElementsDrawer.prototype.ElementView = ElementView.prototype;\n\n\nElementsDrawer.prototype._initTexture = function(gl) {\n  this.texture = gl.createTexture();\n  gl.bindTexture(gl.TEXTURE_2D, this.texture)\n//  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\n  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,\n                this.image);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);\n  gl.bindTexture(gl.TEXTURE_2D, null);\n};\n\n\nElementsDrawer.prototype._pourVerticies = function(i, v) {\n  v.saveVertices();\n  v.rotate();\n  v.translate();\n  for(var j = 0; j < this.ElementView._V_SIZE; j++) {\n    this.vArray[i*this.ElementView._V_SIZE+j] = v.vertices[j];\n  }\n  v.restoreVertices();\n};\n\n\nElementsDrawer.prototype._pourCoordinates = function(i, v) {\n  for(var j = 0; j < this.ElementView._C_SIZE; j++) {\n    this.cArray[i*this.ElementView._C_SIZE+j] = v.coordinates[j];\n  }\n};\n\n\nElementsDrawer.prototype._pourIndices = function(i, v) {\n  // TODO: 4 is a magic number\n  this.iArray[i*this.ElementView._I_SIZE+0] = i*4 + v.indices[0];\n  this.iArray[i*this.ElementView._I_SIZE+1] = i*4 + v.indices[1];\n  this.iArray[i*this.ElementView._I_SIZE+2] = i*4 + v.indices[2];\n\n  this.iArray[i*this.ElementView._I_SIZE+3] = i*4 + v.indices[3];\n  this.iArray[i*this.ElementView._I_SIZE+4] = i*4 + v.indices[4];\n  this.iArray[i*this.ElementView._I_SIZE+5] = i*4 + v.indices[5];\n};\n\n\nElementsDrawer.prototype._pourColors = function(i, v) {\n  this.aArray[i*this.ElementView._A_SIZE+0] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+1] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+2] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+3] = v.a;\n\n  this.aArray[i*this.ElementView._A_SIZE+4] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+5] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+6] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+7] = v.a;\n\n  this.aArray[i*this.ElementView._A_SIZE+8] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+9] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+10] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+11] = v.a;\n\n  this.aArray[i*this.ElementView._A_SIZE+12] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+13] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+14] = 1.0;\n  this.aArray[i*this.ElementView._A_SIZE+15] = v.a;\n};\n\n\nElementsDrawer.prototype._pourArray = function() {\n  var length = this.elementManager.getLength();\n\n  for(var i = 0; i < length; i++) {\n    var e = this.elementManager.get(i);\n    var v = e.getView();\n    v.animate();\n    this._pourVerticies(i, v);\n    this._pourCoordinates(i, v);\n    this._pourIndices(i, v);\n    this._pourColors(i, v);\n  }\n};\n\n\nElementsDrawer.prototype._pourBuffer = function(gl) {\n  var length = this.elementManager.getLength();\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, this.vBuffer);\n  gl.bufferData(gl.ARRAY_BUFFER, this.vArray, gl.STATIC_DRAW);\n  this.vBuffer.itemSize = this.ElementView._V_ITEM_SIZE;\n  this.vBuffer.numItems = length * this.ElementView._V_ITEM_NUM;\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, this.cBuffer);\n  gl.bufferData(gl.ARRAY_BUFFER, this.cArray, gl.STATIC_DRAW);\n  this.cBuffer.itemSize = this.ElementView._C_ITEM_SIZE;\n  this.cBuffer.numItems = length * this.ElementView._C_ITEM_NUM;\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, this.aBuffer);\n  gl.bufferData(gl.ARRAY_BUFFER, this.aArray, gl.STATIC_DRAW);\n  this.aBuffer.itemSize = this.ElementView._A_ITEM_SIZE;\n  this.aBuffer.numItems = length * this.ElementView._A_ITEM_NUM;\n\n  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.iBuffer);\n  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.iArray, gl.STATIC_DRAW);\n  this.iBuffer.itemSize = this.ElementView._I_ITEM_SIZE;\n  this.iBuffer.numItems = length * this.ElementView._I_ITEM_NUM;\n};\n\n\nElementsDrawer.prototype._draw = function(layer) {\n  var gl = layer.gl;\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, this.vBuffer);\n  gl.vertexAttribPointer(layer.shader.vertexPositionAttribute,\n                         this.vBuffer.itemSize, gl.FLOAT, false, 0, 0);\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, this.aBuffer);\n  gl.vertexAttribPointer(layer.shader.colorAttribute,\n                         this.aBuffer.itemSize, gl.FLOAT, false, 0, 0);\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, this.cBuffer);\n  gl.vertexAttribPointer(layer.shader.textureCoordAttribute,\n                         this.cBuffer.itemSize, gl.FLOAT, false, 0, 0);\n\n  gl.activeTexture(gl.TEXTURE0);\n  gl.bindTexture(gl.TEXTURE_2D, this.texture);\n  gl.uniform1i(layer.shader.uSamplerUniform, 0);\n\n  gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n  gl.enable(gl.BLEND);\n  gl.disable(gl.DEPTH_TEST);\n\n  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.iBuffer);\n  layer.setMatrixUniforms(gl);\n  gl.drawElements(gl.TRIANGLES, this.iBuffer.numItems, gl.UNSIGNED_SHORT, 0);\n};\n\n\nElementsDrawer.prototype._prepareDraw = function(layer) {\n};\n\n\nElementsDrawer.prototype.draw = function(layer) {\n  this._pourArray();\n  this._pourBuffer(layer.gl);\n  mat4.identity(layer.mvMatrix);\n  this._prepareDraw(layer);\n  this._draw(layer);\n};\n\n\n\nfunction Fighter() {\n  this.parent = Element;\n  this.parent.call(this);\n  this.w = 32;\n  this.h = 48;\n  this.theta = 270;\n};\n__inherit(Fighter, Element);\n\n\nFighter.prototype._generateView = function(gl, image) {\n  return new FighterView(this);\n};\n\n\nFighter.prototype.runStep = function() {\n  this.count++;\n};\n\n\n\nfunction FighterManager() {\n  this.parent = ElementManager;\n  this.parent.call(this);\n  this.maxLength = 2;\n};\n__inherit(FighterManager, ElementManager);\n\n\n\nfunction FighterView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(FighterView, ElementView);\n\n\nFighterView.prototype.animate = function() {\n  var num = ((this.element.count/4)%8) | 0;\n  this.element.xIndex = num;\n  this._initCoordinates();\n};\n\n\n\nfunction FightersDrawer(elementManager, gl, image) {\n  this.parent = ElementsDrawer;\n  this.parent.call(this, elementManager, gl, image);\n};\n__inherit(FightersDrawer, ElementsDrawer);\n\n\n\nfunction Bullet(type) {\n  this.parent = Element;\n  this.parent.call(this);\n  this.w = this._WIDTHS[type];\n  this.h = this._HEIGHTS[type];\n\n  var xRange = this._X_INDEX_RANGE[type];\n  var yRange = this._Y_INDEX_RANGE[type];\n  this.xIndex = this.Math.floor(this.Math.random()*(xRange[1]-xRange[0])) + xRange[0];\n  this.yIndex = this.Math.floor(this.Math.random()*(yRange[1]-yRange[0])) + yRange[0];\n\n  this.imageH = 512; // TODO: temporal\n\n  this.calculate();\n};\n__inherit(Bullet, Element);\n\nBullet.prototype.Math = Math;\n\nBullet.prototype._TYPE_SMALL = 0;\nBullet.prototype._TYPE_MIDDLE = 1;\nBullet.prototype._TYPE_LARGE = 2;\n\nBullet.prototype._WIDTHS = [16, 32, 64];\nBullet.prototype._HEIGHTS = [16, 32, 64];\nBullet.prototype._X_INDEX_RANGE = [[0, 15], [0, 7], [0, 3]];\nBullet.prototype._Y_INDEX_RANGE = [[1, 11], [8, 12], [7, 7]];\n\n\nBullet.prototype._generateView = function() {\n  return new BulletView(this);\n};\n\n\nBullet.prototype.calculate = function() {\n  this.theta = (this.Math.random()*359) | 0;\n  this.rad = this.theta * this.Math.PI/180;\n  this.v = ((this.Math.random()*10) | 0) + 1 ;\n};\n\n\nBullet.prototype.runStep = function() {\n  this.x += this.v * this.Math.cos(this.rad);\n  this.y += this.v * this.Math.sin(this.rad);\n\n  if(this.x < -240 || this.x > 240)\n    this.x = -this.x;\n  if(this.y < -240 || this.y > 240)\n    this.y = -this.y;\n\n  this.count++;\n//  if(this.count % 50 == 0)\n  if(((this.Math.random()*20) | 0) == 0)\n    this.calculate();\n};\n\n\n\nfunction BulletManager() {\n  this.parent = ElementManager;\n  this.parent.call(this);\n  this.maxLength = 5000;\n};\n__inherit(BulletManager, ElementManager);\n\n\n\nfunction BulletView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n  this.a = 1 - this.Math.floor(this.Math.random() * 2)/10;\n};\n__inherit(BulletView, ElementView);\n\nBulletView.prototype.Math = Math;\n\n\nfunction BulletsDrawer(elementManager, gl, image) {\n  this.parent= ElementsDrawer;\n  this.parent.call(this, elementManager, gl, image);\n};\n__inherit(BulletsDrawer, ElementsDrawer);\n\n\n\nfunction Background() {\n  this.parent = Element;\n  this.parent.call(this);\n  this.theta = 270;\n};\n__inherit(Background, Element);\n\n\nBackground.prototype._generateView = function() {\n  return new BackgroundView(this);\n};\n\n\n\nfunction BackgroundManager() {\n  this.parent = ElementManager;\n  this.parent.call(this);\n  this.maxLength = 2;\n};\n__inherit(BackgroundManager, ElementManager);\n\n\n\nfunction BackgroundView(element) {\n  this.parent = ElementView;\n  this.parent.call(this, element);\n};\n__inherit(BackgroundView, ElementView);\n\n\n\nBackgroundView.prototype._initVertices = function() {\n  this.vertices[0] = 0.0;\n  this.vertices[1] = 0.0;\n  this.vertices[2] = 0.0;\n\n  this.vertices[3] = 1.0;\n  this.vertices[4] = 0.0;\n  this.vertices[5] = 0.0;\n\n  this.vertices[6] = 1.0;\n  this.vertices[7] = 4.0;\n  this.vertices[8] = 0.0;\n\n  this.vertices[9] = 0.0;\n  this.vertices[10] = 4.0;\n  this.vertices[11] = 0.0;\n};\n\n\nBackgroundView.prototype._initCoordinates = function() {\n  this.coordinates[0] = 0.0;\n  this.coordinates[1] = 4.0;\n\n  this.coordinates[2] = 1.0;\n  this.coordinates[3] = 4.0;\n\n  this.coordinates[4] = 1.0;\n  this.coordinates[5] = 0.0;\n\n  this.coordinates[6] = 0.0;\n  this.coordinates[7] = 0.0;\n};\n\n\n\nfunction BackgroundsDrawer(elementManager, gl, image) {\n  this.parent = ElementsDrawer;\n  this.parent.call(this, elementManager, gl, image);\n};\n__inherit(BackgroundsDrawer, ElementsDrawer);\n\nBackgroundsDrawer.prototype.Math = Math;\n\n\nBackgroundsDrawer.prototype._prepareDraw = function(layer) {\n  var e = this.elementManager.get(0);\n\n  mat4.rotate(layer.mvMatrix, this.Math.PI/180*50, [-1, 0, 0]);\n  mat4.translate(layer.mvMatrix, [-0.5, 0-(((e.count/2) | 0)%100)/100, -0.5]);\n};\n\n\n\nfunction Synchronizer(room) {\n  this.peer = new Peer(room, wsURL, this);\n  this.peer.createPeerConnection();\n  this.localDone = false;\n  this.remoteDone = false;\n}\n\n\nSynchronizer.prototype.connect = function() {\n  this.peer.offer();\n};\n\n\nSynchronizer.prototype.sync = function() {\n  this.localDone = true;\n  this.peer.send(this._buildSentData());\n  if(this.remoteDone)\n    this.runStep();\n};\n\n\nSynchronizer.prototype._ID_START = 0;\nSynchronizer.prototype._ID_SYNC  = 1;\nSynchronizer.prototype._FLAG_UP    = 0x01;\nSynchronizer.prototype._FLAG_DOWN  = 0x02;\nSynchronizer.prototype._FLAG_LEFT  = 0x04;\nSynchronizer.prototype._FLAG_RIGHT = 0x08;\nSynchronizer.prototype._FLAG_X     = 0x10;\nSynchronizer.prototype._FLAG_Z     = 0x20;\nSynchronizer.prototype._CONTAINER = {id: Synchronizer.prototype._ID_SYNC,\n                                     keys: 0};\nSynchronizer.prototype._buildSentData = function() {\n  var value = 0;\n  if(keys.up)\n    value |= this._FLAG_UP;\n  if(keys.down)\n    value |= this._FLAG_DOWN;\n  if(keys.left)\n    value |= this._FLAG_LEFT;\n  if(keys.right)\n    value |= this._FLAG_RIGHT;\n  if(keys.x)\n    value |= this._FLAG_X;\n  if(keys.z)\n    value |= this._FLAG_Z;\n  this._CONTAINER.keys = value;\n  return this._CONTAINER;\n};\n\n\nSynchronizer.prototype._deployReceivedData = function(data) {\n  keys2.up    = (data & this._FLAG_UP)    ? true : false;\n  keys2.down  = (data & this._FLAG_DOWN)  ? true : false;\n  keys2.left  = (data & this._FLAG_LEFT)  ? true : false;\n  keys2.right = (data & this._FLAG_RIGHT) ? true : false;\n  keys2.x     = (data & this._FLAG_X)     ? true : false;\n  keys2.z     = (data & this._FLAG_Z)     ? true : false;\n};\n\n\nSynchronizer.prototype.start = function() {\n  this.peer.send({id: this._ID_START});\n};\n\n\nSynchronizer.prototype.notifyWsReady = function(e) {\n  connectButton.disabled = false;\n};\n\n\nSynchronizer.prototype.notifyOpenPeer = function(e) {\n  __connected();\n};\n\n\nSynchronizer.prototype.notifyClosePeer = function(e) {\n  __disconnected();\n};\n\n\nSynchronizer.prototype.receiveFromPeer = function(data) {\n  switch(data.id) {\n    case this._ID_START:\n      __start();\n      break;\n    case this._ID_SYNC:\n      this._deployReceivedData(data.keys);\n      this.remoteDone = true;\n      if(this.localDone)\n        this.runStep();\n      break;\n  }\n};\n\n\nSynchronizer.prototype.runStep = function() {\n  this.localDone = false;\n  this.remoteDone = false;\n  requestAnimationFrame(tick);\n};\n\n\nfunction drawFighter(layer) {\n  layer.ortho(0.1, 10.0);\n  fightersDrawer.draw(layer);\n};\n\n\nfunction drawBullets(layer) {\n  layer.ortho(0.1, 10.0);\n  bulletsDrawer.draw(layer);\n};\n\n\nfunction drawBackground(layer) {\n  layer.perspective(60, 0.1, 10.0);\n  backgroundsDrawer.draw(layer);\n};\n\n\nfunction draw() {\n  bgLayer.viewport();\n  bgLayer.clear();\n  drawBackground(bgLayer);\n\n//  mainLayer.viewport();\n//  mainLayer.clear();\n  drawFighter(mainLayer);\n  drawBullets(mainLayer);\n}\n\n\nfunction calculateFps() {\n  if(r % 60 != 0)\n    return;\n  var newTime = Date.now();\n  if(prevTime) {\n    fps = (1000 * 60 / (newTime - prevTime)) | 0;\n    var div = document.getElementById('fps');\n    div.textContent = fps + 'fps';\n  }\n  prevTime = newTime;\n}\n\n\nfunction tick() {\n  handleMove(keys, fighter);\n  handleMove(keys2, fighter2);\n  fighterManager.runStep();\n  bulletManager.runStep();\n  backgroundManager.runStep();\n  draw();\n  calculateFps();\n  r+=1;\n  sync.sync();\n//  requestAnimationFrame(tick);\n}\n\n\nfunction handleKeydown(e) {\n  switch( e.keyCode ) {\n    case 37: // left\n      keys.left = true;\n      break;\n    case 38: // up\n      keys.up = true;\n      break;\n    case 39: // right\n      keys.right = true;\n      break;\n    case 40: // down\n      keys.down = true;\n      break;\n    case 88: // x\n      keys.x = true;\n      break;\n    case 90: // z\n      keys.z = true;\n      break;\n  };\n  e.preventDefault();\n};\n\n\nfunction handleKeyup(e) {\n  switch( e.keyCode ) {\n    case 37: // left\n      keys.left = false;\n      break;\n    case 38: // up\n      keys.up = false;\n      break;\n    case 39: // right\n      keys.right = false;\n      break;\n    case 40: // down\n      keys.down = false;\n      break;\n    case 88: // x\n      keys.x = false;\n      break;\n    case 90: // z\n      keys.z = false;\n      break;\n  };\n  e.preventDefault();\n};\n\n\nfunction handleMove(keys, fighter) {\n  var d = 4;\n  if(keys.left)\n    fighter.x -= d;\n  if(keys.up)\n    fighter.y -= d;\n  if(keys.right)\n    fighter.x += d;\n  if(keys.down)\n    fighter.y += d;\n/*\n  if(keys.x)\n    fighter.z -= d;\n  if(keys.z)\n    fighter.z += d;\n*/\n\n  if(fighter.x < -240)\n    fighter.x = -240;\n  if(fighter.x > 240)\n    fighter.x = 240;\n\n  if(fighter.y < -240)\n    fighter.y = -240;\n  if(fighter.y > 240)\n    fighter.y = 240;\n\n};\n\n\nvar done = 0;\nfunction startup() {\n  var array = location.href.split('?');\n  if(array.length <= 1) {\n    location.href = array[0] + '?' + (Math.random() * 10000 | 0);\n    return -1;\n  }\n  var room = parseInt(array[1]);\n  document.getElementById('room').innerText = room;\n\n  connectButton = document.getElementById('connectButton');\n  runButton = document.getElementById('runButton');\n\n  connectButton.disabled = true;\n  runButton.disabled = true;\n\n  sync = new Synchronizer(room);\n\n  var mainCanvas = document.getElementById(\"mainCanvas\");\n  mainLayer = new Layer(mainCanvas, 1.0);\n\n  var bgCanvas = document.getElementById(\"bgCanvas\");\n//  bgLayer = new Layer(bgCanvas);\n  bgLayer = mainLayer;\n\n  var fImage = new Image();\n  fImage.onload = function() {\n    fighterManager = new FighterManager();\n    fightersDrawer = new FightersDrawer(fighterManager, mainLayer.gl, fImage);\n\n    fighter = new Fighter();\n    fighter.init();\n    fighterManager.add(fighter);\n\n    fighter2 = new Fighter();\n    fighter2.init();\n    fighterManager.add(fighter2);\n\n    done++;\n    checkStart();\n  };\n  fImage.src = 'image/reimu.png';\n\n  var bImage = new Image();\n  var bp = Bullet.prototype;\n  bImage.onload = function() {\n    bulletManager = new BulletManager();\n    bulletsDrawer = new BulletsDrawer(bulletManager, mainLayer.gl, bImage);\n    for(var i = 0; i < bulletsNum; i++) {\n      var type;\n      if(i < smallNum)\n        type = bp._TYPE_SMALL;\n      else if(i < smallNum+middleNum)\n        type = bp._TYPE_MIDDLE;\n      else\n        type = bp._TYPE_LARGE;\n\n      var b = new Bullet(type);\n      b.init();\n      bulletManager.add(b);\n    }\n    done++;\n    checkStart();\n  };\n  bImage.src = 'image/bullet_pack.png';\n\n  var bgImage = new Image();\n  bgImage.onload = function() {\n    backgroundManager = new BackgroundManager();\n    backgroundsDrawer = new BackgroundsDrawer(backgroundManager, bgLayer.gl,\n                                              bgImage);\n    background = new Background();\n    background.init();\n    backgroundManager.add(background);\n    done++;\n    checkStart();\n  };\n  bgImage.src = 'image/bg1.png';\n\n//  tick();\n}\n\n\nfunction getNumFromInput(e) {\n  var num = e.selectedOptions[0].value | 0;\n  return num\n};\n\n\nfunction updateBullets() {\n\n  smallNum = document.getElementById(\"smallNum\").selectedOptions[0].value | 0;\n  middleNum = document.getElementById(\"middleNum\").selectedOptions[0].value | 0;\n  largeNum = document.getElementById(\"largeNum\").selectedOptions[0].value | 0;\n  bulletsNum = smallNum + middleNum + largeNum;\n\n  bulletManager.clear();\n  var bp = Bullet.prototype;\n  for(var i = 0; i < bulletsNum; i++) {\n      var type;\n      if(i < smallNum)\n        type = bp._TYPE_SMALL;\n      else if(i < smallNum+middleNum)\n        type = bp._TYPE_MIDDLE;\n      else\n        type = bp._TYPE_LARGE;\n\n      var b = new Bullet(type);\n      b.init();\n      bulletManager.add(b);\n  }\n};\n\n\nfunction __connect() {\n  sync.connect();\n  connectButton.disabled = true;\n  __updateStatus('connecting');\n}\n\n\nfunction __connected() {\n  connectButton.disabled = true;\n  done++;\n  checkStart();\n  __updateStatus('connected');\n}\n\n\nfunction __disconnected() {\n  __updateStatus('disconnected');\n}\n\n\nfunction checkStart() {\n  if(done >= 4) {\n    runButton.disabled = false;\n  }\n}\n\n\nfunction __run() {\n  runButton.disabled = true;\n  sync.start();\n  sync.runStep();\n}\n\n\nfunction __start() {\n  runButton.disabled = true;\n  sync.runStep();\n}\n\n\nfunction __updateStatus(str) {\n  var div = document.getElementById('status');\n  div.innerText = str;\n}\n\n\nwindow.onkeydown = handleKeydown;\nwindow.onkeyup = handleKeyup;\n\n</script>\n</head>\n\n<body onload=\"startup();\">\n\nRoom No. <span id=\"room\"></span>\n\n<div id=\"canvasdiv\" style=\"position:relative; width:480px; height:480px\">\n<canvas id=\"mainCanvas\" width=\"480\" height=\"480\"\n style=\"z-index: 2; position:absolute;left0px;top0px;\"></canvas>\n<canvas id=\"bgCanvas\" width=\"480\" height=\"480\"\n style=\"z-index: 1; position:absolute;left0px;top0px;\"></canvas>\n</div>\n\n<div id=\"fps\"></div>\n<div id=\"status\"></div>\n\n<div>\n<button id=\"connectButton\" onclick=\"__connect()\">connect</button>\n<button id=\"runButton\" onclick=\"__run()\">run</button>\nsmall\n<select id=\"smallNum\" onchange=\"updateBullets()\">\n<option>3000</option>\n<option>2000</option>\n<option>1000</option>\n<option>500</option>\n<option selected>100</option>\n<option>10</option>\n<option>1</option>\n<option>0</option>\n</select>\nmiddle\n<select id=\"middleNum\" onchange=\"updateBullets()\">\n<option>1000</option>\n<option>500</option>\n<option>100</option>\n<option selected>50</option>\n<option>10</option>\n<option>1</option>\n<option>0</option>\n</select>\nlarge\n<select id=\"largeNum\" onchange=\"updateBullets()\">\n<option>300</option>\n<option>200</option>\n<option>100</option>\n<option>50</option>\n<option selected>10</option>\n<option>1</option>\n<option>0</option>\n</select>\n</div>\n\n<p>\nTurn your hardware acceleration on to use this benchmark.<br />\nSee &quot;chrome://gpu&quot; and &quot;chrome://flags&quot; on your chrome to check if your hardware acceleration is enabled.\n</p>\n\n<p>\nNote\n</p>\n<ul>\n<li>No packet loss recover support.</li>\n<li>No bullets sync(bullets independently move on each node).</li>\n</ul>\n\n<p>\nThanks\n</p>\n<ul>\n<li>Reimu    <a href=\"http://commons.nicovideo.jp/material/nc70557\">http://commons.nicovideo.jp/material/nc70557</a></li>\n<li>Bullet   <a href=\"http://commons.nicovideo.jp/material/nc74535\">http://commons.nicovideo.jp/material/nc74535</a></li>\n<li>BG       <a href=\"http://gi0.net/\">http://gi0.net/</a></li>\n</ul>\n\n<p>\nThis game is made by <a href=\"http://twitter.com/superhoge\">@suprehoge</a>\n</p>\n\n\n</body>\n</html>\n"
  },
  {
    "path": "webrtc_trial.html",
    "content": "<html>\n<head>\n<script type=\"text/javascript\" src=\"utility/Peer.js\"></script>\n<script type=\"text/javascript\">\nvar peer;\n//var wsURL = 'ws://localhost:5000';\nvar wsURL = 'wss://boiling-anchorage-5279.herokuapp.com/';\nvar callButton, startButton;\n\nfunction Tester(room) {\n  this.fpsDiv = document.getElementById('fps');\n  this.statusDiv = document.getElementById('status');\n  this.oldDate = Date.now();\n\n  this.peer = new Peer(room, wsURL, this);\n  this.peer.createPeerConnection();\n  this.running = false;\n  this.count = 0;\n\n  var self = this;\n  this.runStepFunc = function() {self.runStep();};\n};\n\n\nTester.prototype.offer = function() {\n  this.peer.offer();\n};\n\n\nTester.prototype.run = function() {\n  this.running = true;\n  this.runStep();\n};\n\n\nTester.prototype.runStep = function() {\n  if(this.count % 60 == 0) {\n    var newDate = Date.now();\n    var fps = (1000 * 60 / (newDate - this.oldDate) | 0);\n    var text = '@' + this.count + ': ' + fps;\n    this.fpsDiv.innerText = text;\n    this.oldDate = newDate;\n  }\n\n  this.send((Math.random() * 4) | 0);\n  this.count++;\n};\n\n\nvar keys = {\n  'id': 'sync', // temporal\n  'key': 0xFF\n};\n\nTester.prototype.send = function(data) {\n//  this.peer.send(data);\n  this.peer.send(keys);\n};\n\n\nTester.prototype.receiveFromPeer = function(data) {\n  if(! this.running)\n    return;\n  requestAnimationFrame(this.runStepFunc);\n};\n\n\nTester.prototype.notifyWsReady = function(event) {\n  callButton.disabled = false;\n};\n\n\nTester.prototype.notifyOpenPeer = function(event) {\n  this.statusDiv.innerText = 'connected';\n  callButton.disabled = true;\n  startButton.disabled = false;\n};\n\n\nTester.prototype.notifyClosePeer = function(event) {\n  this.statusDiv.innerText = 'disconnected';\n};\n\n\nvar tester;\n\nfunction __init() {\n  // TODO: temporal\n  var array = location.href.split('?');\n  if(array.length <= 1) {\n    location.href = array[0] + '?' + ((Math.random() * 10000) | 0);\n    return -1;\n  }\n  var room = parseInt(array[1]);\n  document.getElementById('room').innerText = room;\n\n  tester = new Tester(room);\n  callButton = document.getElementById('callButton');\n  startButton = document.getElementById('startButton');\n  callButton.disabled = true;\n  startButton.disabled = true;\n}\n\nfunction __call() {\n  tester.offer();\n  callButton.disabled = true;\n}\n\nfunction __start() {\n  tester.run();\n  startButton.disabled = true;\n}\n\n</script>\n</head>\n<body onload=\"__init()\">\n\nRoom No <span id=\"room\"></span>\n<button id=\"callButton\" onclick=\"__call()\">call</button>\n<button id=\"startButton\" onclick=\"__start()\">start</button>\n<br>\n<span id=\"fps\"></span> fps\n<div id=\"status\"></div>\n</body>\n</html>\n"
  }
]