Full Code of takahirox/toho-like-js for AI

master 8ff780d9a8bb cached
46 files
504.2 KB
162.9k tokens
130 symbols
1 requests
Download .txt
Showing preview only (524K chars total). Download the full file or copy to clipboard to get everything.
Repository: takahirox/toho-like-js
Branch: master
Commit: 8ff780d9a8bb
Files: 46
Total size: 504.2 KB

Directory structure:
gitextract_2g3v46sm/

├── README.md
├── TODO.txt
├── data/
│   ├── bosses_params.js
│   ├── bullets_params.js
│   ├── danmaku_helper.js
│   ├── enemies_params.js
│   ├── stage_params.js
│   └── talk_params.js
├── index.html
├── index2.html
├── replay/
│   ├── replay1.txt
│   ├── replay2.txt
│   └── replay_list.txt
├── source/
│   ├── Background.js
│   ├── Bomb.js
│   ├── Boss.js
│   ├── Bullet.js
│   ├── CharacterSelectState.js
│   ├── Effect.js
│   ├── Element.js
│   ├── EndingState.js
│   ├── Enemy.js
│   ├── EnemyBullet.js
│   ├── Fighter.js
│   ├── FighterOption.js
│   ├── Game.js
│   ├── GameSocket.js
│   ├── GameState.js
│   ├── Item.js
│   ├── LoadingState.js
│   ├── MoveVector.js
│   ├── OpeningState.js
│   ├── PostReplayState.js
│   ├── ReplaySelectState.js
│   ├── SpellCard.js
│   ├── StaffRollState.js
│   └── StageState.js
├── utility/
│   ├── Draw.js
│   ├── FreeList.js
│   ├── Inherit.js
│   ├── Peer.js
│   ├── Random.js
│   └── WebGL.js
├── webgl_test.html
├── webrtc_test.html
└── webrtc_trial.html

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
# toho-like-js

This is a touhou style danmaku shooter game which runs on your chrome.

## Demo
[Demo](http://takahirox.github.io/toho-like-js/index.html)

[Demo(online Co-op play)](http://takahirox.github.io/toho-like-js/index2.html)

## Online co-op play tutorial

http://d.hatena.ne.jp/takahirox/20140920/1411190305

## Screenshot

![Screen shot](https://github.com/takahirox/assets/blob/master/toho-like-js/screenshot.gif)

![Screen shot1](http://f.st-hatena.com/images/fotolife/t/takahirox/20140608/20140608210348.png)

![Screen shot2](http://f.st-hatena.com/images/fotolife/t/takahirox/20140919/20140919225039.png)

## Features

- fast rendering and many bullets with WebGL
- online co-op play with WebRTC
- watch other players real-time status with WebSocket
- register your replay and watch other players replays

## Benchmarks
[WebGL benchmark](http://takahirox.github.io/toho-like-js/webgl_test.html)

[WebRTC performance test](http://takahirox.github.io/toho-like-js/webrtc_test.html)

[WebRTC Simple test](http://takahirox.github.io/toho-like-js/webrtc_trial.html)

## Dependencies

- [glMatrix](https://github.com/toji/gl-matrix)

No any WebGL 3D libraries, yeah!

## Link

[Touhou Project official site](http://www16.big.or.jp/~zun/)


================================================
FILE: TODO.txt
================================================
stage2
  - bgm
  - bg
boss finish bonus
boss time limit
spell card finish bonus
vanish bullet

enemy variation
Boss effect
Game pad API

separate count up from run step?

enemy beam collision
multi power items

divide area
sin, cos, tan cache

network


================================================
FILE: data/bosses_params.js
================================================
var __stage1BossParams = [ ] ;

__stage1BossParams.push(
  {
    'count': 2100,
    'character': 'rumia',
    'width': 128,
    'height': 128,
    'collisionWidth': 50,
    'collisionHeight': 50,
    'appearedTalk': false,
    'vanishedTalk': false,
    'dead': 'escape',
    'x': 240,
    'y': 0,
    'animation': 3,
    'powerItem': 1,
    'score': 1000,
    'params':
    [
      {
        'spellCard': false,
        'x': 400,
        'y': 150,
        'vital': 200,
        's': [
          { 'bullet': 2, 'type':  5, 'r': 20, 'shotCount': [  10,  20,  30, 280, 290, 300 ], 'baseCount': 600 },
          { 'bullet': 3, 'type':  2,          'shotCount': [ 120, 420 ],                     'baseCount': 600 },
          { 'bullet': 4, 'type':  7, 'r': 20, 'shotCount': [ 310, 320, 330 ],                'baseCount': 600 },
          { 'bullet':20, 'type':  6,          'shotCount': [ 130, 430 ],                     'baseCount': 600 },
        ],
        'v': [
          { 'count':   0, 'v': { 'r':  0, 'theta':180, 'w': 0, 'ra':    0, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count':  50, 'v': { 'r':  4, 'theta':200, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count': 200, 'v': { 'r':  4, 'theta':160, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count': 350, 'v': { 'r':  4, 'theta':340, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count': 500, 'v': { 'r':  4, 'theta': 20, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count': 600, 'v': 2 }
        ],
      },
    ]
  }
) ;


__stage1BossParams.push(
  {
    'count': 3200,
//    'count': 0,
    'character': 'rumia',
    'width': 128,
    'height': 128,
    'collisionWidth': 50,
    'collisionHeight': 50,
    'appearedTalk': true,
    'vanishedTalk': true,
    'x': 240,
    'y': 0,
    'animation': 3,
    'powerItem': 1,
    'score': 5000,
    'params':
    [
      {
        'x': 240,
        'y': 150,
        'vital': 200,
        's': [
          { 'bullet': 2, 'type': 3, 'shotCount': [ 250, 260, 270, 280, 290 ],                'baseCount': 400 },
          { 'bullet': 3, 'type': 3, 'shotCount': [ 340, 360 ],                               'baseCount': 400 },
          { 'bullet': 4, 'type': 3, 'shotCount': [ 255, 265, 275, 285, 295 ],                'baseCount': 400 },
          { 'bullet': 5, 'type': 4, 'shotCount': [ 35, 37, 39, 41, 43, 45, 47, 49, 51, 53 ], 'baseCount': 400 },
          { 'bullet': 6, 'type': 4, 'shotCount': [ 37, 39, 41, 43, 45, 47, 49, 51, 53, 55 ], 'baseCount': 400 },
          { 'bullet': 7, 'type': 4, 'shotCount': [ 39, 41, 43, 45, 47, 49, 51, 53, 55, 57 ], 'baseCount': 400 },
          { 'bullet': 8, 'type': 1, 'shotCount': [ 135 ],                                    'baseCount': 400 },
        ],
        'v': [
          { 'count':   0,   'v': { 'r':  0, 'theta': 90, 'w': 0, 'ra':    0, 'wa': 0, 'raa':  0 } },
          { 'count':  30,   'v': { 'r':  3, 'theta':290, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count': 130,   'v': { 'r':  3, 'theta': 70, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count': 230,   'v': { 'r':  3, 'theta':250, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count': 330,   'v': { 'r':  3, 'theta':110, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count': 400,   'v': 2 }
        ]
      },
      {
        'spellCard': 'Rumia\'s Spell 1',
        'x': 240,
        'y': 100,
        'vital': 300,
        's': [
          { 'bullet': 9, 'type': 2, 'r': 20, 'shotCount': [ 50, 100, 150, 200 ], 'baseCount': 250 },
          { 'bullet':10, 'type': 4, 'r': 20, 'shotCount': [ 25,  75, 125, 170 ], 'baseCount': 250 },
          { 'bullet':11,                     'shotCount': [ 50 ],                'baseCount': 250 },
        ],
        'v': [
          { 'count':   0,   'v': { 'r':  0, 'theta': 90, 'w': 0, 'ra':   0, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count': 250,   'v': { 'r':  3, 'theta': 80, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count': 500,   'v': { 'r':  3, 'theta':240, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count': 750,   'v': { 'r':  3, 'theta':110, 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count':1000,   'v': { 'r':  3, 'theta':310 , 'w': 0, 'ra':-0.05, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count':1250,   'v': 2 }
        ]
      },
      {
        'spellCard': 'Rumia\'s Spell 2',
        'x': 240,
        'y': 100,
        'vital': 300,
        's': [
          { 'bullet':12, 'type': 5, 'r': 20, 'shotCount': [ 0 ], 'baseCount': 1 },
          { 'bullet':12, 'type': 6, 'r': 20, 'shotCount': [ 0 ], 'baseCount': 1 },
        ],
        'v': [
          { 'count':   0,   'v': { 'r':  0, 'theta': 90, 'w': 0, 'ra':   0, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
        ]
      },
    ]
  }
) ;


var __stage2BossParams = [ ] ;

__stage2BossParams.push(
  {
    'count': 2100,
    'character': 'daiyousei',
    'width': 128,
    'height': 128,
    'collisionWidth': 50,
    'collisionHeight': 50,
    'appearedTalk': false,
    'vanishedTalk': false,
    'x': 240,
    'y': 0,
    'animation': 3,
    'powerItem': 1,
    'score': 1000,
    'params':
    [
      {
        'spellCard': false,
        'x': 240,
        'y': 150,
        'vital': 250,
        's': [
          { 'bullet': 14, 'type': 8, 'shotCount': [  10,  20,  30,  40 ], 'baseCount': 300 },
          { 'bullet': 15, 'type': 9, 'shotCount': [ 160, 170, 180, 190 ], 'baseCount': 300 },
        ],
        'v': [
          { 'count':   0, 'v': { 'r':  0, 'theta': 90 } },
          { 'count': 149, 'v': { 'target': { 'x': { 'min':  50, 'max': 240 }, 'y': { 'min':100, 'max': 200 }, 'count': 1 } } },
          { 'count': 150, 'v': { 'r':  0, 'theta': 90 } },
          { 'count': 299, 'v': { 'target': { 'x': { 'min': 240, 'max': 430 }, 'y': { 'min':100, 'max': 200 }, 'count': 1 } } },
          { 'count': 300, 'v': { 'r':  0, 'theta': 90 } },
          { 'count': 449, 'v': { 'target': { 'x': { 'min': 190, 'max': 290 }, 'y': { 'min': 50, 'max': 150 }, 'count': 1 } } },
          { 'count': 450, 'v': 2 }
        ],
        'e': {
          'vanish': { 'count': 100, 'length': 50, 'baseCount': 150 }
        }
      },
    ]
  }
) ;


__stage2BossParams.push(
  {
    'count': 3200,
//    'count': 0,
    'character': 'chilno',
    'width': 128,
    'height': 128,
    'collisionWidth': 50,
    'collisionHeight': 50,
    'appearedTalk': true,
    'vanishedTalk': true,
    'x': 240,
    'y': 0,
    'animation': 3,
    'powerItem': 1,
    'score': 5000,
    'params':
    [
      {
        'spellCard': 'The star of Chilno',
        'x': 240,
        'y': 150,
        'vital': 300,
        's': [
          { 'bullet':16, 'type': 4, 'shotCount': [ 20 ], 'baseCount': 100 },
        ],
        'v': [
          { 'count':   0,   'v': { 'r':  0, 'theta': 90, 'w': 0, 'ra':    0, 'wa': 0, 'raa':  0 } },
        ]
      },
      {
        'spellCard': 'Something freeze',
        'x': 240,
        'y': 100,
        'vital': 300,
        's': [
          { 'bullet': 18, 'type': 2, 'r': 20, 'shotCount': [ 0 ],                                 'baseCount': 500 },
          { 'bullet': 19, 'type': 3, 'r': 20, 'shotCount': [ 350, 355, 360, 365, 370, 375, 380 ], 'baseCount': 500 },
        ],
        'v': [ 
          { 'count':   0, 'v': { 'r':   0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
          { 'count':  10,   'v': { 'target': { 'x': { 'min': 100, 'max': 340 }, 'y': { 'min': 80, 'max': 120 }, 'count':100 } } },
          { 'count': 110, 'v': { 'r':   0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
          { 'count': 335,   'v': { 'target': { 'x': { 'min': 200, 'max': 280 }, 'y': { 'min': 80, 'max': 120 }, 'count': 35 } } },
          { 'count': 370, 'v': { 'r':   0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
          { 'count': 500, 'v': 2 }
        ],
        'e': {
          'shockwave': [
            { 'count': 175, 'baseCount': 500, 'params': { 'w': 10, 'g': 5, 'b': 7, 'a': 0.5, 'endCount': 100 } },
            { 'count': 375, 'baseCount': 500, 'params': { 'w': 10, 'g': 5, 'b': 7, 'a': 0.5, 'endCount': 100 } }
          ]
        }
      },
      {
        'spellCard': 'Falling icicle',
        'x': 240,
        'y': 100,
        'vital': 300,
        's': [
          { 'bullet':17, 'type': 7, 'r': 20, 'shotCount': [ 0 ], 'baseCount': 1 },
        ],
        'v': [
          { 'count':   0,   'v': { 'r':  0, 'theta': 90, 'w': 0, 'ra':   0, 'wa': 0, 'raa':  0, 'rrange': { min: 0 } } },
          { 'count':  50,   'v': { 'target': { 'x': { 'min': 190, 'max': 290 }, 'y': { 'min': 80, 'max': 120 }, 'count': 100 } } },
          { 'count': 150,   'v': 2 },
        ]
      },
    ]
  }
) ;


var __bossesParams = [ ] ;
__bossesParams.push( __stage1BossParams ) ;
__bossesParams.push( __stage2BossParams ) ;




================================================
FILE: data/bullets_params.js
================================================
var __danmakuHelper = new DanmakuHelper( ) ;

var __bulletTypes = [
  {
    'image':            0,
    'indexX':           3,
    'indexY':           4,
    'width':           16,
    'height':          32,
    'collisionWidth':  16,
    'collisionHeight': 32,
    'rotate':          true
  },
  {
    'image':            0,
    'indexX':           3,
    'indexY':           3,
    'width':           16,
    'height':          32,
    'collisionWidth':  16,
    'collisionHeight': 32,
    'rotate':          true
  },
  {
    'image':            0,
    'indexX':           1,
    'indexY':          15,
    'width':           16,
    'height':          16,
    'collisionWidth':  16,
    'collisionHeight': 16,
    'rotate':          true
  },
  {
    'image':            0,
    'indexX':           5,
    'indexY':           0,
    'width':           16,
//    'height':          32,
    'height':          256,
    'collisionWidth':  16,
    'collisionHeight': 32,
    'rotate':          true
  },
] ;


var __bulletsParams = [
  [
    [
      [
        {
          'power': 1,
          'x':   0,
          'y': -20,
          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
      ],
      [
        {
          'power': 0.6,
          'x':  -1,
          'y': -20,
          'v': { 'r':12, 'theta': 266, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.6,
          'x':   1,
          'y': -20,
          'v': { 'r':12, 'theta': 274, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.50,
          'option': 0,
          'homing': true,
          'nextCount': 50,
          'v': { 'r':12, 'theta':210, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },
        },
        {
          'power': 0.50,
          'option': 1,
          'homing': true,
          'nextCount': 50,
          'v': { 'r':12, 'theta':330, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },
        },
      ],
      [
        {
          'power': 0.46,
          'x':  -1,
          'y': -20,
          'v': { 'r':12, 'theta': 262, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.46,
          'x':   0,
          'y': -20,
          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.46,
          'x':   1,
          'y': -20,
          'v': { 'r':12, 'theta': 278, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.40,
          'option': 0,
          'homing': true,
          'nextCount': 20,
          'v': { 'r':12, 'theta':210, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },
        },
        {
          'power': 0.40,
          'option': 1,
          'homing': true,
          'nextCount': 20,
          'v': { 'r':12, 'theta':330, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },
        },
      ],
      [
        {
          'power': 0.4,
          'x':  -3,
          'y': -20,
          'v': { 'r':12, 'theta': 258, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.4,
          'x':  -1,
          'y': -20,
          'v': { 'r':12, 'theta': 266, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.4,
          'x':   1,
          'y': -20,
          'v': { 'r':12, 'theta': 274, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.4,
          'x':   3,
          'y': -20,
          'v': { 'r':12, 'theta': 282, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.30,
          'option': 0,
          'homing': true,
          'nextCount': 10,
          'v': { 'r':12, 'theta':210, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },
        },
        {
          'power': 0.30,
          'option': 1,
          'homing': true,
          'nextCount': 10,
          'v': { 'r':12, 'theta':330, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },
        },
      ],
    ],
    [
      [
        {
          'power': 1,
          'x':   0,
          'y': -20,
          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
      ],
      [
        {
          'power': 0.6,
          'x':  -1,
          'y': -20,
          'v': { 'r':12, 'theta': 269, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.6,
          'x':   1,
          'y': -20,
          'v': { 'r':12, 'theta': 271, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.5,
          'option': 0,
          'homing': true,
          'nextCount': 50,
          'v': { 'r':12, 'theta':260, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },
        },
        {
          'power': 0.5,
          'option': 1,
          'homing': true,
          'nextCount': 50,
          'v': { 'r':12, 'theta':280, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },
        },
      ],
      [
        {
          'power': 0.46,
          'x':  -1,
          'y': -20,
          'v': { 'r':12, 'theta': 268, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.46,
          'x':   0,
          'y': -20,
          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.46,
          'x':   1,
          'y': -20,
          'v': { 'r':12, 'theta': 272, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.4,
          'option': 0,
          'homing': true,
          'nextCount': 20,
          'v': { 'r':12, 'theta':260, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },
        },
        {
          'power': 0.4,
          'option': 1,
          'homing': true,
          'nextCount': 20,
          'v': { 'r':12, 'theta':280, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },
        },
      ],
      [
        {
          'power': 0.4,
          'x':  -3,
          'y': -20,
          'v': { 'r':12, 'theta': 267, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.4,
          'x':  -1,
          'y': -20,
          'v': { 'r':12, 'theta': 269, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.4,
          'x':   1,
          'y': -20,
          'v': { 'r':12, 'theta': 271, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.4,
          'x':   3,
          'y': -20,
          'v': { 'r':12, 'theta': 273, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.3,
          'option': 0,
          'homing': true,
          'nextCount': 10,
          'v': { 'r':12, 'theta':260, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },
        },
        {
          'power': 0.3,
          'option': 1,
          'homing': true,
          'nextCount': 10,
          'v': { 'r':12, 'theta':280, 'w': 0, 'ra': 0.01, 'wa': 0, 'rrange': { 'max': 10 } },
        },
      ]
    ]
  ],
  [
    [
      [
        {
          'power': 1,
          'x':   0,
          'y': -20,
          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
      ],
      [
        {
          'power': 0.6,
          'x':  -1,
          'y': -20,
          'v': { 'r':12, 'theta': 266, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.6,
          'x':   1,
          'y': -20,
          'v': { 'r':12, 'theta': 274, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 1,
          'laser': true,
          'option': 0,
          'keep': 80,
          'waitCount': 50,
          'nextCount': 220,
          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 1,
          'laser': true,
          'option': 1,
          'keep': 80,
          'waitCount': 50,
          'nextCount': 220,
          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
      ],
      [
        {
          'power': 0.46,
          'x':  -1,
          'y': -20,
          'v': { 'r':12, 'theta': 262, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.46,
          'x':   0,
          'y': -20,
          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.46,
          'x':   1,
          'y': -20,
          'v': { 'r':12, 'theta': 278, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 1,
          'option': 0,
          'laser': true,
          'keep': 80,
          'waitCount': 40,
          'nextCount': 210,
          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 1,
          'option': 1,
          'laser': true,
          'keep': 80,
          'waitCount': 40,
          'nextCount': 210,
          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
      ],
      [
        {
          'power': 0.4,
          'x':  -3,
          'y': -20,
          'v': { 'r':12, 'theta': 258, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.4,
          'x':  -1,
          'y': -20,
          'v': { 'r':12, 'theta': 266, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.4,
          'x':   1,
          'y': -20,
          'v': { 'r':12, 'theta': 274, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.4,
          'x':   3,
          'y': -20,
          'v': { 'r':12, 'theta': 282, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 1,
          'option': 0,
          'laser': true,
          'keep': 80,
          'waitCount': 30,
          'nextCount': 200,
          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 1,
          'option': 1,
          'laser': true,
          'keep': 80,
          'waitCount': 30,
          'nextCount': 200,
          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
      ],
    ],
    [
      [
        {
          'power': 1,
          'x':   0,
          'y': -20,
          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
      ],
      [
        {
          'power': 0.6,
          'x':  -1,
          'y': -20,
          'v': { 'r':12, 'theta': 269, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.6,
          'x':   1,
          'y': -20,
          'v': { 'r':12, 'theta': 271, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 1,
          'option': 0,
          'laser': true,
          'keep': 80,
          'waitCount': 50,
          'nextCount': 120,
          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 1,
          'option': 1,
          'laser': true,
          'keep': 80,
          'waitCount': 50,
          'nextCount': 120,
          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
      ],
      [
        {
          'power': 0.46,
          'x':  -1,
          'y': -20,
          'v': { 'r':12, 'theta': 268, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.46,
          'x':   0,
          'y': -20,
          'v': { 'r':12, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.46,
          'x':   1,
          'y': -20,
          'v': { 'r':12, 'theta': 272, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 1,
          'option': 0,
          'laser': true,
          'keep': 80,
          'waitCount': 40,
          'nextCount': 110,
          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 1,
          'option': 1,
          'laser': true,
          'keep': 80,
          'waitCount': 40,
          'nextCount': 110,
          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
      ],
      [
        {
          'power': 0.4,
          'x':  -3,
          'y': -20,
          'v': { 'r':12, 'theta': 267, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.4,
          'x':  -1,
          'y': -20,
          'v': { 'r':12, 'theta': 269, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.4,
          'x':   1,
          'y': -20,
          'v': { 'r':12, 'theta': 271, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 0.4,
          'x':   3,
          'y': -20,
          'v': { 'r':12, 'theta': 273, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 1,
          'option': 0,
          'laser': true,
          'keep': 80,
          'waitCount': 30,
          'nextCount': 100,
          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
        {
          'power': 1,
          'option': 1,
          'laser': true,
          'keep': 80,
          'waitCount': 30,
          'nextCount': 100,
          'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra': 0, 'wa': 0 },
        },
      ]
    ],
  ]
] ;


var __enemyBulletsParams = [
  [
    {
      'v': { 'r': 5, 'theta': 165, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 135, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 105, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta':  75, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta':  45, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta':  15, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
  ],
  [
    {
      'v': { 'aimed': true, 'r': 5, 'theta':  0, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 3 } },
    },
  ],
  [
    {
      'v': { 'r': 5, 'theta':   0, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta':  23, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta':  45, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta':  68, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta':  90, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 113, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 135, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 158, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 180, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 203, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 225, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 248, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 270, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 293, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 315, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 338, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
  ],
  // TODO: simplify
  [
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':   0, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':   5, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  10, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  15, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  20, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  45, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  50, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  55, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  60, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  65, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  90, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  95, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 100, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 105, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 110, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 135, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 140, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 145, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 150, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 155, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 180, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 185, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 190, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 195, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 200, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 225, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 230, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 235, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 240, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 245, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 270, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 275, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 280, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 285, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 290, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 315, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count':  5, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 320, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 10, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 325, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 15, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 330, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 20, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 335, 'w': 0, 'ra':  0, 'wa': 0 } },
        { 'count': 25, 'v': { 'r': 0,               'w': 0, 'ra':0.1, 'wa': 0, 'rrange': { 'max': 3 } } },
      ]
    },
  ],
  [
    {
      'v': { 'r': 5, 'theta':  12, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta':  35, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta':  57, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta':  80, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 102, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 125, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 147, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 170, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 192, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 215, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 237, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 260, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 282, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 305, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 327, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
    {
      'v': { 'r': 5, 'theta': 350, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 2 } },
    },
  ],
  [
    {
      'v': { 'aimed': true, 'r': 5, 'theta':-10, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 3 } },
    },
  ],
  [
    {
      'v': { 'aimed': true, 'r': 5, 'theta':  0, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 3 } },
    },
  ],
  [
    {
      'v': { 'aimed': true, 'r': 5, 'theta': 10, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': -0.01, 'rrange': { 'min': 3 } },
    },
  ],
  [
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  30, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  35, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.1 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  40, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.2 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  45, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  50, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.4 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  55, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.5 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  60, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.6 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  65, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.7 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  70, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.8 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  75, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.9 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  80, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.0 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  85, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.1 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  90, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.2 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  95, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 100, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.4 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 105, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.5 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 110, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.6 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 115, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.7 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 120, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.8 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 125, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.9 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 130, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.0 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 135, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.1 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 140, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.2 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 145, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 150, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.4 } } },
      ]
    },
  ],
  [
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':   0, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  10, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.2 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  20, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.4 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  30, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.6 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  40, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.8 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  50, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.0 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  60, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.2 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  70, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.4 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  80, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.6 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  90, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.8 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 100, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.0 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 110, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.2 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 120, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.4 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 130, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.6 } } },
      ]
    },
  ],
  [
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 175, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.1 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 165, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 155, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.5 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 145, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.7 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 135, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 3.9 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 125, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.1 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 115, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta': 105, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.5 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  95, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.7 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  85, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 4.9 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  75, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.1 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  65, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.3 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  55, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.5 } } },
      ]
    },
    {
      'v': [
        { 'count':  0, 'v': { 'r': 0, 'theta':  45, 'w': 0, 'ra': 0.1, 'wa': 0, 'raa': 0.01, 'rrange': { 'max': 5.7 } } },
      ]
    },
  ],
  [
    {
      'laser': true,
      'waitCount': 40,
      'keep': 150,
      'v': { 'r': 0, 'theta': 180, 'w': -0.01, 'ra':0, 'wa': -0.01, 'trange': { 'min': 110 } },
    },
    {
      'laser': true,
      'waitCount': 40,
      'keep': 150,
      'v': { 'r': 0, 'theta':   0, 'w':  0.01, 'ra':0, 'wa':  0.01, 'trange': { 'max':  70 } },
    },
  ],
  [
    {
      'v': { 'r': 5, 'theta':   0, 'w': 0, 'ra': 0, 'wa': 0, 'rrandom': { 'min': 4, 'max': 5 }, 'trandom': { 'min': 0, 'max': 360 } },
    },
  ],
  [
    {
      'v': { 'r': 3, 'theta':  45, 'w': 0, 'ra': 0, 'wa': 0, 'raa': 0 },
    },
    {
      'v': { 'r': 3, 'theta': 135, 'w': 0, 'ra': 0, 'wa': 0, 'raa': 0 },
    },
    {
      'v': { 'r': 3, 'theta': 225, 'w': 0, 'ra': 0, 'wa': 0, 'raa': 0 },
    },
    {
      'v': { 'r': 3, 'theta': 315, 'w': 0, 'ra': 0, 'wa': 0, 'raa': 0 },
    },
  ],
  __danmakuHelper.daiYousei1( ),
  __danmakuHelper.daiYousei2( ),
  __danmakuHelper.chilno1( ),
  [
    {
      'v': { 'r': 2, 'theta':   0, 'w': 0, 'ra': 0, 'wa': 0, 'rrandom': { 'min': 2, 'max': 3 }, 'trandom': { 'min': 0, 'max': 360 },
             'g': { 'r': 0, 'theta': 90, 'ra': 0.05 }
           },
    },
  ],
  __danmakuHelper.chilno2( ),
  [
    {
      'v': { 'aimed': true, 'r': 5, 'theta':-15, 'w': 0 },
    },
    {
      'v': { 'aimed': true, 'r': 5, 'theta': -5, 'w': 0 },
    },
    {
      'v': { 'aimed': true, 'r': 5, 'theta':  5, 'w': 0 },
    },
    {
      'v': { 'aimed': true, 'r': 5, 'theta': 15, 'w': 0 },
    },
  ],
  [
    {
      'beam': true,
      'v': { 'rrandom': { 'min': 4, 'max': 6 }, 'trandom': { 'min': 180, 'max': 200 },
             'g': { 'r': 0, 'theta': 90, 'ra': 0.3 }
           },
    },
    {
      'beam': true,
      'v': { 'rrandom': { 'min': 4, 'max': 6 }, 'trandom': { 'min': 225, 'max': 245 },
             'g': { 'r': 0, 'theta': 90, 'ra': 0.3 }
           },
    },
    {
      'beam': true,
      'v': { 'rrandom': { 'min': 4, 'max': 6 }, 'trandom': { 'min': 270, 'max': 290 },
             'g': { 'r': 0, 'theta': 90, 'ra': 0.3 }
           },
    },
    {
      'beam': true,
      'v': { 'rrandom': { 'min': 4, 'max': 6 }, 'trandom': { 'min': 340, 'max': 360 },
             'g': { 'r': 0, 'theta': 90, 'ra': 0.3 }
           },
    },
  ],
] ;


var __enemyBulletTypes = [
  {
    'indexX':          15,
    'indexY':           3,
    'width':           16,
    'height':          16,
    'collisionWidth':  10,
    'collisionHeight': 10
  },
  {
    'indexX':           2,
    'indexY':           3,
    'width':           16,
    'height':          16,
    'collisionWidth':  10,
    'collisionHeight': 10
  },
  {
    'indexX':           8,
    'indexY':           3,
    'width':           16,
    'height':          16,
    'collisionWidth':  10,
    'collisionHeight': 10
  },
  {
    'indexX':           6,
    'indexY':           3,
    'width':           16,
    'height':          16,
    'collisionWidth':  10,
    'collisionHeight': 10
  },
  {
    'indexX':           7,
    'indexY':           3,
    'width':           16,
    'height':          16,
    'collisionWidth':  10,
    'collisionHeight': 10
  },
  {
    'indexX':          13,
    'indexY':           4,
    'width':           16,
    'height':          16,
    'collisionWidth':   5,
    'collisionHeight':  5,
    'rotate':        true,
  },
  {
    'indexX':          10,
    'indexY':           4,
    'width':           16,
    'height':          16,
    'collisionWidth':   5,
    'collisionHeight':  5,
    'rotate':        true,
  },
  {
    'indexX':           7,
    'indexY':           4,
    'width':           16,
    'height':          16,
    'collisionWidth':   5,
    'collisionHeight':  5,
    'rotate':        true,
  },
  {
    'indexX':           1,
    'indexY':           5,
    'width':           16,
    'height':          16,
    'collisionWidth':   5,
    'collisionHeight':  5,
    'rotate':        true,
  },
  {
    'indexX':           9,
    'indexY':           5,
    'width':           16,
    'height':          16,
    'collisionWidth':   5,
    'collisionHeight':  5,
    'rotate':        true,
  },
] ;


================================================
FILE: data/danmaku_helper.js
================================================
function DanmakuHelper( ) {

}

DanmakuHelper.prototype._calculateRadian = function( theta ) {
  return theta * Math.PI / 180 ;
} ;


DanmakuHelper.prototype._calculateTheta = function( radian ) {
  return parseInt( radian * 180 / Math.PI ) ;
} ;


DanmakuHelper.prototype.daiYousei1 = function( ) {
  var array = [ ] ;
  var r = 30 ;
  for( var i = 0; i < 36; i++ ) {
    var count = i * 1 ;
    var t = ( ( i * 10 ) + 90 ) % 360 ;
    var v = { 'x': r * Math.cos( this._calculateRadian( t ) ),
              'y': r * Math.sin( this._calculateRadian( t ) ),
              'count': i * 1,
              'v': { 'r': 2 + ( i / 50 ), 'theta': t }
            } ;
    array.push( v ) ;
  }
  return array ;
} ;


DanmakuHelper.prototype.daiYousei2 = function( ) {
  var array = [ ] ;
  var r = 30 ;
  for( var i = 0; i < 36; i++ ) {
    var count = i * 1 ;
    var t = ( ( i * -10 ) + 450 ) % 360 ;
    var v = { 'x': r * Math.cos( this._calculateRadian( t ) ),
              'y': r * Math.sin( this._calculateRadian( t ) ),
              'count': count,
              'v': { 'r': 2 + ( i / 50 ), 'theta': t }
            } ;
    array.push( v ) ;
  }
  return array ;
} ;


DanmakuHelper.prototype.chilno1 = function( ) {
  var array = [ ] ;
  var r = 50 ;
  var r2 = 100 ;
  var points = [ ] ;
  var span = 10 ;
  for( var i = 0; i < 5; i++ ) {
    points[ i ] = ( 126 + 144 * i ) % 360 ;
  }
  for( var i = 0; i < 5; i++ ) {
    var t1 = points[ i ] ;
    var t2 = points[ ( i + 1 ) % 5 ] ;
    var x1 = r * Math.cos( this._calculateRadian( t1 ) ) ;
    var y1 = r * Math.sin( this._calculateRadian( t1 ) ) ;
    var x2 = r * Math.cos( this._calculateRadian( t2 ) ) ;
    var y2 = r * Math.sin( this._calculateRadian( t2 ) ) ;
    for( var j = 0; j < span; j++ ) {
      var count = ( j + i * span ) ;
      var x = x1 + ( x2 - x1 ) / span * j ;
      var y = y1 + ( y2 - y1 ) / span * j ;
      var t = this._calculateTheta( Math.atan2( y, x ) ) ;
      for( var k = 0; k < 5; k++ ) {
        var at = points[ k ] ;
        var ax = x + r2 * Math.cos( this._calculateRadian( at ) ) ;
        var ay = y + r2 * Math.sin( this._calculateRadian( at ) ) ;
        var v = { 'x': ax,
                  'y': ay,
                  'count': count,
                  'v': [
                    { 'count': 0,            'v': { 'r': 0, 'theta': t, } },
                    { 'count': span*6-count, 'v': { 'r': 2, 'w': 0 } }
                  ]
                } ;
        array.push( v ) ;
      }
    }
  }
  return array ;
} ;


DanmakuHelper.prototype.chilno2 = function( ) {
  var array = [ ] ;
  for( var i = 0; i < 200; i++ ) {
    var count = i * 1 ;
    var v = {
              'count': count,
              'v': [
                { 'count': 0,
                  '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 } },
                },
                { 'count': 200 - count,
                  'v': { 'r': 0 },
                },
                { 'count': 400 - count,
                  'v': { 'r': 1, 'theta':   0, 'w': 0, 'ra': 0.02, 'wa': 0, 'trandom': { 'min': 0, 'max': 360 } },
                },
              ]
            } ;
    array.push( v ) ;
  }
  return array ;
} ;


================================================
FILE: data/enemies_params.js
================================================
var __stage1EnemiesParams = [ ] ;


/*
__stage1EnemiesParams.push(
  { 'count': 100,
    'x': 240,
    'y': 100,
    'vital': 3,
    's': [
      { 'bullet': 20, 'type': 6, 'shotCount': [ 10 ], 'loop': true },
//      { 'bullet': 11, 'type': 6, 'shotCount': [ 100 ], 'loop': true },
//      { 'bullet': 8, 'type': 7, 'shotCount': [ 0 ], 'loop': true, 'r': 20 },
    ],
    'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 },
  }
) ;
*/

for( var i = 0; i < 6 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 100 + i * 15,
      'x': 50 + i * 20,
      'vital': 1,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },
        { 'count':  50,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 135 }, 'wrange': { 'max': 0.5 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 6 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 300 + i * 15,
      'x': 380 - i * 20,
      'vital': 1,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  50,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': 45 }, 'wrange': { 'min': -0.5 } } },
      ]
    }
  ) ;
}


for( var i = 0; i < 6 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 500 + i * 15,
      'x': 50 + i * 20,
      'vital': 1,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },
        { 'count':  50,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 135 }, 'wrange': { 'max': 0.5 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 6 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 700 + i * 15,
      'x': 380 - i * 20,
      'vital': 1,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  50,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': 45 }, 'wrange': { 'min': -0.5 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 900 + i * ( 80 - i * 5 ),
      'x': 25 + (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 950 + i * ( 80 - i * 5 ),
      'x': 455 - (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 4 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 1400 + i * 20,
      'x': 50 + i * 50,
      'vital': 1,
      'powerItem': i % 4 == 0 ? 1 : 0,
      'scoreItem': i % 4 == 2 ? 1 : 0,
      's': { 'bullet': 1, 'shotCount': [ 40 ] },
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },
        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': -30 }, 'wrange': { 'min': -1 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 4 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 1410 + i * 10,
      'x': 25 + i * 50,
      'vital': 1,
      'powerItem': i % 4 == 0 ? 1 : 0,
      'scoreItem': i % 4 == 2 ? 1 : 0,
      's': { 'bullet': 1, 'shotCount': [ 40 ] },
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },
        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': -30 }, 'wrange': { 'min': -1 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 4 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 1420 + i * 20,
      'x': 430 - i * 50,
      'vital': 1,
      'powerItem': i % 4 == 0 ? 1 : 0,
      'scoreItem': i % 4 == 2 ? 1 : 0,
      's': { 'bullet': 1, 'shotCount': [ 40 ] },
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 210 }, 'wrange': { 'max': 1 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 4 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 1430 + i * 10,
      'x': 455 - i * 50,
      'vital': 1,
      'powerItem': i % 4 == 0 ? 1 : 0,
      'scoreItem': i % 4 == 2 ? 1 : 0,
      's': { 'bullet': 1, 'shotCount': [ 40 ] },
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 210 }, 'wrange': { 'max': 1 } } },
      ]
    }
  ) ;
}


for( var i = 0; i < 20 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count':1700 + parseInt( i/2 ) * 10,
      'x': ( i%2 == 0 ? 50 : 80 ) + i * 10,
      'vital': 1,
      'powerItem': i % 4 == 0 ? 1 : 0,
      'scoreItem': i % 4 == 2 ? 1 : 0,
      'v': [
        { 'count':   0,  'v': { 'r': 3,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },
        { 'count':  30,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa':-0.02, 'trange': { 'min': -45 }, 'wrange': { 'min': -1 } } },
        { 'count': 180,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa': 0.02, 'trange': { 'max':  45 }, 'wrange': { 'max':  1 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 20 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 1900 + parseInt( i/2 ) * 10,
      'x': ( i%2 == 0 ? 430 : 400 ) - i * 10,
      'vital': 1,
      'powerItem': i % 4 == 0 ? 1 : 0,
      'scoreItem': i % 4 == 2 ? 1 : 0,
      'v': [
        { 'count':   0,  'v': { 'r': 3,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },
        { 'count':  30,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa': 0.02, 'trange': { 'max': 225 }, 'wrange': { 'max':  1 } } },
        { 'count': 180,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa':-0.02, 'trange': { 'min': 135 }, 'wrange': { 'min': -1 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 2300 + i * ( 80 - i * 5 ),
      'x': 25 + (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 2350 + i * ( 80 - i * 5 ),
      'x': 455 - (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 2500 + i * ( 80 - i * 5 ),
      'x': 25 + (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 2550 + i * ( 80 - i * 5 ),
      'x': 455 - (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 2700 + i * ( 80 - i * 5 ),
      'x': 25 + (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage1EnemiesParams.push(
    { 'count': 2750 + i * ( 80 - i * 5 ),
      'x': 455 - (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },
      ]
    }
  ) ;
}


var __stage2EnemiesParams = [ ] ;

for( var i = 0; i < 100 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 100 + i * 5,
      'x': parseInt(__randomizer.random() * 480),
      'vital': 1,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      's': { 'bullet': 13, 'shotCount': [ 10 ] },
      'v': [
        { 'count':   0,  'v': { 'r': 3,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },
      ]
    }
  ) ;
}

for( var i = 0; i < 6 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 500 + i * 15,
      'x': 50 + i * 20,
      'vital': 1,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },
        { 'count':  50,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 135 }, 'wrange': { 'max': 0.5 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 6 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 700 + i * 15,
      'x': 380 - i * 20,
      'vital': 1,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  50,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': 45 }, 'wrange': { 'min': -0.5 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 900 + i * ( 80 - i * 5 ),
      'x': 25 + (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 950 + i * ( 80 - i * 5 ),
      'x': 455 - (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 4 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 1400 + i * 20,
      'x': 50 + i * 50,
      'vital': 1,
      'powerItem': i % 4 == 0 ? 1 : 0,
      'scoreItem': i % 4 == 2 ? 1 : 0,
      's': { 'bullet': 1, 'shotCount': [ 40 ] },
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },
        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': -30 }, 'wrange': { 'min': -1 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 4 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 1410 + i * 10,
      'x': 25 + i * 50,
      'vital': 1,
      'powerItem': i % 4 == 0 ? 1 : 0,
      'scoreItem': i % 4 == 2 ? 1 : 0,
      's': { 'bullet': 1, 'shotCount': [ 40 ] },
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },
        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': -0.01, 'trange': { 'min': -30 }, 'wrange': { 'min': -1 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 4 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 1420 + i * 20,
      'x': 430 - i * 50,
      'vital': 1,
      'powerItem': i % 4 == 0 ? 1 : 0,
      'scoreItem': i % 4 == 2 ? 1 : 0,
      's': { 'bullet': 1, 'shotCount': [ 40 ] },
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 210 }, 'wrange': { 'max': 1 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 4 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 1430 + i * 10,
      'x': 455 - i * 50,
      'vital': 1,
      'powerItem': i % 4 == 0 ? 1 : 0,
      'scoreItem': i % 4 == 2 ? 1 : 0,
      's': { 'bullet': 1, 'shotCount': [ 40 ] },
      'v': [
        { 'count':   0,  'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30,  'v': { 'r': 2,               'w':    0, 'ra': 0, 'wa': 0.01, 'trange': { 'max': 210 }, 'wrange': { 'max': 1 } } },
      ]
    }
  ) ;
}


for( var i = 0; i < 20 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count':1700 + parseInt( i/2 ) * 10,
      'x': ( i%2 == 0 ? 50 : 80 ) + i * 10,
      'vital': 1,
      'powerItem': i % 4 == 0 ? 1 : 0,
      'scoreItem': i % 4 == 2 ? 1 : 0,
      'v': [
        { 'count':   0,  'v': { 'r': 3,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },
        { 'count':  30,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa':-0.02, 'trange': { 'min': -45 }, 'wrange': { 'min': -1 } } },
        { 'count': 180,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa': 0.02, 'trange': { 'max':  45 }, 'wrange': { 'max':  1 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 20 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 1900 + parseInt( i/2 ) * 10,
      'x': ( i%2 == 0 ? 430 : 400 ) - i * 10,
      'vital': 1,
      'powerItem': i % 4 == 0 ? 1 : 0,
      'scoreItem': i % 4 == 2 ? 1 : 0,
      'v': [
        { 'count':   0,  'v': { 'r': 3,  'theta': 90, 'w':    0, 'ra': 0, 'wa':    0 } },
        { 'count':  30,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa': 0.02, 'trange': { 'max': 225 }, 'wrange': { 'max':  1 } } },
        { 'count': 180,  'v': { 'r': 3,               'w':    0, 'ra': 0, 'wa':-0.02, 'trange': { 'min': 135 }, 'wrange': { 'min': -1 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 2300 + i * ( 80 - i * 5 ),
      'x': 25 + (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 2350 + i * ( 80 - i * 5 ),
      'x': 455 - (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 2500 + i * ( 80 - i * 5 ),
      'x': 25 + (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 2550 + i * ( 80 - i * 5 ),
      'x': 455 - (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 2700 + i * ( 80 - i * 5 ),
      'x': 25 + (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':   0.1, 'trange': { 'max': 190 } } },
      ]
    }
  ) ;
}

for( var i = 0; i < 8 ; i++ ) {
  __stage2EnemiesParams.push(
    { 'count': 2750 + i * ( 80 - i * 5 ),
      'x': 455 - (i%4) * 50,
      'vital': 3,
      'powerItem': i % 2 == 0 ? 1 : 0,
      'scoreItem': i % 2 == 1 ? 1 : 0,
      's': { 'bullet': 0, 'shotCount': [ 40+(i%2)*20 ] },
      'v': [
        { 'count':   0,      'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count':  30+(i%2)*20, 'v': { 'r': 0,  'theta': 90, 'w':    0, 'ra': 0, 'wa':     0 } },
        { 'count': 130+(i%2)*20, 'v': { 'r': 2,  'theta': 90, 'w':    0, 'ra': 0, 'wa':  -0.1, 'trange': { 'min': -10 } } },
      ]
    }
  ) ;
}


var __enemiesParams = [ ] ;
__enemiesParams.push( __stage1EnemiesParams ) ;
__enemiesParams.push( __stage2EnemiesParams ) ;



================================================
FILE: data/stage_params.js
================================================
var __stage1Params = {
  'title': 'Nothing Special',
  'bgScale': [
    { 'beginCount':    0, 'endCount':    1, 'a': 0.5 },
    { 'beginCount':  500, 'endCount': 1500, 'd': 0.0002 },
    { 'beginCount': 2500, 'endCount': 3000, 'd': -0.0004 },
  ]
} ;

var __stage2Params = {
  'title': 'Something Special',
  'bgScale': [
    { 'beginCount':    0, 'endCount':    1, 'a': 1.0 },
    { 'beginCount':  500, 'endCount': 1500, 'd': -0.0001 },
    { 'beginCount': 2500, 'endCount': 3000, 'd': -0.0006 },
  ]
} ;

var __stageParams = [ ] ;
__stageParams.push( __stage1Params ) ;
__stageParams.push( __stage2Params ) ;



================================================
FILE: data/talk_params.js
================================================
var __reimuBossTalkParams = [ ] ;
var __marisaBossTalkParams = [ ] ;

__reimuBossTalkParams.push(
  { 'serif': 'Hi, how\'re you doing, Rumia?',
    'left':  { 'character': 'reimu', 'active': true },
    'right': { 'character': 'rumia' },
  }
) ;

__reimuBossTalkParams.push(
  { 'serif': 'Good. But hungry. Can I eat you?',
    'left':  { 'character': 'reimu' },
    'right': { 'character': 'rumia', 'active': true },
  }
) ;

__reimuBossTalkParams.push(
  { 'serif': 'Sorry, I\'m busy now.\nI can play with you after I solve the Ihen.',
    'left':  { 'character': 'reimu', 'active': true },
    'right': { 'character': 'rumia' },
  }
) ;


__marisaBossTalkParams.push(
  { 'serif': 'Hi, Marisa. What are you doing now?',
    'left':  { 'character': 'marisa' },
    'right': { 'character': 'rumia', 'active': true },
  }
) ;

__marisaBossTalkParams.push(
  { 'serif': 'Ah? I just enjoy flying now.',
    'left':  { 'character': 'marisa', 'active': true},
    'right': { 'character': 'rumia' },
  }
) ;

__marisaBossTalkParams.push(
  { 'serif': 'So-nano-ka-?',
    'left':  { 'character': 'marisa' },
    'right': { 'character': 'rumia',  'active': true },
  }
) ;

var __stage1BossTalkParams = [ ] ;
__stage1BossTalkParams.push( __reimuBossTalkParams ) ;
__stage1BossTalkParams.push( __marisaBossTalkParams ) ;

var __reimuClearTalkParams = [ ] ;

__reimuClearTalkParams.push(
  { 'serif': 'Got tired.',
    'left':  { 'character': 'reimu', 'active': true },
  }
) ;

var __marisaClearTalkParams = [ ] ;

__marisaClearTalkParams.push(
  { 'serif': 'I\'ve done it.',
    'left':  { 'character': 'marisa', 'active': true },
  }
) ;

var __stage1ClearTalkParams = [ ] ;
__stage1ClearTalkParams.push( __reimuClearTalkParams ) ;
__stage1ClearTalkParams.push( __marisaClearTalkParams ) ;

var __stage1TalksParams = [ ] ;
__stage1TalksParams.push( __stage1BossTalkParams ) ;
__stage1TalksParams.push( __stage1ClearTalkParams ) ;


var __reimuBossTalk2Params = [ ] ;
__reimuBossTalk2Params.push(
  { 'serif': 'Sorry, I have no topics.',
    'left':  { 'character': 'reimu', 'active': true },
    'right': { 'character': 'chilno' },
  }
) ;

__reimuBossTalk2Params.push(
  { 'serif': 'W-What\'s!?',
    'left':  { 'character': 'reimu' },
    'right': { 'character': 'chilno', 'active': true },
  }
) ;


var __marisaBossTalk2Params = [ ] ;
__marisaBossTalk2Params.push(
  { 'serif': 'Sorry, I have no topics.',
    'left':  { 'character': 'marisa', 'active': true },
    'right': { 'character': 'chilno' },
  }
) ;

__marisaBossTalk2Params.push(
  { 'serif': 'W-What\'s!?',
    'left':  { 'character': 'marisa' },
    'right': { 'character': 'chilno', 'active': true },
  }
) ;


var __stage2BossTalkParams = [ ] ;
__stage2BossTalkParams.push( __reimuBossTalk2Params ) ;
__stage2BossTalkParams.push( __marisaBossTalk2Params ) ;


var __stage2TalksParams = [ ] ;
__stage2TalksParams.push( __stage2BossTalkParams ) ;
__stage2TalksParams.push( __stage1ClearTalkParams ) ; // TODO: temporal


var __talkParams = [ ] ;
__talkParams.push( __stage1TalksParams ) ;
__talkParams.push( __stage2TalksParams ) ;



================================================
FILE: index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Toho like shooting with JavaScript</title>
<script type="text/javascript" src="lib/glMatrix-0.9.5.min.js"></script>
<script type="text/javascript" src="utility/Inherit.js"></script>
<script type="text/javascript" src="utility/Draw.js"></script>
<script type="text/javascript" src="utility/Random.js"></script>
<script type="text/javascript" src="utility/FreeList.js"></script>
<script type="text/javascript" src="utility/WebGL.js"></script>
<script type="text/javascript" src="utility/Peer.js"></script>
<script type="text/javascript" src="data/danmaku_helper.js"></script>
<script type="text/javascript" src="data/bullets_params.js"></script>
<script type="text/javascript" src="data/enemies_params.js"></script>
<script type="text/javascript" src="data/bosses_params.js"></script>
<script type="text/javascript" src="data/talk_params.js"></script>
<script type="text/javascript" src="data/stage_params.js"></script>
<script type="text/javascript" src="source/GameSocket.js"></script>
<script type="text/javascript" src="source/Game.js"></script>
<script type="text/javascript" src="source/MoveVector.js"></script>
<script type="text/javascript" src="source/Element.js"></script>
<script type="text/javascript" src="source/Background.js"></script>
<script type="text/javascript" src="source/Fighter.js"></script>
<script type="text/javascript" src="source/FighterOption.js"></script>
<script type="text/javascript" src="source/Enemy.js"></script>
<script type="text/javascript" src="source/Boss.js"></script>
<script type="text/javascript" src="source/Effect.js"></script>
<script type="text/javascript" src="source/Bullet.js"></script>
<script type="text/javascript" src="source/Bomb.js"></script>
<script type="text/javascript" src="source/EnemyBullet.js"></script>
<script type="text/javascript" src="source/Item.js"></script>
<script type="text/javascript" src="source/SpellCard.js"></script>
<script type="text/javascript" src="source/GameState.js"></script>
<script type="text/javascript" src="source/LoadingState.js"></script>
<script type="text/javascript" src="source/OpeningState.js"></script>
<script type="text/javascript" src="source/CharacterSelectState.js"></script>
<script type="text/javascript" src="source/ReplaySelectState.js"></script>
<script type="text/javascript" src="source/PostReplayState.js"></script>
<script type="text/javascript" src="source/StageState.js"></script>
<script type="text/javascript" src="source/EndingState.js"></script>
<script type="text/javascript" src="source/StaffRollState.js"></script>
<script type="text/javascript">

var __game ;

var init = function( ) {
  var mainCanvas = document.getElementById( 'mainCanvas' ) ;
  var bgCanvas = document.getElementById('bgCanvas');
  var game = new Game(mainCanvas, bgCanvas);
  __game = game ;
  window.onkeydown = function(event) { game.handleKeyDown(event); };
  window.onkeyup = function(event) { game.handleKeyUp(event); };
  game.run( ) ;
} ;

</script>
</head>

<body onLoad="init( )">

<div id="canvasdiv" style="position:relative; width:640px; height:480px">
<canvas id="mainCanvas" width="640" height="480"
 style="z-index: 2; position:absolute;left0px;top0px;"></canvas>
<canvas id="bgCanvas" width="480" height="480"
 style="z-index: 1; position:absolute;left0px;top0px;"></canvas>
</div>

<p>
How to play
</p>
<ul>
<li>Cursor key: move / character select</li>
<li>Z:          shot / ok</li>
<li>X:          bomb / cancel</li>
<li>Shift:      slow</li>
<li>Space:      character change(for debug)</li>
<li>Y:          viewpoint change</li>
</ul>

<p>
Turn your hardware acceleration on to fully enjoy this game.<br />
See &quot;chrome://gpu&quot; and &quot;chrome://flags&quot; on your chrome to check if your hardware acceleration is enabled.
</p>

<p>
Thanks for all the images and musics.
</p>
<ul>
<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>
<li>SE       <a href="http://commons.nicovideo.jp/material/nc1456">http://commons.nicovideo.jp/material/nc1456</a></li>
<li>Face     <a href="http://kinginsan.blog60.fc2.com/">http://kinginsan.blog60.fc2.com/</a></li>
<li>Standup  <a href="http://gensoukyou.1000.tv/">http://gensoukyou.1000.tv/</a></li>
<li>Marisa   <a href="http://commons.nicovideo.jp/material/nc71167">http://commons.nicovideo.jp/material/nc71167</a></li>
<li>Reimu    <a href="http://commons.nicovideo.jp/material/nc70557">http://commons.nicovideo.jp/material/nc70557</a></li>
<li>Bullet   <a href="http://commons.nicovideo.jp/material/nc74535">http://commons.nicovideo.jp/material/nc74535</a></li>
<li>BG       <a href="http://subtlepatterns.com/hixs-evolution/">http://subtlepatterns.com/hixs-evolution/</a></li>
<li>BG       <a href="http://gi0.net/">http://gi0.net/</a></li>
<li>BG       <a href="http://commons.nicovideo.jp/material/nc21291">http://commons.nicovideo.jp/material/nc21291</a></li>
<li>BGM      <a href="http://commons.nicovideo.jp/material/nc25738">http://commons.nicovideo.jp/material/nc25738</a></li>
<li>BGM      <a href="http://commons.nicovideo.jp/material/nc13447">http://commons.nicovideo.jp/material/nc13447</a></li>
<li>BGM      <a href="http://commons.nicovideo.jp/material/nc22928">http://commons.nicovideo.jp/material/nc22928</a></li>
</ul>

<p>
This game is made by <a href="http://twitter.com/superhoge">@suprehoge</a>
</p>

<p>
<a href="https://github.com/takahirox/toho-like-js">Source code</a>
</p>

</body>
</html>


================================================
FILE: index2.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Toho like shooting with JavaScript</title>
<script type="text/javascript" src="lib/glMatrix-0.9.5.min.js"></script>
<script type="text/javascript" src="utility/Inherit.js"></script>
<script type="text/javascript" src="utility/Draw.js"></script>
<script type="text/javascript" src="utility/Random.js"></script>
<script type="text/javascript" src="utility/FreeList.js"></script>
<script type="text/javascript" src="utility/WebGL.js"></script>
<script type="text/javascript" src="utility/Peer.js"></script>
<script type="text/javascript" src="data/danmaku_helper.js"></script>
<script type="text/javascript" src="data/bullets_params.js"></script>
<script type="text/javascript" src="data/enemies_params.js"></script>
<script type="text/javascript" src="data/bosses_params.js"></script>
<script type="text/javascript" src="data/talk_params.js"></script>
<script type="text/javascript" src="data/stage_params.js"></script>
<script type="text/javascript" src="source/GameSocket.js"></script>
<script type="text/javascript" src="source/Game.js"></script>
<script type="text/javascript" src="source/MoveVector.js"></script>
<script type="text/javascript" src="source/Element.js"></script>
<script type="text/javascript" src="source/Background.js"></script>
<script type="text/javascript" src="source/Fighter.js"></script>
<script type="text/javascript" src="source/FighterOption.js"></script>
<script type="text/javascript" src="source/Enemy.js"></script>
<script type="text/javascript" src="source/Boss.js"></script>
<script type="text/javascript" src="source/Effect.js"></script>
<script type="text/javascript" src="source/Bullet.js"></script>
<script type="text/javascript" src="source/Bomb.js"></script>
<script type="text/javascript" src="source/EnemyBullet.js"></script>
<script type="text/javascript" src="source/Item.js"></script>
<script type="text/javascript" src="source/SpellCard.js"></script>
<script type="text/javascript" src="source/GameState.js"></script>
<script type="text/javascript" src="source/LoadingState.js"></script>
<script type="text/javascript" src="source/OpeningState.js"></script>
<script type="text/javascript" src="source/CharacterSelectState.js"></script>
<script type="text/javascript" src="source/ReplaySelectState.js"></script>
<script type="text/javascript" src="source/PostReplayState.js"></script>
<script type="text/javascript" src="source/StageState.js"></script>
<script type="text/javascript" src="source/EndingState.js"></script>
<script type="text/javascript" src="source/StaffRollState.js"></script>
<script type="text/javascript">

// for console
var __game;
var __connectButton, __statusSpan;
var __alreadyConnected = false;


// TODO: temporal
var __reloadWithRandomRoomNo = function(baseURL, params) {
  var args = '';
  if(params.lag !== null)
    args = '&l=' + params.lag;

  location.href = baseURL + '?' + (Math.random() * 10000 | 0) + args;
};


// TODO: temporal
var __validateURL = function(params) {
  var array = location.href.split('?');
  var baseURL = array[0];

  if(array.length <= 1) {
    __reloadWithRandomRoomNo(baseURL, params);
    return false;
  }

  var args = array[1].split('&');

  if(args.length > 1) {
    for(var i = 1; i < args.length; i++) {
      var p = args[i].split('=');
      if(p[0] === 'l' && ! isNaN(p[1])) {
        params.lag = parseInt(p[1]);
        if(params.lag < 1)
          params.lag = 1;
        if(params.lag > 20)
          params.lag = 20;
      }
    }
  }

  var room = args[0];
  if(room === '' || isNaN(room)) {
    __reloadWithRandomRoomNo(baseURL, params);
    return false;
  }
  params.room = parseInt(room);
  return true;
};


var __init = function( ) {
  // TODO: temporal
  var params = {room: null, lag: null};
  if(! __validateURL(params)) {
    return -1;
  }

  var room = params.room;
  document.getElementById('room').innerText = room;

  __statusSpan = document.getElementById('status');
  __connectButton = document.getElementById('connectButton');

  __statusSpan.innerText = '0 in the room.';
  __connectButton.disabled = true;

  var mainCanvas = document.getElementById( 'mainCanvas' ) ;
  var bgCanvas = document.getElementById('bgCanvas');
  var game = new Game(mainCanvas, bgCanvas);
  game.setRoom(room);
  if(params.lag !== null)
    game.setLag(params.lag);

  __game = game ;

  game.onWsReady = function(event) { __wsReady(event); };
  game.onRoomUpdate = function(num) { __updatedRoom(num); };
  game.onConnected = function(event) { __connected(event); };
  game.onSentParams = function() { __waitingForOther(); };
  game.onRan = function() { __ranTheGame(); };

  window.onkeydown = function(event) { game.handleKeyDown(event); };
  window.onkeyup = function(event) { game.handleKeyUp(event); };

  __game.run();
} ;


var __wsReady = function(event) {
//  __connectButton.disabled = false;
};


var __connect = function() {
  __connectButton.disabled = true;
  __statusSpan.innerText = 'connecting.';
  __game.connect();
};


var __updatedRoom = function(num) {
  if(! __alreadyConnected) {
    __statusSpan.innerText = num + ' in the room.';
    if(num < 2) {
      __connectButton.disabled = true;
      __statusSpan.innerText += ' (need one more person)';
    } else if(num == 2) {
      __connectButton.disabled = false;
      __statusSpan.innerText += ' (ready to push connect button)';
    } else {
      __connectButton.disabled = true;
      __statusSpan.innerText += ' (over capacity)';
    }
  }
};


var __connected = function() {
  __alreadyConnected = true;
  __connectButton.disabled = true;
  __statusSpan.innerText = 'connected.';
};


var __waitingForOther = function() {
  __statusSpan.innerText = 'waiting for other\'s character select.';
};


var __ranTheGame = function() {
  __statusSpan.innerText = 'ran.';
};


</script>
</head>

<body onLoad="__init()">

Room No. <span id="room"></span>
<button id="connectButton" onclick="__connect()">connect</button>
<span id="status"></span>

<div id="canvasdiv" style="position:relative; width:640px; height:480px">
<canvas id="mainCanvas" width="640" height="480"
 style="z-index: 2; position:absolute;left0px;top0px;"></canvas>
<canvas id="bgCanvas" width="480" height="480"
 style="z-index: 1; position:absolute;left0px;top0px;"></canvas>
</div>

<p>
How to play
</p>
<ul>
<li>Cursor key: move / character select</li>
<li>Z:          shot / ok</li>
<li>X:          bomb / cancel</li>
<li>Shift:      slow</li>
<li>Space:      character change(for debug)</li>
<li>Y:          viewpoint change</li>
</ul>

<p>
Turn your hardware acceleration on to fully enjoy this game.<br />
See &quot;chrome://gpu&quot; and &quot;chrome://flags&quot; on your chrome to check if your hardware acceleration is enabled.
</p>

<p>
Thanks for all the images and musics.
</p>
<ul>
<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>
<li>SE       <a href="http://commons.nicovideo.jp/material/nc1456">http://commons.nicovideo.jp/material/nc1456</a></li>
<li>Face     <a href="http://kinginsan.blog60.fc2.com/">http://kinginsan.blog60.fc2.com/</a></li>
<li>Standup  <a href="http://gensoukyou.1000.tv/">http://gensoukyou.1000.tv/</a></li>
<li>Marisa   <a href="http://commons.nicovideo.jp/material/nc71167">http://commons.nicovideo.jp/material/nc71167</a></li>
<li>Reimu    <a href="http://commons.nicovideo.jp/material/nc70557">http://commons.nicovideo.jp/material/nc70557</a></li>
<li>Bullet   <a href="http://commons.nicovideo.jp/material/nc74535">http://commons.nicovideo.jp/material/nc74535</a></li>
<li>BG       <a href="http://subtlepatterns.com/hixs-evolution/">http://subtlepatterns.com/hixs-evolution/</a></li>
<li>BG       <a href="http://gi0.net/">http://gi0.net/</a></li>
<li>BG       <a href="http://commons.nicovideo.jp/material/nc21291">http://commons.nicovideo.jp/material/nc21291</a></li>
<li>BGM      <a href="http://commons.nicovideo.jp/material/nc25738">http://commons.nicovideo.jp/material/nc25738</a></li>
<li>BGM      <a href="http://commons.nicovideo.jp/material/nc13447">http://commons.nicovideo.jp/material/nc13447</a></li>
<li>BGM      <a href="http://commons.nicovideo.jp/material/nc22928">http://commons.nicovideo.jp/material/nc22928</a></li>
</ul>

<p>
This game is made by <a href="http://twitter.com/superhoge">@suprehoge</a>
</p>

<p>
<a href="https://github.com/takahirox/toho-like-js">Source code</a>
</p>

</body>
</html>


================================================
FILE: replay/replay1.txt
================================================
{
  user: 'takahirox',
  characterIndex: 0,
  seed: 57914,
  params: [
    {count: 34, z: true},
    {count: 46, l: true},
    {count: 46, z: false},
    {count: 80, u: true},
    {count: 81, l: false},
    {count: 102, l: true},
    {count: 104, u: false},
    {count: 111, l: false},
    {count: 130, z: true},
    {count: 136, r: true},
    {count: 168, l: true},
    {count: 168, r: false},
    {count: 203, z: false},
    {count: 205, u: true},
    {count: 205, l: false},
    {count: 235, r: true},
    {count: 240, u: false},
    {count: 250, r: false},
    {count: 261, r: true},
    {count: 263, r: false},
    {count: 268, r: true},
    {count: 271, r: false},
    {count: 278, r: true},
    {count: 282, r: false},
    {count: 288, r: true},
    {count: 295, d: true},
    {count: 310, d: false},
    {count: 350, z: true},
    {count: 352, l: true},
    {count: 353, r: false},
    {count: 390, r: true},
    {count: 391, l: false},
    {count: 424, u: true},
    {count: 425, z: false},
    {count: 428, r: false},
    {count: 443, l: true},
    {count: 447, u: false},
    {count: 461, l: false},
    {count: 473, l: true},
    {count: 477, l: false},
    {count: 481, l: true},
    {count: 493, l: false},
    {count: 493, d: true},
    {count: 522, l: true},
    {count: 526, d: false},
    {count: 574, z: true},
    {count: 574, r: true},
    {count: 574, l: false},
    {count: 610, l: true},
    {count: 611, r: false},
    {count: 611, z: false},
    {count: 648, u: true},
    {count: 651, l: false},
    {count: 667, r: true},
    {count: 670, u: false},
    {count: 687, r: false},
    {count: 697, r: true},
    {count: 702, r: false},
    {count: 705, r: true},
    {count: 714, d: true},
    {count: 740, d: false},
    {count: 764, z: true},
    {count: 769, r: false},
    {count: 772, l: true},
    {count: 780, s: true},
    {count: 812, s: false},
    {count: 813, r: true},
    {count: 814, l: false},
    {count: 844, u: true},
    {count: 846, r: false},
    {count: 868, l: true},
    {count: 869, u: false},
    {count: 884, l: false},
    {count: 892, l: true},
    {count: 903, d: true},
    {count: 904, l: false},
    {count: 955, l: true},
    {count: 956, d: false},
    {count: 961, s: true},
    {count: 987, s: false},
    {count: 1025, u: true},
    {count: 1026, l: false},
    {count: 1041, r: true},
    {count: 1043, u: false},
    {count: 1055, d: true},
    {count: 1062, d: false},
    {count: 1076, d: true},
    {count: 1090, d: false},
    {count: 1091, l: true},
    {count: 1091, r: false},
    {count: 1137, l: false},
    {count: 1137, u: true},
    {count: 1165, u: false},
    {count: 1166, r: true},
    {count: 1177, d: true},
    {count: 1188, d: false},
    {count: 1191, r: false},
    {count: 1216, l: true},
    {count: 1248, l: false},
    {count: 1254, u: true},
    {count: 1264, u: false},
    {count: 1272, r: true},
    {count: 1277, r: false},
    {count: 1297, r: true},
    {count: 1324, r: false},
    {count: 1329, d: true},
    {count: 1367, d: false},
    {count: 1385, r: true},
    {count: 1399, u: true},
    {count: 1400, r: false},
    {count: 1429, u: false},
    {count: 1439, l: true},
    {count: 1473, l: false},
    {count: 1481, u: true},
    {count: 1538, l: true},
    {count: 1539, u: false},
    {count: 1545, l: false},
    {count: 1549, r: true},
    {count: 1562, d: true},
    {count: 1571, r: false},
    {count: 1633, r: true},
    {count: 1636, d: false},
    {count: 1652, r: false},
    {count: 1660, r: true},
    {count: 1678, u: true},
    {count: 1679, r: false},
    {count: 1693, l: true},
    {count: 1695, u: false},
    {count: 1710, u: true},
    {count: 1712, l: false},
    {count: 1738, r: true},
    {count: 1738, u: false},
    {count: 1742, d: true},
    {count: 1747, r: false},
    {count: 1806, l: true},
    {count: 1807, d: false},
    {count: 1823, r: true},
    {count: 1824, l: false},
    {count: 1848, r: false},
    {count: 1849, l: true},
    {count: 1873, u: true},
    {count: 1874, l: false},
    {count: 1906, r: true},
    {count: 1907, u: false},
    {count: 1916, r: false},
    {count: 1936, r: true},
    {count: 1944, d: true},
    {count: 1960, d: false},
    {count: 1985, r: false},
    {count: 1986, l: true},
    {count: 1999, l: false},
    {count: 2002, l: true},
    {count: 2033, l: false},
    {count: 2035, r: true},
    {count: 2079, u: true},
    {count: 2082, r: false},
    {count: 2095, l: true},
    {count: 2096, u: false},
    {count: 2121, l: false},
    {count: 2130, l: true},
    {count: 2132, l: false},
    {count: 2136, l: true},
    {count: 2152, l: false},
    {count: 2156, r: true},
    {count: 2192, s: true},
    {count: 2199, d: true},
    {count: 2200, r: false},
    {count: 2214, d: false},
    {count: 2272, d: true},
    {count: 2292, d: false},
    {count: 2293, l: true},
    {count: 2335, u: true},
    {count: 2337, l: false},
    {count: 2379, l: true},
    {count: 2380, u: false},
    {count: 2385, l: false},
    {count: 2395, d: true},
    {count: 2428, d: false},
    {count: 2430, l: true},
    {count: 2446, l: false},
    {count: 2451, l: true},
    {count: 2456, l: false},
    {count: 2461, l: true},
    {count: 2465, l: false},
    {count: 2469, l: true},
    {count: 2473, l: false},
    {count: 2475, l: true},
    {count: 2490, u: true},
    {count: 2491, l: false},
    {count: 2511, u: false},
    {count: 2516, l: true},
    {count: 2521, l: false},
    {count: 2539, d: true},
    {count: 2576, d: false},
    {count: 2580, r: true},
    {count: 2602, r: false},
    {count: 2607, r: true},
    {count: 2610, r: false},
    {count: 2620, u: true},
    {count: 2649, u: false},
    {count: 2651, r: true},
    {count: 2677, r: false},
    {count: 2682, d: true},
    {count: 2703, d: false},
    {count: 2708, r: true},
    {count: 2713, r: false},
    {count: 2717, r: true},
    {count: 2720, r: false},
    {count: 2723, r: true},
    {count: 2724, r: false},
    {count: 2728, r: true},
    {count: 2729, r: false},
    {count: 2733, r: true},
    {count: 2735, r: false},
    {count: 2737, r: true},
    {count: 2740, r: false},
    {count: 2744, r: true},
    {count: 2746, r: false},
    {count: 2749, r: true},
    {count: 2752, r: false},
    {count: 2756, r: true},
    {count: 2757, r: false},
    {count: 2760, r: true},
    {count: 2785, s: false},
    {count: 2792, r: false},
    {count: 2799, d: true},
    {count: 2814, l: true},
    {count: 2814, d: false},
    {count: 2831, l: false},
    {count: 2832, u: true},
    {count: 2846, u: false},
    {count: 2847, r: true},
    {count: 2853, d: true},
    {count: 2858, r: false},
    {count: 2864, d: false},
    {count: 2868, l: true},
    {count: 2895, l: false},
    {count: 2896, u: true},
    {count: 2903, u: false},
    {count: 2904, l: true},
    {count: 2959, l: false},
    {count: 2960, r: true},
    {count: 3025, r: false},
    {count: 3025, l: true},
    {count: 3068, d: true},
    {count: 3069, l: false},
    {count: 3076, l: true},
    {count: 3077, d: false},
    {count: 3102, u: true},
    {count: 3104, l: false},
    {count: 3120, u: false},
    {count: 3121, r: true},
    {count: 3130, d: true},
    {count: 3134, r: false},
    {count: 3139, d: false},
    {count: 3176, d: true},
    {count: 3182, d: false},
    {count: 3196, d: true},
    {count: 3201, d: false},
    {count: 3212, r: true},
    {count: 3221, r: false},
    {count: 3241, u: true},
    {count: 3248, u: false},
    {count: 3249, l: true},
    {count: 3276, u: true},
    {count: 3276, l: false},
    {count: 3285, u: false},
    {count: 3298, d: true},
    {count: 3304, d: false},
    {count: 3314, r: true},
    {count: 3319, r: false},
    {count: 3324, r: true},
    {count: 3327, r: false},
    {count: 3331, r: true},
    {count: 3337, r: false},
    {count: 3338, r: true},
    {count: 3344, r: false},
    {count: 3372, d: true},
    {count: 3375, r: true},
    {count: 3376, d: false},
    {count: 3380, r: false},
    {count: 3393, r: true},
    {count: 3397, r: false},
    {count: 3400, r: true},
    {count: 3408, r: false},
    {count: 3422, l: true},
    {count: 3426, l: false},
    {count: 3437, l: true},
    {count: 3440, l: false},
    {count: 3459, r: true},
    {count: 3464, u: true},
    {count: 3468, r: false},
    {count: 3471, l: true},
    {count: 3471, u: false},
    {count: 3477, l: false},
    {count: 3484, l: true},
    {count: 3488, l: false},
    {count: 3493, l: true},
    {count: 3519, l: false},
    {count: 3520, r: true},
    {count: 3540, r: false},
    {count: 3566, r: true},
    {count: 3570, r: false},
    {count: 3576, d: true},
    {count: 3581, d: false},
    {count: 3592, r: true},
    {count: 3604, r: false},
    {count: 3612, l: true},
    {count: 3620, l: false},
    {count: 3621, d: true},
    {count: 3628, d: false},
    {count: 3639, r: true},
    {count: 3645, u: true},
    {count: 3647, r: false},
    {count: 3666, u: false},
    {count: 3667, r: true},
    {count: 3674, r: false},
    {count: 3677, d: true},
    {count: 3684, d: false},
    {count: 3691, l: true},
    {count: 3711, l: false},
    {count: 3724, r: true},
    {count: 3730, r: false},
    {count: 3735, u: true},
    {count: 3742, u: false},
    {count: 3755, l: true},
    {count: 3760, l: false},
    {count: 3783, d: true},
    {count: 3791, d: false},
    {count: 3795, r: true},
    {count: 3809, u: true},
    {count: 3813, r: false},
    {count: 3829, r: true},
    {count: 3831, u: false},
    {count: 3839, d: true},
    {count: 3856, d: false},
    {count: 3867, r: false},
    {count: 3891, z: false},
    {count: 3907, l: true},
    {count: 3912, u: true},
    {count: 3914, l: false},
    {count: 3921, u: false},
    {count: 3987, z: true},
    {count: 4034, z: true},
    {count: 4050, z: true},
    {count: 4066, z: true},
    {count: 4077, l: true},
    {count: 4087, s: true},
    {count: 4097, l: false},
    {count: 4098, d: true},
    {count: 4105, r: true},
    {count: 4106, d: false},
    {count: 4114, d: true},
    {count: 4116, r: false},
    {count: 4121, d: false},
    {count: 4131, l: true},
    {count: 4136, l: false},
    {count: 4147, l: true},
    {count: 4150, l: false},
    {count: 4159, l: true},
    {count: 4163, l: false},
    {count: 4169, l: true},
    {count: 4173, l: false},
    {count: 4176, l: true},
    {count: 4182, l: false},
    {count: 4193, r: true},
    {count: 4217, d: true},
    {count: 4219, r: false},
    {count: 4230, d: false},
    {count: 4285, l: true},
    {count: 4288, l: false},
    {count: 4312, u: true},
    {count: 4316, u: false},
    {count: 4320, l: true},
    {count: 4324, l: false},
    {count: 4329, l: true},
    {count: 4334, l: false},
    {count: 4346, u: true},
    {count: 4349, u: false},
    {count: 4365, u: true},
    {count: 4367, u: false},
    {count: 4372, u: true},
    {count: 4377, u: false},
    {count: 4421, l: true},
    {count: 4427, l: false},
    {count: 4491, r: true},
    {count: 4502, r: false},
    {count: 4575, r: true},
    {count: 4584, r: false},
    {count: 4597, d: true},
    {count: 4603, d: false},
    {count: 4605, r: true},
    {count: 4617, d: true},
    {count: 4623, r: false},
    {count: 4627, d: false},
    {count: 4666, l: true},
    {count: 4674, l: false},
    {count: 4707, s: false},
    {count: 4709, l: true},
    {count: 4720, l: false},
    {count: 4721, u: true},
    {count: 4757, s: true},
    {count: 4765, u: false},
    {count: 4774, d: true},
    {count: 4828, d: false},
    {count: 4831, l: true},
    {count: 4837, l: false},
    {count: 4859, r: true},
    {count: 4865, r: false},
    {count: 5126, r: true},
    {count: 5142, d: true},
    {count: 5149, d: false},
    {count: 5155, r: false},
    {count: 5163, r: true},
    {count: 5171, r: false},
    {count: 5185, r: true},
    {count: 5189, r: false},
    {count: 5208, r: true},
    {count: 5215, r: false},
    {count: 5225, r: true},
    {count: 5239, r: false},
    {count: 5268, d: true},
    {count: 5284, r: true},
    {count: 5285, d: false},
    {count: 5290, r: false},
    {count: 5305, l: true},
    {count: 5317, l: false},
    {count: 5325, d: true},
    {count: 5334, d: false},
    {count: 5336, l: true},
    {count: 5341, l: false},
    {count: 5353, l: true},
    {count: 5358, l: false},
    {count: 5387, l: true},
    {count: 5392, l: false},
    {count: 5410, r: true},
    {count: 5420, r: false},
    {count: 5433, l: true},
    {count: 5443, l: false},
    {count: 5450, l: true},
    {count: 5453, l: false},
    {count: 5466, r: true},
    {count: 5474, r: false},
    {count: 5482, u: true},
    {count: 5490, u: false},
    {count: 5492, l: true},
    {count: 5500, l: false},
    {count: 5515, r: true},
    {count: 5519, r: false},
    {count: 5543, l: true},
    {count: 5548, l: false},
    {count: 5564, r: true},
    {count: 5573, r: false},
    {count: 5582, l: true},
    {count: 5598, l: false},
    {count: 5628, d: true},
    {count: 5635, d: false},
    {count: 5637, r: true},
    {count: 5643, r: false},
    {count: 5674, r: true},
    {count: 5679, r: false},
    {count: 5692, r: true},
    {count: 5699, r: false},
    {count: 5710, r: true},
    {count: 5712, r: false},
    {count: 5725, r: true},
    {count: 5729, r: false},
    {count: 5747, s: false},
    {count: 5749, u: true},
    {count: 5821, s: true},
    {count: 5823, u: false},
    {count: 5826, r: true},
    {count: 5831, r: false},
    {count: 5856, l: true},
    {count: 5860, l: false},
    {count: 5874, d: true},
    {count: 5885, d: false},
    {count: 5900, d: true},
    {count: 5906, d: false},
    {count: 5930, r: true},
    {count: 5934, r: false},
    {count: 5959, l: true},
    {count: 5963, l: false},
    {count: 5997, l: true},
    {count: 5999, u: true},
    {count: 6000, l: false},
    {count: 6014, u: false},
    {count: 6018, r: true},
    {count: 6021, r: false},
    {count: 6050, r: true},
    {count: 6055, r: false},
    {count: 6058, u: true},
    {count: 6075, l: true},
    {count: 6075, u: false},
    {count: 6080, u: true},
    {count: 6080, l: false},
    {count: 6084, u: false},
    {count: 6086, r: true},
    {count: 6093, r: false},
    {count: 6115, l: true},
    {count: 6123, l: false},
    {count: 6128, u: true},
    {count: 6132, u: false},
    {count: 6144, l: true},
    {count: 6147, l: false},
    {count: 6163, r: true},
    {count: 6166, r: false},
    {count: 6175, u: true},
    {count: 6179, u: false},
    {count: 6184, r: true},
    {count: 6187, r: false},
    {count: 6200, r: true},
    {count: 6203, r: false},
    {count: 6209, l: true},
    {count: 6211, l: false},
    {count: 6215, l: true},
    {count: 6219, l: false},
    {count: 6224, r: true},
    {count: 6231, r: false},
    {count: 6235, l: true},
    {count: 6244, l: false},
    {count: 6258, u: true},
    {count: 6261, u: false},
    {count: 6264, r: true},
    {count: 6268, r: false},
  ]
}

================================================
FILE: replay/replay2.txt
================================================
{
  user: 'takahirox',
  characterIndex: 1,
  seed: 11249,
  params: [
    {count: 26, d: true},
    {count: 33, d: false},
    {count: 40, z: true},
    {count: 46, l: true},
    {count: 91, r: true},
    {count: 92, l: false},
    {count: 131, r: false},
    {count: 131, l: true},
    {count: 163, l: false},
    {count: 164, r: true},
    {count: 194, l: true},
    {count: 194, r: false},
    {count: 224, l: false},
    {count: 225, u: true},
    {count: 243, u: false},
    {count: 244, r: true},
    {count: 249, z: false},
    {count: 253, r: false},
    {count: 272, r: true},
    {count: 277, r: false},
    {count: 314, r: true},
    {count: 319, r: false},
    {count: 330, r: true},
    {count: 380, l: true},
    {count: 381, r: false},
    {count: 382, z: true},
    {count: 412, r: true},
    {count: 412, l: false},
    {count: 439, z: false},
    {count: 440, u: true},
    {count: 441, r: false},
    {count: 470, l: true},
    {count: 473, u: false},
    {count: 480, l: false},
    {count: 490, l: true},
    {count: 495, l: false},
    {count: 501, l: true},
    {count: 506, l: false},
    {count: 513, l: true},
    {count: 516, l: false},
    {count: 519, d: true},
    {count: 547, l: true},
    {count: 549, d: false},
    {count: 588, z: true},
    {count: 594, r: true},
    {count: 595, l: false},
    {count: 626, l: true},
    {count: 626, r: false},
    {count: 650, u: true},
    {count: 651, l: false},
    {count: 653, z: false},
    {count: 682, r: true},
    {count: 683, u: false},
    {count: 693, r: false},
    {count: 701, r: true},
    {count: 706, r: false},
    {count: 718, r: true},
    {count: 724, d: true},
    {count: 765, l: true},
    {count: 766, z: true},
    {count: 766, d: false},
    {count: 767, r: false},
    {count: 793, r: true},
    {count: 794, l: false},
    {count: 825, u: true},
    {count: 826, r: false},
    {count: 829, z: false},
    {count: 865, l: true},
    {count: 867, u: false},
    {count: 880, l: false},
    {count: 887, l: true},
    {count: 892, l: false},
    {count: 902, d: true},
    {count: 911, z: true},
    {count: 939, s: true},
    {count: 945, l: true},
    {count: 946, d: false},
    {count: 990, d: true},
    {count: 991, l: false},
    {count: 1002, l: true},
    {count: 1002, d: false},
    {count: 1032, u: true},
    {count: 1032, l: false},
    {count: 1052, r: true},
    {count: 1052, u: false},
    {count: 1076, d: true},
    {count: 1079, r: false},
    {count: 1088, d: false},
    {count: 1114, l: true},
    {count: 1138, u: true},
    {count: 1140, l: false},
    {count: 1161, u: false},
    {count: 1172, r: true},
    {count: 1181, d: true},
    {count: 1185, r: false},
    {count: 1196, d: false},
    {count: 1200, d: true},
    {count: 1210, r: true},
    {count: 1212, d: false},
    {count: 1215, d: true},
    {count: 1217, r: false},
    {count: 1223, r: true},
    {count: 1224, d: false},
    {count: 1234, r: false},
    {count: 1249, r: true},
    {count: 1256, r: false},
    {count: 1259, u: true},
    {count: 1263, l: true},
    {count: 1264, u: false},
    {count: 1302, r: true},
    {count: 1302, s: false},
    {count: 1303, l: false},
    {count: 1327, r: false},
    {count: 1378, r: true},
    {count: 1388, r: false},
    {count: 1466, l: true},
    {count: 1493, l: false},
    {count: 1523, u: true},
    {count: 1571, u: false},
    {count: 1575, r: true},
    {count: 1582, d: true},
    {count: 1592, d: false},
    {count: 1594, r: false},
    {count: 1600, d: true},
    {count: 1605, r: true},
    {count: 1610, r: false},
    {count: 1627, d: false},
    {count: 1684, u: true},
    {count: 1726, u: false},
    {count: 1732, d: true},
    {count: 1781, l: true},
    {count: 1782, d: false},
    {count: 1793, l: false},
    {count: 1793, r: true},
    {count: 1827, l: true},
    {count: 1828, r: false},
    {count: 1862, u: true},
    {count: 1864, l: false},
    {count: 1882, u: false},
    {count: 1883, r: true},
    {count: 1901, r: false},
    {count: 1918, r: true},
    {count: 1922, r: false},
    {count: 1932, r: true},
    {count: 1936, r: false},
    {count: 1944, r: true},
    {count: 1956, d: true},
    {count: 1970, s: true},
    {count: 1976, d: false},
    {count: 1977, r: false},
    {count: 1978, l: true},
    {count: 2012, r: true},
    {count: 2012, s: false},
    {count: 2013, l: false},
    {count: 2050, r: false},
    {count: 2050, u: true},
    {count: 2069, l: true},
    {count: 2070, u: false},
    {count: 2091, l: false},
    {count: 2097, l: true},
    {count: 2101, l: false},
    {count: 2105, l: true},
    {count: 2110, l: false},
    {count: 2115, l: true},
    {count: 2121, l: false},
    {count: 2123, l: true},
    {count: 2128, l: false},
    {count: 2131, r: true},
    {count: 2153, s: true},
    {count: 2156, d: true},
    {count: 2158, r: false},
    {count: 2186, d: false},
    {count: 2192, r: true},
    {count: 2196, r: false},
    {count: 2207, r: true},
    {count: 2212, r: false},
    {count: 2217, r: true},
    {count: 2221, r: false},
    {count: 2226, r: true},
    {count: 2230, r: false},
    {count: 2242, d: true},
    {count: 2247, d: false},
    {count: 2261, l: true},
    {count: 2265, l: false},
    {count: 2270, l: true},
    {count: 2273, l: false},
    {count: 2279, l: true},
    {count: 2283, l: false},
    {count: 2286, l: true},
    {count: 2315, l: false},
    {count: 2317, u: true},
    {count: 2322, u: false},
    {count: 2345, u: true},
    {count: 2348, u: false},
    {count: 2353, u: true},
    {count: 2355, u: false},
    {count: 2359, u: true},
    {count: 2363, u: false},
    {count: 2367, l: true},
    {count: 2371, l: false},
    {count: 2375, l: true},
    {count: 2379, l: false},
    {count: 2406, d: true},
    {count: 2413, d: false},
    {count: 2440, l: true},
    {count: 2442, l: false},
    {count: 2447, l: true},
    {count: 2473, l: false},
    {count: 2475, u: true},
    {count: 2477, s: false},
    {count: 2503, u: false},
    {count: 2504, s: true},
    {count: 2513, d: true},
    {count: 2542, l: true},
    {count: 2543, d: false},
    {count: 2548, d: true},
    {count: 2549, l: false},
    {count: 2557, r: true},
    {count: 2559, d: false},
    {count: 2563, r: false},
    {count: 2576, r: true},
    {count: 2580, r: false},
    {count: 2584, r: true},
    {count: 2588, r: false},
    {count: 2601, r: true},
    {count: 2606, r: false},
    {count: 2610, r: true},
    {count: 2613, r: false},
    {count: 2624, u: true},
    {count: 2624, s: false},
    {count: 2647, u: false},
    {count: 2647, r: true},
    {count: 2659, s: true},
    {count: 2665, d: true},
    {count: 2666, r: false},
    {count: 2679, d: false},
    {count: 2706, d: true},
    {count: 2712, d: false},
    {count: 2716, r: true},
    {count: 2744, r: false},
    {count: 2753, d: true},
    {count: 2758, d: false},
    {count: 2765, r: true},
    {count: 2770, r: false},
    {count: 2772, d: true},
    {count: 2784, d: false},
    {count: 2818, l: true},
    {count: 2821, l: false},
    {count: 2840, r: true},
    {count: 2843, r: false},
    {count: 2880, l: true},
    {count: 2915, l: false},
    {count: 2919, u: true},
    {count: 2960, u: false},
    {count: 2968, d: true},
    {count: 2993, d: false},
    {count: 3007, l: true},
    {count: 3024, l: false},
    {count: 3062, l: true},
    {count: 3066, l: false},
    {count: 3074, l: true},
    {count: 3078, l: false},
    {count: 3082, l: true},
    {count: 3099, l: false},
    {count: 3105, s: false},
    {count: 3108, r: true},
    {count: 3149, r: false},
    {count: 3150, l: true},
    {count: 3205, r: true},
    {count: 3206, l: false},
    {count: 3235, d: true},
    {count: 3238, r: false},
    {count: 3249, l: true},
    {count: 3250, d: false},
    {count: 3279, u: true},
    {count: 3280, l: false},
    {count: 3308, r: true},
    {count: 3308, u: false},
    {count: 3327, d: true},
    {count: 3331, r: false},
    {count: 3341, l: true},
    {count: 3342, d: false},
    {count: 3366, r: true},
    {count: 3368, l: false},
    {count: 3378, d: true},
    {count: 3390, d: false},
    {count: 3399, r: false},
    {count: 3412, l: true},
    {count: 3416, l: false},
    {count: 3457, l: true},
    {count: 3475, l: false},
    {count: 3478, u: true},
    {count: 3485, u: false},
    {count: 3492, l: true},
    {count: 3497, l: false},
    {count: 3505, u: true},
    {count: 3511, u: false},
    {count: 3525, d: true},
    {count: 3534, d: false},
    {count: 3539, r: true},
    {count: 3548, r: false},
    {count: 3595, r: true},
    {count: 3607, d: true},
    {count: 3608, r: false},
    {count: 3614, d: false},
    {count: 3629, r: true},
    {count: 3634, r: false},
    {count: 3641, l: true},
    {count: 3653, l: false},
    {count: 3659, r: true},
    {count: 3667, r: false},
    {count: 3670, u: true},
    {count: 3686, u: false},
    {count: 3696, d: true},
    {count: 3703, d: false},
    {count: 3718, l: true},
    {count: 3743, l: false},
    {count: 3745, r: true},
    {count: 3753, r: false},
    {count: 3762, r: true},
    {count: 3766, r: false},
    {count: 3793, r: true},
    {count: 3804, r: false},
    {count: 3810, d: true},
    {count: 3816, d: false},
    {count: 3842, r: true},
    {count: 3848, r: false},
    {count: 3861, u: true},
    {count: 3879, u: false},
    {count: 3891, d: true},
    {count: 3903, d: false},
    {count: 3920, l: true},
    {count: 3924, l: false},
    {count: 3961, u: true},
    {count: 3970, u: false},
    {count: 3973, l: true},
    {count: 3979, l: false},
    {count: 3991, r: true},
    {count: 3998, r: false},
    {count: 4002, r: true},
    {count: 4012, r: false},
    {count: 4037, u: true},
    {count: 4050, u: false},
    {count: 4050, r: true},
    {count: 4069, d: true},
    {count: 4091, l: true},
    {count: 4092, r: false},
    {count: 4092, d: false},
    {count: 4122, z: false},
    {count: 4128, l: false},
    {count: 4147, r: true},
    {count: 4163, r: false},
    {count: 4213, z: true},
    {count: 4236, z: true},
    {count: 4250, z: true},
    {count: 4270, z: true},
    {count: 4282, l: true},
    {count: 4292, s: true},
    {count: 4295, l: false},
    {count: 4302, r: true},
    {count: 4310, r: false},
    {count: 4321, d: true},
    {count: 4328, d: false},
    {count: 4330, r: true},
    {count: 4335, r: false},
    {count: 4357, r: true},
    {count: 4361, r: false},
    {count: 4381, l: true},
    {count: 4387, l: false},
    {count: 4392, l: true},
    {count: 4394, l: false},
    {count: 4414, r: true},
    {count: 4419, r: false},
    {count: 4442, d: true},
    {count: 4448, d: false},
    {count: 4458, u: true},
    {count: 4463, u: false},
    {count: 4495, l: true},
    {count: 4499, l: false},
    {count: 4514, l: true},
    {count: 4516, l: false},
    {count: 4529, u: true},
    {count: 4532, u: false},
    {count: 4540, l: true},
    {count: 4544, l: false},
    {count: 4596, l: true},
    {count: 4597, l: false},
    {count: 4623, l: true},
    {count: 4626, l: false},
    {count: 4694, r: true},
    {count: 4697, r: false},
    {count: 4702, r: true},
    {count: 4705, r: false},
    {count: 4710, r: true},
    {count: 4713, r: false},
    {count: 4715, r: true},
    {count: 4719, r: false},
    {count: 4739, l: true},
    {count: 4741, l: false},
    {count: 4747, l: true},
    {count: 4752, l: false},
    {count: 4774, r: true},
    {count: 4778, r: false},
    {count: 4795, r: true},
    {count: 4798, r: false},
    {count: 4831, d: true},
    {count: 4836, d: false},
    {count: 4847, r: true},
    {count: 4849, r: false},
    {count: 4874, l: true},
    {count: 4878, l: false},
    {count: 4909, l: true},
    {count: 4913, l: false},
    {count: 4925, u: true},
    {count: 4928, u: false},
    {count: 4932, u: true},
    {count: 4936, u: false},
    {count: 4941, u: true},
    {count: 4945, u: false},
    {count: 4961, l: true},
    {count: 4963, l: false},
    {count: 5000, d: true},
    {count: 5002, d: false},
    {count: 5013, l: true},
    {count: 5016, l: false},
    {count: 5032, r: true},
    {count: 5034, r: false},
    {count: 5051, l: true},
    {count: 5055, l: false},
    {count: 5075, r: true},
    {count: 5077, r: false},
    {count: 5094, l: true},
    {count: 5097, l: false},
    {count: 5137, l: true},
    {count: 5147, l: false},
    {count: 5157, r: true},
    {count: 5171, r: false},
    {count: 5179, l: true},
    {count: 5185, l: false},
    {count: 5205, r: true},
    {count: 5208, r: false},
    {count: 5239, l: true},
    {count: 5245, l: false},
    {count: 5264, r: true},
    {count: 5266, r: false},
    {count: 5295, l: true},
    {count: 5299, l: false},
    {count: 5314, r: true},
    {count: 5318, r: false},
    {count: 5346, l: true},
    {count: 5350, l: false},
    {count: 5361, r: true},
    {count: 5369, r: false},
    {count: 5383, l: true},
    {count: 5390, l: false},
    {count: 5413, r: true},
    {count: 5421, d: true},
    {count: 5421, r: false},
    {count: 5430, d: false},
    {count: 5481, r: true},
    {count: 5488, r: false},
    {count: 5511, l: true},
    {count: 5516, l: false},
    {count: 5528, r: true},
    {count: 5536, r: false},
    {count: 5548, l: true},
    {count: 5556, l: false},
    {count: 5578, l: true},
    {count: 5587, l: false},
    {count: 5608, l: true},
    {count: 5614, l: false},
    {count: 5628, r: true},
    {count: 5632, r: false},
    {count: 5638, r: true},
    {count: 5643, r: false},
    {count: 5651, l: true},
    {count: 5657, l: false},
    {count: 5663, l: true},
    {count: 5665, l: false},
    {count: 5669, u: true},
    {count: 5675, u: false},
    {count: 5691, d: true},
    {count: 5696, d: false},
    {count: 5706, r: true},
    {count: 5710, r: false},
    {count: 5740, l: true},
    {count: 5749, l: false},
    {count: 5760, r: true},
    {count: 5767, r: false},
    {count: 5794, l: true},
    {count: 5803, l: false},
    {count: 5818, r: true},
    {count: 5828, r: false},
    {count: 5846, l: true},
    {count: 5852, l: false},
    {count: 5874, r: true},
    {count: 5882, r: false},
    {count: 5894, l: true},
    {count: 5905, l: false},
    {count: 5961, r: true},
    {count: 5966, r: false},
    {count: 5981, l: true},
    {count: 5991, l: false},
    {count: 6003, r: true},
    {count: 6010, r: false},
    {count: 6029, l: true},
    {count: 6036, l: false},
    {count: 6051, r: true},
    {count: 6057, r: false},
    {count: 6080, l: true},
    {count: 6086, l: false},
    {count: 6102, r: true},
    {count: 6108, r: false},
    {count: 6127, r: true},
    {count: 6135, r: false},
    {count: 6165, u: true},
    {count: 6169, u: false},
    {count: 6173, r: true},
    {count: 6182, r: false},
    {count: 6203, d: true},
    {count: 6207, d: false},
    {count: 6214, r: true},
    {count: 6219, r: false},
    {count: 6242, l: true},
    {count: 6242, s: false},
    {count: 6247, u: true},
    {count: 6247, l: false},
    {count: 6280, s: true},
    {count: 6281, u: false},
    {count: 6289, d: true},
    {count: 6295, d: false},
    {count: 6316, d: true},
    {count: 6320, d: false},
    {count: 6326, d: true},
    {count: 6330, d: false},
    {count: 6334, d: true},
    {count: 6339, d: false},
    {count: 6395, d: true},
    {count: 6400, d: false},
    {count: 6461, l: true},
    {count: 6464, l: false},
    {count: 6481, l: true},
    {count: 6484, l: false},
    {count: 6493, r: true},
    {count: 6496, r: false},
    {count: 6500, d: true},
    {count: 6503, d: false},
    {count: 6588, d: true},
    {count: 6593, d: false},
    {count: 6599, l: true},
    {count: 6602, l: false},
    {count: 6645, l: true},
    {count: 6649, l: false},
    {count: 6663, r: true},
    {count: 6667, r: false},
    {count: 6725, r: true},
    {count: 6729, r: false},
    {count: 6738, r: true},
    {count: 6741, r: false},
    {count: 6754, r: true},
    {count: 6759, r: false},
    {count: 6770, l: true},
    {count: 6785, l: false},
    {count: 6810, l: true},
    {count: 6812, l: false},
    {count: 6819, r: true},
    {count: 6826, r: false},
    {count: 6838, u: true},
    {count: 6841, u: false},
    {count: 6844, r: true},
    {count: 6849, r: false},
    {count: 6865, d: true},
    {count: 6870, d: false},
    {count: 6874, r: true},
    {count: 6878, r: false},
    {count: 6894, r: true},
    {count: 6897, r: false},
    {count: 6918, u: true},
    {count: 6924, u: false},
    {count: 6926, l: true},
    {count: 6932, l: false},
    {count: 6992, l: true},
    {count: 6997, l: false},
    {count: 7058, r: true},
    {count: 7064, r: false},
    {count: 7067, r: true},
    {count: 7070, r: false},
    {count: 7090, l: true},
    {count: 7095, l: false},
    {count: 7123, l: true},
    {count: 7127, l: false},
    {count: 7157, r: true},
    {count: 7161, r: false},
    {count: 7180, l: true},
    {count: 7190, l: false},
    {count: 7218, d: true},
    {count: 7220, d: false},
    {count: 7240, l: true},
    {count: 7243, l: false},
    {count: 7283, u: true},
    {count: 7289, u: false},
    {count: 7295, r: true},
    {count: 7303, d: true},
    {count: 7305, r: false},
    {count: 7311, d: false},
    {count: 7314, r: true},
    {count: 7321, r: false},
    {count: 7345, r: true},
    {count: 7348, r: false},
    {count: 7363, u: true},
    {count: 7370, u: false},
    {count: 7371, l: true},
    {count: 7379, l: false},
    {count: 7424, d: true},
    {count: 7427, d: false},
    {count: 7431, l: true},
    {count: 7435, l: false},
    {count: 7471, l: true},
    {count: 7474, l: false},
    {count: 7477, l: true},
    {count: 7482, l: false},
    {count: 7501, r: true},
    {count: 7510, s: false},
    {count: 7511, r: false},
    {count: 7512, z: false},
    {count: 7513, u: true},
    {count: 7531, u: false},
    {count: 7566, r: true},
    {count: 7583, r: false},
    {count: 7635, z: true},
    {count: 7698, z: true},
    {count: 7716, z: true},
    {count: 7720, d: true},
    {count: 7734, d: false},
    {count: 7734, l: true},
    {count: 7789, r: true},
    {count: 7790, l: false},
    {count: 7835, l: true},
    {count: 7835, r: false},
    {count: 7880, r: true},
    {count: 7881, l: false},
    {count: 7910, r: false},
    {count: 7915, l: true},
    {count: 7923, l: false},
    {count: 7939, l: true},
    {count: 7950, l: false},
    {count: 7953, r: true},
    {count: 7961, d: true},
    {count: 7964, r: false},
    {count: 7968, l: true},
    {count: 7969, d: false},
    {count: 7985, l: false},
    {count: 7990, d: true},
    {count: 7996, d: false},
    {count: 8005, r: true},
    {count: 8022, r: false},
    {count: 8041, u: true},
    {count: 8051, u: false},
    {count: 8056, x: true},
    {count: 8070, u: true},
    {count: 8088, u: false},
    {count: 8089, r: true},
    {count: 8095, d: true},
    {count: 8097, r: false},
    {count: 8110, l: true},
    {count: 8110, d: false},
    {count: 8132, l: false},
    {count: 8135, r: true},
    {count: 8182, l: true},
    {count: 8182, r: false},
    {count: 8238, r: true},
    {count: 8239, l: false},
    {count: 8280, r: false},
    {count: 8281, l: true},
    {count: 8303, l: false},
    {count: 8309, r: true},
    {count: 8322, r: false},
    {count: 8328, x: true},
    {count: 8337, u: true},
    {count: 8362, u: false},
    {count: 8413, d: true},
    {count: 8441, d: false},
    {count: 8441, l: true},
    {count: 8471, r: true},
    {count: 8471, l: false},
    {count: 8528, r: false},
    {count: 8536, u: true},
    {count: 8596, l: true},
    {count: 8597, u: false},
    {count: 8609, d: true},
    {count: 8610, l: false},
    {count: 8660, s: true},
    {count: 8672, l: true},
    {count: 8672, d: false},
    {count: 8727, u: true},
    {count: 8728, l: false},
    {count: 8749, r: true},
    {count: 8750, u: false},
    {count: 8759, d: true},
    {count: 8766, r: false},
    {count: 8768, r: true},
    {count: 8781, d: false},
    {count: 8783, r: false},
    {count: 8785, d: true},
    {count: 8791, d: false},
    {count: 8795, l: true},
    {count: 8826, u: true},
    {count: 8827, l: false},
    {count: 8858, r: true},
    {count: 8859, u: false},
    {count: 8876, d: true},
    {count: 8877, r: false},
    {count: 8885, d: false},
    {count: 8893, d: true},
    {count: 8902, d: false},
    {count: 8907, l: true},
    {count: 8916, l: false},
    {count: 8929, u: true},
    {count: 8935, u: false},
    {count: 8943, d: true},
    {count: 8955, l: true},
    {count: 8955, d: false},
    {count: 8972, l: false},
    {count: 8985, d: true},
    {count: 8991, r: true},
    {count: 8992, d: false},
    {count: 9023, r: false},
    {count: 9054, r: true},
    {count: 9062, d: true},
    {count: 9063, r: false},
    {count: 9070, d: false},
    {count: 9085, r: true},
    {count: 9091, r: false},
    {count: 9098, u: true},
    {count: 9133, u: false},
    {count: 9135, l: true},
    {count: 9161, l: false},
    {count: 9166, d: true},
    {count: 9174, l: true},
    {count: 9175, d: false},
    {count: 9191, l: false},
    {count: 9195, u: true},
    {count: 9248, u: false},
    {count: 9251, r: true},
    {count: 9251, s: false},
    {count: 9258, r: false},
    {count: 9271, r: true},
    {count: 9278, d: true},
    {count: 9283, r: false},
    {count: 9326, r: true},
    {count: 9331, d: false},
    {count: 9337, r: false},
    {count: 9354, u: true},
    {count: 9371, u: false},
    {count: 9380, u: true},
    {count: 9416, u: false},
    {count: 9421, d: true},
    {count: 9475, l: true},
    {count: 9476, d: false},
    {count: 9490, r: true},
    {count: 9491, l: false},
    {count: 9526, l: true},
    {count: 9527, r: false},
    {count: 9557, u: true},
    {count: 9558, l: false},
    {count: 9573, u: false},
    {count: 9575, l: true},
    {count: 9584, l: false},
    {count: 9587, r: true},
    {count: 9615, r: false},
    {count: 9639, r: true},
    {count: 9647, d: true},
    {count: 9650, s: true},
    {count: 9675, d: false},
    {count: 9679, l: true},
    {count: 9679, r: false},
    {count: 9686, s: false},
    {count: 9718, r: true},
    {count: 9718, l: false},
    {count: 9757, u: true},
    {count: 9759, r: false},
    {count: 9779, l: true},
    {count: 9781, u: false},
    {count: 9802, l: false},
    {count: 9816, l: true},
    {count: 9819, l: false},
    {count: 9824, l: true},
    {count: 9828, l: false},
    {count: 9838, s: true},
    {count: 9851, l: true},
    {count: 9856, l: false},
    {count: 9861, d: true},
    {count: 9866, d: false},
    {count: 9875, r: true},
    {count: 9880, r: false},
    {count: 9883, d: true},
    {count: 9888, d: false},
    {count: 9897, l: true},
    {count: 9901, l: false},
    {count: 9910, d: true},
    {count: 9913, d: false},
    {count: 9937, d: true},
    {count: 9940, d: false},
    {count: 9983, r: true},
    {count: 9986, r: false},
    {count: 9997, d: true},
    {count: 9999, d: false},
    {count: 10004, d: true},
    {count: 10009, d: false},
    {count: 10031, d: true},
    {count: 10035, d: false},
    {count: 10039, d: true},
    {count: 10041, d: false},
    {count: 10048, r: true},
    {count: 10051, r: false},
    {count: 10066, u: true},
    {count: 10069, u: false},
    {count: 10073, u: true},
    {count: 10075, u: false},
    {count: 10081, u: true},
    {count: 10084, u: false},
    {count: 10089, u: true},
    {count: 10104, l: true},
    {count: 10105, u: false},
    {count: 10144, d: true},
    {count: 10145, l: false},
    {count: 10157, d: false},
    {count: 10159, l: true},
    {count: 10165, l: false},
    {count: 10210, u: true},
    {count: 10226, u: false},
    {count: 10229, r: true},
    {count: 10230, s: false},
    {count: 10238, r: false},
    {count: 10246, r: true},
    {count: 10268, r: false},
    {count: 10276, s: true},
    {count: 10282, d: true},
    {count: 10286, d: false},
    {count: 10288, r: true},
    {count: 10293, r: false},
    {count: 10296, d: true},
    {count: 10299, r: true},
    {count: 10300, d: false},
    {count: 10303, r: false},
    {count: 10316, d: true},
    {count: 10320, d: false},
    {count: 10324, d: true},
    {count: 10327, d: false},
    {count: 10335, l: true},
    {count: 10338, l: false},
    {count: 10341, l: true},
    {count: 10343, l: false},
    {count: 10357, u: true},
    {count: 10376, u: false},
    {count: 10412, s: false},
    {count: 10423, l: true},
    {count: 10428, l: false},
    {count: 10428, s: true},
    {count: 10432, d: true},
    {count: 10438, d: false},
    {count: 10453, l: true},
    {count: 10455, l: false},
    {count: 10458, d: true},
    {count: 10467, d: false},
    {count: 10469, r: true},
    {count: 10473, r: false},
    {count: 10491, u: true},
    {count: 10493, u: false},
    {count: 10496, u: true},
    {count: 10499, u: false},
    {count: 10501, u: true},
    {count: 10505, u: false},
    {count: 10508, u: true},
    {count: 10511, u: false},
    {count: 10515, u: true},
    {count: 10518, u: false},
    {count: 10521, u: true},
    {count: 10525, u: false},
    {count: 10551, d: true},
    {count: 10565, d: false},
    {count: 10569, l: true},
    {count: 10588, d: true},
    {count: 10588, l: false},
    {count: 10597, d: false},
    {count: 10607, d: true},
    {count: 10611, d: false},
    {count: 10625, r: true},
    {count: 10627, r: false},
    {count: 10643, r: true},
    {count: 10645, r: false},
    {count: 10663, l: true},
    {count: 10666, l: false},
    {count: 10683, u: true},
    {count: 10695, u: false},
    {count: 10701, s: false},
    {count: 10701, r: true},
    {count: 10725, d: true},
    {count: 10728, s: true},
    {count: 10728, r: false},
    {count: 10741, d: false},
    {count: 10742, l: true},
    {count: 10754, l: false},
    {count: 10766, r: true},
    {count: 10770, r: false},
    {count: 10774, r: true},
    {count: 10777, r: false},
    {count: 10780, r: true},
    {count: 10782, r: false},
    {count: 10799, r: true},
    {count: 10802, r: false},
    {count: 10810, u: true},
    {count: 10829, u: false},
    {count: 10861, l: true},
    {count: 10885, l: false},
    {count: 10916, d: true},
    {count: 10920, d: false},
    {count: 10942, r: true},
    {count: 10945, r: false},
    {count: 10948, r: true},
    {count: 10951, r: false},
    {count: 11007, s: false},
    {count: 11035, d: true},
    {count: 11046, d: false},
    {count: 11047, l: true},
    {count: 11093, l: false},
    {count: 11093, r: true},
    {count: 11144, l: true},
    {count: 11145, r: false},
    {count: 11190, u: true},
    {count: 11191, l: false},
    {count: 11211, u: false},
    {count: 11251, r: true},
    {count: 11263, r: false},
    {count: 11285, u: true},
    {count: 11291, u: false},
    {count: 11293, r: true},
    {count: 11299, r: false},
    {count: 11318, d: true},
    {count: 11326, d: false},
    {count: 11334, l: true},
    {count: 11345, l: false},
    {count: 11350, d: true},
    {count: 11357, d: false},
    {count: 11359, l: true},
    {count: 11364, l: false},
    {count: 11388, d: true},
    {count: 11393, d: false},
    {count: 11397, d: true},
    {count: 11401, d: false},
    {count: 11415, d: true},
    {count: 11420, d: false},
    {count: 11451, r: true},
    {count: 11464, r: false},
    {count: 11480, d: true},
    {count: 11485, r: true},
    {count: 11486, d: false},
    {count: 11491, r: false},
    {count: 11521, r: true},
    {count: 11526, r: false},
    {count: 11547, l: true},
    {count: 11552, l: false},
    {count: 11560, r: true},
    {count: 11565, r: false},
    {count: 11568, u: true},
    {count: 11583, u: false},
    {count: 11598, d: true},
    {count: 11604, d: false},
    {count: 11613, l: true},
    {count: 11633, l: false},
    {count: 11634, d: true},
    {count: 11640, d: false},
    {count: 11644, l: true},
    {count: 11651, l: false},
    {count: 11659, r: true},
    {count: 11672, r: false},
    {count: 11694, r: true},
    {count: 11702, r: false},
    {count: 11719, d: true},
    {count: 11724, d: false},
    {count: 11735, r: true},
    {count: 11741, r: false},
    {count: 11745, r: true},
    {count: 11747, r: false},
    {count: 11755, u: true},
    {count: 11775, u: false},
    {count: 11792, d: true},
    {count: 11797, d: false},
    {count: 11815, l: true},
    {count: 11828, l: false},
    {count: 11829, l: true},
    {count: 11837, d: true},
    {count: 11837, l: false},
    {count: 11845, l: true},
    {count: 11846, d: false},
    {count: 11858, l: false},
    {count: 11862, r: true},
    {count: 11886, r: false},
    {count: 11901, r: true},
    {count: 11916, r: false},
    {count: 11931, u: true},
    {count: 11954, u: false},
    {count: 11955, r: true},
    {count: 11978, d: true},
    {count: 11982, r: false},
    {count: 11995, l: true},
    {count: 11996, d: false},
    {count: 12016, l: false},
    {count: 12017, z: false},
    {count: 12021, r: true},
    {count: 12039, r: false},
    {count: 12042, u: true},
    {count: 12059, u: false},
    {count: 12122, z: true},
    {count: 12143, z: true},
    {count: 12166, z: true},
    {count: 12173, l: true},
    {count: 12182, s: true},
    {count: 12188, l: false},
    {count: 12190, d: true},
    {count: 12197, d: false},
    {count: 12202, l: true},
    {count: 12203, l: false},
    {count: 12244, d: true},
    {count: 12246, d: false},
    {count: 12251, d: true},
    {count: 12253, d: false},
    {count: 12260, l: true},
    {count: 12263, l: false},
    {count: 12273, d: true},
    {count: 12277, d: false},
    {count: 12279, r: true},
    {count: 12281, r: false},
    {count: 13182, s: false},
    {count: 13190, r: true},
    {count: 13203, r: false},
    {count: 13207, l: true},
    {count: 13233, s: true},
    {count: 13237, l: false},
    {count: 13239, r: true},
    {count: 13262, l: true},
    {count: 13262, r: false},
    {count: 13278, r: true},
    {count: 13279, l: false},
    {count: 13301, r: false},
    {count: 13312, l: true},
    {count: 13320, l: false},
    {count: 13325, d: true},
    {count: 13344, d: false},
    {count: 13360, l: true},
    {count: 13381, u: true},
    {count: 13382, l: false},
    {count: 13386, s: false},
    {count: 13398, s: true},
    {count: 13399, u: false},
    {count: 13412, r: true},
    {count: 13419, d: true},
    {count: 13423, r: false},
    {count: 13424, d: false},
    {count: 13429, d: true},
    {count: 13434, d: false},
    {count: 13436, l: true},
    {count: 13443, l: false},
    {count: 13447, l: true},
    {count: 13458, l: false},
    {count: 13458, u: true},
    {count: 13463, u: false},
    {count: 13464, r: true},
    {count: 13471, r: false},
    {count: 13488, r: true},
    {count: 13492, r: false},
    {count: 13494, r: true},
    {count: 13498, r: false},
    {count: 13514, d: true},
    {count: 13523, r: true},
    {count: 13528, d: false},
    {count: 13533, r: false},
    {count: 13540, r: true},
    {count: 13542, d: true},
    {count: 13545, r: false},
    {count: 13551, r: true},
    {count: 13552, d: false},
    {count: 13557, r: false},
    {count: 13653, l: true},
    {count: 13658, l: false},
    {count: 13689, r: true},
    {count: 13692, r: false},
    {count: 13897, r: true},
    {count: 13900, u: true},
    {count: 13903, r: false},
    {count: 13911, u: false},
    {count: 13915, l: true},
    {count: 13925, l: false},
    {count: 13939, r: true},
    {count: 13945, r: false},
    {count: 13958, l: true},
    {count: 13967, l: false},
    {count: 14015, r: true},
    {count: 14019, r: false},
    {count: 14299, d: true},
    {count: 14311, l: true},
    {count: 14312, d: false},
    {count: 14319, l: false},
    {count: 14341, r: true},
    {count: 14346, r: false},
    {count: 14353, u: true},
    {count: 14360, u: false},
    {count: 14383, r: true},
    {count: 14400, r: false},
    {count: 14434, l: true},
    {count: 14438, l: false},
    {count: 14483, l: true},
    {count: 14487, l: false},
    {count: 14685, d: true},
    {count: 14691, d: false},
    {count: 14706, s: false},
    {count: 14710, l: true},
    {count: 14717, l: false},
    {count: 14717, u: true},
    {count: 14717, z: false},
    {count: 14768, z: true},
    {count: 14777, s: true},
    {count: 14780, u: false},
    {count: 14796, d: true},
    {count: 14856, d: false},
    {count: 14879, u: true},
    {count: 14885, u: false},
    {count: 14902, l: true},
    {count: 14908, l: false},
    {count: 14910, u: true},
    {count: 14921, u: false},
    {count: 14945, l: true},
    {count: 14955, l: false},
    {count: 14968, r: true},
    {count: 14975, r: false},
    {count: 14983, r: true},
    {count: 14987, r: false},
    {count: 14998, d: true},
    {count: 15014, l: true},
    {count: 15014, d: false},
    {count: 15019, l: false},
    {count: 15030, u: true},
    {count: 15041, u: false},
    {count: 15045, r: true},
    {count: 15048, r: false},
    {count: 15072, d: true},
    {count: 15076, d: false},
    {count: 15128, r: true},
    {count: 15137, r: false},
    {count: 15143, r: true},
    {count: 15151, r: false},
    {count: 15153, u: true},
    {count: 15158, l: true},
    {count: 15158, u: false},
    {count: 15164, l: false},
    {count: 15180, l: true},
    {count: 15183, l: false},
    {count: 15185, l: true},
    {count: 15202, l: false},
    {count: 15204, r: true},
    {count: 15209, d: true},
    {count: 15211, x: true},
    {count: 15215, r: false},
    {count: 15215, d: false},
    {count: 15219, u: true},
    {count: 15228, r: true},
    {count: 15228, u: false},
    {count: 15232, r: false},
    {count: 15233, u: true},
    {count: 15261, u: false},
    {count: 15265, d: true},
    {count: 15294, d: false},
    {count: 15350, d: true},
    {count: 15356, d: false},
    {count: 15363, l: true},
    {count: 15370, l: false},
    {count: 15389, r: true},
    {count: 15392, r: false},
    {count: 15483, l: true},
    {count: 15500, l: false},
    {count: 15519, r: true},
    {count: 15525, r: false},
    {count: 15533, r: true},
    {count: 15536, r: false},
    {count: 15554, l: true},
    {count: 15563, l: false},
    {count: 15572, r: true},
    {count: 15575, r: false},
    {count: 15597, r: true},
    {count: 15602, r: false},
    {count: 15627, r: true},
    {count: 15629, r: false},
    {count: 15643, d: true},
    {count: 15654, d: false},
    {count: 15666, r: true},
    {count: 15676, r: false},
    {count: 15692, r: true},
    {count: 15697, r: false},
    {count: 15707, u: true},
    {count: 15712, l: true},
    {count: 15713, u: false},
    {count: 15719, l: false},
    {count: 15731, l: true},
    {count: 15734, l: false},
    {count: 15750, u: true},
    {count: 15756, u: false},
    {count: 15766, r: true},
    {count: 15771, r: false},
    {count: 15776, r: true},
    {count: 15785, u: true},
    {count: 15786, r: false},
    {count: 15791, l: true},
    {count: 15791, u: false},
    {count: 15802, l: false},
    {count: 15844, l: true},
    {count: 15848, l: false},
    {count: 15861, u: true},
    {count: 15870, u: false},
    {count: 15875, r: true},
    {count: 15892, r: false},
    {count: 15910, l: true},
    {count: 15918, l: false},
    {count: 15918, d: true},
    {count: 15933, l: true},
    {count: 15933, x: true},
    {count: 15934, d: false},
    {count: 15937, l: false},
    {count: 15945, u: true},
    {count: 15973, u: false},
    {count: 15997, d: true},
    {count: 16007, d: false},
    {count: 16020, r: true},
    {count: 16025, d: true},
    {count: 16034, d: false},
    {count: 16038, z: false},
    {count: 16039, s: false},
    {count: 16059, r: false},
    {count: 16063, u: true},
    {count: 16071, l: true},
    {count: 16072, u: false},
    {count: 16082, l: false},
    {count: 16132, z: true},
    {count: 16178, z: true},
  ]
}

================================================
FILE: replay/replay_list.txt
================================================
[
  { id: 1, user: 'takahirox', characterIndex: 0, datetime: 1381201800000 },
  { id: 2, user: 'takahirox', characterIndex: 1, datetime: 1381201932580 },
]

================================================
FILE: source/Background.js
================================================
function BackgroundManager(gameState) {
  this.parent = ElementManager;
  this.parent.call(this, gameState);
  this.activeIndex = 0;
  this.drawers = [];
  this.effectTextures = [];
  this._init();
};
__inherit(BackgroundManager, ElementManager);

BackgroundManager.prototype._MAX_NUM = 5;


BackgroundManager.prototype._initMaxNum = function() {
  return this._MAX_NUM;
};


/**
 * Unnecessary to have factory.
 */
BackgroundManager.prototype._initFactory = function() {
};


BackgroundManager.prototype._init = function() {
  this.elements.length = 0;
  this.add(new Background(this.gameState,
                          this.gameState.maxX,
                          this.gameState.maxY));
  this.add(new Background(this.gameState,
                          this.gameState.maxX,
                          this.gameState.maxY));
};


BackgroundManager.prototype.initDrawer = function(layer, image) {
  this.drawers.length = 0;
  this.drawers.push(new BackgroundDrawer(
                          this.get(0), layer,
                          this.gameState.getImage(Game._IMG_BG1)));
  this.drawers.push(new BackgroundDrawer(
                          this.get(1), layer,
                          this.gameState.getImage(Game._IMG_BG2)));

  this.effectTextures.length = 0;
  this._initForwardBlackEffect(layer);
};


/**
 * TODO: is there a way to generate non-premultiplied image?
 */
BackgroundManager.prototype._initForwardBlackEffect = function(layer) {
  var h = 3;
  var loop = 40;

  var width = layer.calculateSquareValue(this.gameState.getWidth());
  var height = layer.calculateSquareValue(h*loop);

  var canvas = document.createElement('canvas');
  canvas.width = width;
  canvas.height = height;
  var surface = canvas.getContext('2d');

  surface.fillStyle = 'rgb(0, 0, 0)';
  for(var i = 0; i < loop; i++) {
    surface.globalAlpha = 0.4 - i * 0.01;
    surface.fillRect(0, i * h, width, h);
  }

  var texture = layer.generateTexture(canvas);
  texture.width = width;
  texture.height = height;

  this.effectTextures.push(texture);
};


BackgroundManager.prototype.setDarkness = function(d) {
  this.get(this.activeIndex).getView().setDarkness(d);
};


BackgroundManager.prototype.draw = function(layer, darken) {
  var d = darken ? 0.4 : 1.0;

  this.setDarkness(d);
  this.drawers[this.activeIndex].draw(layer);

  if(! darken)
    this._drawEffect(layer);
};


BackgroundManager.prototype._drawEffect = function(layer) {
  var texture = this.effectTextures[0];
  layer.viewport();
  layer.ortho(0.1, 10.0);
  mat4.identity(layer.mvMatrix);
  layer.drawOneTexture(texture,
                       texture.width/2, texture.height/2, -1.0,
                       texture.width,   texture.height, 1.0, 1.0);
};


/**
 * should not call parent reset() method to
 * keep elements available.
 */
BackgroundManager.prototype.reset = function() {
  this.activeIndex = 0;
  for(var i = 0; i < this.getNum(); i++) {
    this.get(i).reset();
  }
};


BackgroundManager.prototype.goNextStage = function() {
  this.activeIndex++;
};



function BackgroundView(element) {
  this.parent = ElementView;
  this.parent.call(this, element);
};
__inherit(BackgroundView, ElementView);


BackgroundView.prototype.setDarkness = function(d) {
  this.d = d;
};


BackgroundView.prototype._initVertices = function() {
  this.vertices[0]  = -2.0;
  this.vertices[1]  =  2.0;
  this.vertices[2]  =  0.0;

  this.vertices[3]  =  2.0;
  this.vertices[4]  =  2.0;
  this.vertices[5]  =  0.0;

  this.vertices[6]  =  2.0;
  this.vertices[7]  = -8.0;
  this.vertices[8]  =  0.0;

  this.vertices[9]  = -2.0;
  this.vertices[10] = -8.0;
  this.vertices[11] =  0.0;
};


BackgroundView.prototype._initCoordinates = function() {
  this.coordinates[0] =  0.0;
  this.coordinates[1] = 10.0;

  this.coordinates[2] =  4.0;
  this.coordinates[3] = 10.0;

  this.coordinates[4] =  4.0;
  this.coordinates[5] =  0.0;

  this.coordinates[6] =  0.0;
  this.coordinates[7] =  0.0;
};



function BackgroundDrawer(elementManager, gl, image) {
  this.parent = ElementDrawer;
  this.parent.call(this, elementManager, gl, image);
};
__inherit(BackgroundDrawer, ElementDrawer);

// only for reference
BackgroundDrawer.prototype.Math = Math;
BackgroundDrawer.prototype.mat4 = mat4;



BackgroundDrawer.prototype._project = function(layer) {
  layer.perspective(60, 0.1, 100.0);
};


BackgroundDrawer.prototype._prepareDraw = function(layer) {
  this.mat4.rotate(layer.mvMatrix, this.Math.PI/180*50, [-1, 0, 0]);
};

/**
 * independent of fighter so far.
 * TODO: remove magic numbers.
 */
BackgroundDrawer.prototype.lookAtFromViewpointTarget = function(layer) {
  var eye = this._VIEWPOINTS_CONTAINERS[0];
  var center = this._VIEWPOINTS_CONTAINERS[1];
  var up = this._VIEWPOINTS_CONTAINERS[2];

  eye[0] = 0;
  eye[1] = -0.4;
  eye[2] = 0.1;

  center[0] = 0;
  center[1] = 0;
  center[2] = 0;

  layer.lookAt(eye, center, up);
};


function Background(gameState, maxX, maxY) {
  this.parent = Element;
  this.parent.call(this, gameState, maxX, maxY);
  this._initView();
};
__inherit(Background, Element);


/**
 * Excepts not to call this method unlike other Element inherit class.
 * TODO: bad design.
 */
Background.prototype.init = function(params, image) {
  this.image = image;
//  Prolly unnecessary to call perent init()
//  this.parent.prototype.init.call(this, params, image);
};


Background.prototype.reset = function() {
  this.count = 0;
  this.x = 0;
  this.y = 0;
  this.z = 0;
};


Background.prototype._generateView = function() {
  return new BackgroundView(this);
};


// not implemented yet and no plan to implement.
Background.prototype.display = function(surface) {
};


// TODO: temporal
Background.prototype.Element_runStep = Element.prototype.runStep;
Background.prototype.runStep = function() {
  this.Element_runStep();
  // TODO: should be in BackgroundView?
  this.y = (this.count%200)/200;
  this.z = -this.gameState.bgScale;
};



================================================
FILE: source/Bomb.js
================================================
function BombManager( gameState ) {
  this.parent = ElementManager ;
  this.parent.call( this, gameState ) ;
}
__inherit( BombManager, ElementManager ) ;

BombManager.prototype._MAX_NUM = 40;


BombManager.prototype._initMaxNum = function() {
  return this._MAX_NUM;
};


BombManager.prototype._initFactory = function( ) {
  this.factory = new BombFactory( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;
} ;


BombManager.prototype.initDrawer = function(layer, image) {
  this.drawer = new BombDrawer(this, layer,
                               this.gameState.getImage(Game._IMG_BOMB));
};


// TODO: temporal
BombManager.prototype.create = function( fighter ) {
  var bombs = this.factory.create( fighter ) ;
  for( var i = 0; i < bombs.length; i++ )
    this.addElement( bombs[ i ] ) ;
} ;



function BombFactory( gameState, maxX, maxY ) {
  this.parent = ElementFactory ;
  this.parent.call( this, gameState, maxX, maxY ) ;
  this.params = [ ] ;
  this._initBomb( ) ;
  this.image = null; // TODO: temporal
}
__inherit( BombFactory, ElementFactory ) ;

BombFactory.prototype._NUM = 20 ;
BombFactory.prototype._BULLET_NUM = 10 ;


BombFactory.prototype._initFreelist = function() {
  this.freelist = new BombFreeList(this._NUM, this.gameState); 
};


BombFactory.prototype._initBomb = function() {
  var num = this._BULLET_NUM;
  for(var i = 0; i < num; i++) {
    this.params.push( {
      'x': 0,
      'y': 0,
      'v': { 'r': 0, 'theta': ((360 / num) | 0) * i, 'w': 1, 'ra': 0.2 }
    } ) ;
  }
} ;


BombFactory.prototype.create = function( fighter ) {
  var bombs = [ ] ;
  for( var i = 0; i < this.params.length; i++ ) {
    this.params[ i ].x = fighter.getX( ) ;
    this.params[ i ].y = fighter.getY( ) ;
    var bomb = this.freelist.get( ) ;
    bomb.init( this.params[ i ], this._getImage( this.params[ i ] ), fighter ) ;
    bombs.push( bomb ) ;
  }
  return bombs ;
} ;


/**
 * TODO: temporal
 */
BombFactory.prototype._getImage = function(params) {
  if(this.image === null)
    this.image = this.gameState.getImage(Game._IMG_BOMB);
  return this.image;
};



function BombFreeList( num, gameState ) {
  this.parent = ElementFreeList ;
  this.parent.call( this, num, gameState ) ;
}
__inherit( BombFreeList, ElementFreeList ) ;


BombFreeList.prototype._generateElement = function( ) {
  return new Bomb( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;
} ;



function BombDrawer(elementManager, layer, image) {
  this.parent = ElementDrawer;
  this.parent.call(this, elementManager, layer, image);
};
__inherit(BombDrawer, ElementDrawer);

BombDrawer.prototype.Layer = Layer;

BombDrawer.prototype._getBlend = function() {
  return this.Layer._BLEND_ADD_ALPHA;
};



function BombView(element) {
  this.parent = ElementView;
  this.parent.call(this, element);
  this.a = 0.4;
};
__inherit(BombView, ElementView);



/**
 * Currently Bomb represents just a big bullet.
 */
function Bomb( gameState, maxX, maxY ) {
  this.parent = Element ;
  this.parent.call( this, gameState, maxX, maxY ) ;
}
__inherit( Bomb, Element ) ;

Bomb.prototype._WIDTH  = 128 ;
Bomb.prototype._HEIGHT = 128 ;

Bomb.prototype._OUT_RANGE = 200 ;


Bomb.prototype.Element_init = Element.prototype.init;
Bomb.prototype.init = function( params, image, fighter ) {
  this.Element_init(params, image);

  this.setX( fighter.getX( ) ) ;
  this.setY( fighter.getY( ) ) ;

  this.width = this._WIDTH ;
  this.height = this._HEIGHT ;
  this.collisionWidth = this.width ;
  this.collisionHeight = this.height ;
  this.indexX = 0 ;
  this.indexY = 3 ;
  this._initView();
} ;


Bomb.prototype._generateView = function() {
  return new BombView(this);
};


Bomb.prototype.display = function( surface ) {
//  surface.save( ) ;
  surface.globalAlpha = 0.6 ;
  this.parent.prototype.display.call( this, surface ) ;
  surface.globalAlpha = 1.0 ;
//  surface.restore( ) ;
} ;


Bomb.prototype._outOfTheField = function( ) {
  if( this.getX( ) < -this._OUT_RANGE || this.getX( ) > this.maxX + this._OUT_RANGE ||
      this.getY( ) < -this._OUT_RANGE || this.getY( ) > this.maxY + this._OUT_RANGE )
    return true ;
  return false ;
} ;


================================================
FILE: source/Boss.js
================================================
function BossManager( gameState, params ) {
  this.parent = ElementManager ;
  this.parent.call( this, gameState ) ;
  for( var i = 0; i < params.length; i++ ) {
    params[ i ].sort( function( a, b ) {
      return a.count - b.count ;
    } ) ;
  }
  this.params = params ;
  this.index = 0 ;
  this.stageIndex = 0 ; // TODO: temporal
  this.drawers = null;
  this.activeType = null;
} ;
__inherit( BossManager, ElementManager ) ;

BossManager.prototype._MAX_NUM = 4;

BossManager.prototype._initMaxNum = function() {
  return this._MAX_NUM;
};


BossManager.prototype._initFactory = function( ) {
  this.factory = new BossFactory( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;
} ;


/**
 * TODO: consider the design. To use drawers is easy to handle,
 *       but not smart. To extend BossDrawer is smarter.
 */
BossManager.prototype.initDrawer = function(layer, image) {
  this.drawers = [];
  this._generateDrawer(this.Boss._TYPE_RUMIA, layer);
  this._generateDrawer(this.Boss._TYPE_DAIYOUSEI, layer);
  this._generateDrawer(this.Boss._TYPE_CHIRNO, layer);
};


BossManager.prototype._generateDrawer = function(key, layer) {
  this.drawers[key] = new BossDrawer(this, layer, this._getImage(key));
};


/**
 * TODO: consider who should manage image.
 */
BossManager.prototype._getImage = function(type) {
  var key;
  switch(type) {
    case this.Boss._TYPE_RUMIA:
      key = Game._IMG_ENEMY_RUMIA;
      break;
    case this.Boss._TYPE_DAIYOUSEI:
      key = Game._IMG_ENEMY_DAIYOUSEI;
      break;
    case this.Boss._TYPE_CHIRNO:
      key = Game._IMG_ENEMY_CHILNO;
      break;
    // TODO: temporal
    default:
      key = Game._IMG_ENEMY_MOKOU;
      break;
  }
  return this.gameState.getImage(key);
};


__copyParentMethod(BossManager, ElementManager, 'reset');
BossManager.prototype.reset = function() {
  this.ElementManager_reset();
  this.index = 0;
  this.stageIndex = 0;
  this.activeType = null;
};


/**
 * assumes only one boss in a display.
 */
BossManager.prototype.draw = function(layer) {
  if(! this.existBoss())
    return;

  this.drawers[this.activeType].draw(layer);
};


BossManager.prototype.goNextStage = function() {
  this.ElementManager_reset(this);
  this.index = 0;
  this.stageIndex++;
};


__copyParentMethod(BossManager, ElementManager, 'runStep');
BossManager.prototype.runStep = function() {
  this._generateBoss();
  this.ElementManager_runStep();
};


BossManager.prototype._generateBoss = function() {
  if(this.gameState.isBossExist())
    return;

  while(this.index < this.params[this.stageIndex].length &&
        this.params[this.stageIndex][this.index].count
          + this.gameState.pending <= this.gameState.count) {
    var params = this.params[this.stageIndex][this.index];
    var boss = this.factory.create(params);
    this.activeType = this._str2type(params.character);
    this.gameState.notifyBossAppeared(boss);
    this.addElement(boss);
    this.index++;
  }
};


BossManager.prototype._str2type = function(str) {
  switch(str) {
    case 'rumia':
      return this.Boss._TYPE_RUMIA;
    case 'daiyousei':
      return this.Boss._TYPE_DAIYOUSEI;
    case 'chilno':
      return this.Boss._TYPE_CHIRNO;
    // TODO: temporal
    default:
      return null;
  }
};


/**
 * TODO: temporal
 */
__copyParentMethod(BossManager, ElementManager, 'checkLoss');
BossManager.prototype.checkLoss = function() {
  this.ElementManager_checkLoss(this);
};


/**
 * TODO: temporal
 */
BossManager.prototype.notifyCheckLoss = function(element) {
  if(element.dead != 'escape')
    this.gameState.notifyBossVanishEnd(element);
};


/**
 * TODO: temporal. implement multi bosses?
 */
BossManager.prototype.getBoss = function() {
  return (this.existBoss()) > 0 ? this.elements[0] : null;
};


BossManager.prototype.existBoss = function() {
  return this.getNum( ) > 0 ? true : false;
};


/**
 * TODO: temporal. I wanna use the parent method but bigger one should be the argument of this method.
 */
__copyParentMethod(BossManager, ElementManager, 'checkCollisionWith');
BossManager.prototype.checkCollisionWith = function(fighter) {
  this.ElementManager_checkCollisionWith(null, fighter, this);
};


BossManager.prototype.checkCollisionWithFighters = function(fighters) {
  for(var i = 0; i < fighters.length; i++) {
    this.checkCollisionWith(fighters[i]);
  }
};


BossManager.prototype.notifyCollision = function(id, fighter, boss) {
  fighter.die();
  this.gameState.notifyFighterDead(fighter, boss);
};



function BossFactory( gameState, maxX, maxY ) {
  this.parent = ElementFactory ;
  this.parent.call( this, gameState, maxX, maxY ) ;
} ;
__inherit( BossFactory, ElementFactory ) ;

BossFactory.prototype._NUM = 2 ;


BossFactory.prototype._initFreelist = function() {
  this.freelist = new BossFreeList(this._NUM, this.gameState);
};


BossFactory.prototype._getImage = function( params ) {
  switch( params.character ) {
    case 'rumia':
      return this.gameState.getImage( Game._IMG_ENEMY_RUMIA ) ;
    case 'chilno':
      return this.gameState.getImage( Game._IMG_ENEMY_CHILNO ) ;
    case 'daiyousei':
      return this.gameState.getImage( Game._IMG_ENEMY_DAIYOUSEI ) ;
    // TODO: temporal
    default:
      return this.gameState.getImage( Game._IMG_ENEMY_MOKOU ) ;
  }
} ;



function BossFreeList( num, gameState ) {
  this.parent = ElementFreeList ;
  this.parent.call( this, num, gameState ) ;
}
__inherit( BossFreeList, ElementFreeList ) ;


BossFreeList.prototype._generateElement = function( ) {
  return new Boss( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;
} ;


function BossDrawer(elementManager, layer, image) {
  this.parent = ElementDrawer;
  this.parent.call(this, elementManager, layer, image);
};
__inherit(BossDrawer, ElementDrawer);



function BossView(element) {
  this.parent = ElementView;
  this.parent.call(this, element);
};
__inherit(BossView, ElementView);


/**
 * no rotate.
 * TODO: no rotate impl should be in parent class?
 */
BossView.prototype.rotate = function() {
};


BossView.prototype.doRotateForViewpoint = function() {
  return true;
};


BossView.prototype.animate = function() {
  this._initCoordinates();

  if(this.element.inVanishing()) {
    this.a = this._inVanishingEffect();
  } else if(this.element.effects && this.element.effects['vanish']) {
    this.a = this._vanishEffect(this.element.effects['vanish']);
  } else {
    this.a = 1.0;
  }
};


/**
 * TODO: temporal. especially name.
 */
BossView.prototype._inVanishingEffect = function() {
  return (this.element._VANISH_COUNT -
          this.element.vanishingCount + 1) * 0.01;
};


/**
 * TODO: temporal. especially name.
 */
BossView.prototype._vanishEffect = function(params) {
  var count = this.element._getCountFromBase(params, -1);

  if(count >= params['count'] &&
     count <  params['count'] + params['length']) {
    return 1.0 - ((count - params['count']) / params['length']) ;
  }
  return 1.0;
};



function Boss( gameState, maxX, maxY ) {
  this.parent = Element ;
  this.parent.call( this, gameState, maxX, maxY ) ;

  this.params = null ;
  this.index = 0 ;
  this.maxVital = 0 ;

  this.appearedTalk = null ;
  this.vanishedTalk = null ;
  this.character = null ;
  this.score = null ;
  this.dead = null ;
  this.animation = null ;
  this.spellCard = false ;
  this.effect = null ;

  this.escaping = false;

  this.vanishing = false;
  this.vanishingCount = 0;

/*
  this.powerItem  = powerItem  ? powerItem : 0 ;
  this.lpowerItem = lpowerItem ? lpowerItem : 0 ;
  this.scoreItem  = scoreItem  ? scoreItem : 0 ;
*/

  this.shots = [ ] ;
  this.shotIndices = [ ] ;

}
__inherit( Boss, Element ) ;

Boss.prototype._WIDTH = 128 ;
Boss.prototype._HEIGHT = 128 ;

Boss.prototype._APPEAR_COUNT = 100 ;
Boss.prototype._APPEAR_WAIT_COUNT = 50 ;

Boss.prototype._VANISH_COUNT = 100;

Boss.prototype._TYPE_RUMIA     = 0;
Boss.prototype._TYPE_DAIYOUSEI = 1;
Boss.prototype._TYPE_CHIRNO    = 2;

Boss.prototype._ESCAPE_VECTOR = {'r': 0, 'theta': 225, 'ra': 0.1};


__copyParentMethod(Boss, Element, 'init');
Boss.prototype.init = function(params, image) {
  this.Element_init(params, image);

  this.params = params.params ;
  this.index = 0 ;
  this.maxVital = 0 ;

  this.appearedTalk = params.appearedTalk ;
  this.vanishedTalk = params.vanishedTalk ;
  this.character = params.character ;
  this.score = params.score ;
  this.dead = params.dead ;
  this.animation = params.animation ; // TODO: temporal
  this.spellCard = false ;
  this.effect = null ;

  this.escaping = false;

  this.vanishing = false;
  this.vanishingCount = 0;

/*
  this.powerItem  = powerItem  ? powerItem : 0 ;
  this.lpowerItem = lpowerItem ? lpowerItem : 0 ;
  this.scoreItem  = scoreItem  ? scoreItem : 0 ;
*/

  this.shots.length = 0 ;
  this.shotIndices.length = 0 ;

  this._initState( ) ;
  this._initView();
} ;


Boss.prototype._generateView = function() {
  return new BossView(this);
};


Boss.prototype._shot = function( ) {
  if( this.shots.length == 0 )
    return ;

  if(this.vanishing || this.escaping)
    return;

  var offset = this._APPEAR_COUNT + this._APPEAR_WAIT_COUNT ;
  if( this.count < offset )
    return ;
  for( var i = 0; i < this.shots.length; i++ ) {
    var count = this.count - offset ;
    if( this.shots[ i ].baseCount )
      count = count % this.shots[ i ].baseCount ;
    if( count == 0 ) {
      this.shotIndices[ i ] = 0 ;
    }
    if( this.shotIndices[ i ] >= this.shots[ i ].shotCount.length ) {
      continue ;
    }
    if( count >= this.shots[ i ].shotCount[ this.shotIndices[ i ] ] ) {
      // TODO: temporal
      this.gameState.notifyEnemyDoShot( this, this.shots[ i ] ) ;
      this.shotIndices[ i ]++ ;
    }
  }
} ;


// TODO: temporal
__copyParentMethod(Boss, Element, 'runStep');
Boss.prototype.runStep = function() {
  if(this.isFlagSet(this._FLAG_UNHITTABLE) &&
     this.count + 1 >= this._APPEAR_COUNT + this._APPEAR_WAIT_COUNT) {
    this.clearFlag(this._FLAG_UNHITTABLE);
    if(this.index == 0)
      this.gameState.notifyBossBeginTalk(this);
    else
      this.gameState.notifyBossBecameActive(this);
  }
  this._shot();
  this._doEffect();

  this.Element_runStep();

  // for animation
  this._checkState();
  // TODO: temporal
  if(this.getXDirection() == 1) {
    this.indexX = 2;
    this.indexY = 3;
  } else if(this.getXDirection() == -1) {
    this.indexX = 2;
    this.indexY = 1;
  } else {
    this.indexX = 0;
    if(this.count % 4 == 0) {
      this.indexY++;
      if(this.indexY > this.animation)
        this.indexY = 0;
    }
  }

  if(this.vanishing)
    this.vanishingCount++;
};


/**
 * TODO: temporal
 */
Boss.prototype._getCountFromBase = function(params, o) {
  var o = o ? o : 0;
  var offset = this._APPEAR_COUNT + this._APPEAR_WAIT_COUNT;
  return (this.count - offset + o) % params['baseCount'];
};


Boss.prototype._doEffect = function() {
  if(this.effects && this.effects['shockwave'] !== void 0) {
    // TODO: temporal
    for(var i = 0; i < this.effects['shockwave'].length; i++) {
      var params = this.effects['shockwave'][i];
      var count = this._getCountFromBase(params);
      if(count == params['count'])
        this.gameState.notifyDoEffect(this, 'shockwave', params.params);
    }
  }
};


/**
 * TODO: temporal
 */
Boss.prototype._checkState = function() {
  if(this.vanishing || this.escaping)
    return;
  if(this.vital <= 0) {
    this.index++;
    if(this.index >= this.params.length) {
      this.die();
      this.gameState.notifyBossVanished(this);
      if(this.dead == 'escape')
        this._beginEscape();
      else
        this._beginVanish();
    } else {
      this.gameState.notifyBossMovedNextStage(this);
      this._initState();
    }
  }
};


Boss.prototype._initState = function( ) {

  // TODO: temporal
  this.count = 0 ;

  // TODO: temporal
  var shots = this.params[ this.index ].s ;

  // TODO: temporal
  this.vectorIndex = 0 ;
  this.vectors.length = 0 ;
  for( var i = 0; i < this.params[ this.index ].v.length; i++ ) {
    this.vectors.push( this.params[ this.index ].v[ i ] ) ;
  }
//  this.vectors = this.params[ this.index ].v ;
  this.vectors.unshift( {
    'count': -this._APPEAR_WAIT_COUNT,
    'v': {
      'r':     0,
      'theta': 0,
      'w':     0,
      'ra':    0,
      'wa':    0,
      'raa':   0,
    }
  } ) ;
  this.vectors.unshift( {
    'count': 0,
    'v': {
      'r':     0,
      'theta': 0,
      'w':     0,
      'ra':    0,
      'wa':    0,
      'raa':   0,
      'target': { 'x': this.params[ this.index ].x,
                  'y': this.params[ this.index ].y,
                  'count': this._APPEAR_COUNT }
    }
  } ) ;
  this.baseVectorCount = this._APPEAR_COUNT + this._APPEAR_WAIT_COUNT ;

  this._initVector( ) ;

  this.shots.length = 0;
  if(shots === void 0) {
  } else if(shots instanceof Array) {
    for( var i = 0; i < shots.length; i++ )
      this.shots.push( shots[ i ] ) ;
  } else {
    shots = [ shots ] ;
    this.shots.push( shots[ 0 ] ) ;
  }

  // TODO: temporal
  this.shotIndices.length = 0 ;
  for( var i = 0; i < this.shots.length; i++ ) {
    this.shotIndices.push( 0 ) ;
  }

  this.vital = this.params[ this.index ].vital ;
  this.maxVital = this.vital ;
  this.spellCard = this.params[ this.index ].spellCard ;
  this.effects = this.params[ this.index ].e ;
  this.setFlag( this._FLAG_UNHITTABLE ) ;
  this.gameState.notifyBossStageChanged( this ) ;

} ;


__copyParentMethod(Boss, Element, 'getXDirection');
Boss.prototype.getXDirection = function() {
  if(this.vector && this.vector.r == 0)
    return 0;
  return this.Element_getXDirection();
};


__copyParentMethod(Boss, Element, '_outOfTheField');
Boss.prototype._outOfTheField = function() {
  if(this.Element_outOfTheField())
    this._beInTheField();
  return false;
};


/**
 * TODO: temporal function name
 */
Boss.prototype.outOfTheField = function() {
  return this.Element_outOfTheField();
};


Boss.prototype._beginEscape = function() {
  this.escaping = true;
  this.gravity = null;
  // TODO: temporal
  this.vector = this.moveVectorManager.create(this._ESCAPE_VECTOR);

  // TODO: these parameters should move to EffectFactory.
  this.gameState.notifyDoEffect(this, 'shockwave', {
    'w': 5,
    'g': 5,
    'a': 0.1,
    'b': 20,
    'endCount': 100
  });
};


Boss.prototype._beginVanish = function() {
  this.vanishing = true;
  this.vanishingCount = 0;

  this.gravity = null;
  this.vector = null;

  // TODO: these parameters should move to EffectFactory.
  this.gameState.notifyDoEffect(this, 'shockwave', {
    'w': 5,
    'g': 5,
    'a': 0.1,
    'b': 10,
    'endCount': 100
  });
  this.gameState.effectManager.createBigExplosion(this);


  // TODO: who manages this logic? Boss? StageState?
  if(this.dead == 'escape' && this.vanishedTalk) {
    this.gameState.notifyBeginTalk();
  }

};


Boss.prototype.inVanishing = function() {
  return (this.vanishing && this.vanishingCount < this._VANISH_COUNT);
};


Boss.prototype.overVanishing = function() {
  return (this.vanishing && this.vanishingCount >= this._VANISH_COUNT);
};


/**
 * TODO: temporal workaround.
 */
__copyParentMethod(Boss, Element, '_checkVectorChange');
Boss.prototype._checkVectorChange = function() {
  if(this.escaping || this.vanishing)
    return false;
  return this.Element_checkVectorChange();
};


/**
 * TODO: temporal logic.
 */
__copyParentMethod(Boss, Element, 'checkLoss');
Boss.prototype.checkLoss = function() {
  if(this.escaping)
    return this.Element_outOfTheField();

  if(! this.vanishing)
    return this.Element_checkLoss();

  var tmp = this.state;
  this.state = this._STATE_ALIVE;
  var value = this.Element_checkLoss();
  this.state = tmp;

  if(value)
    return value;

  return this.overVanishing();
};


// TODO: temporal
Boss.prototype.isVanishingOrEscaping = function() {
  return (this.vanishing || this.escaping);
};



// TODO: remove the followings because they complicate the design.

// only for reference
// TODO: temporal
BossManager.prototype.Boss = Boss.prototype;



================================================
FILE: source/Bullet.js
================================================
function BulletManager( gameState, params ) {
  this.parent = ElementManager ;
  this.parent.call( this, gameState ) ;
  this.params = params ;
  this.laserCounts = [0, 0]; // TODO: temporal
} ;
__inherit( BulletManager, ElementManager ) ;

BulletManager.prototype._MAX_NUM = 500;

BulletManager.prototype._initMaxNum = function() {
  return this._MAX_NUM;
};


BulletManager.prototype._initFactory = function( ) {
  this.factory = new BulletFactory( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;
} ;


BulletManager.prototype.initDrawer = function(layer, image) {
  this.drawer = new BulletDrawer(this, layer,
                                 this.gameState.getImage(Game._IMG_SHOT));
};


__copyParentMethod(BulletManager, ElementManager, 'reset');
BulletManager.prototype.reset = function() {
  this.ElementManager_reset();
  for(var i = 0; i < this.laserCounts.length; i++) {
    this.laserCounts[i] = 0;
  }
};


/**
 * TODO: temporal. to make the logic straightforward.
 */
BulletManager.prototype.create = function( fighter ) {
  var params = this.params[ fighter.characterIndex ][ fighter.getBulletIndex( ) ][ fighter.getPowerLevel( ) ] ;
  var flag = false ;
  var count = 0 ;
  var id = fighter.getID();
  for( var i = 0; i < params.length; i++ ) {
    // TODO: temporal
    if( ( params[ i ].laser || params[ i ].homing ) && params[ i ].nextCount ) {
      if( this.count < this.laserCounts[id] + params[ i ].nextCount ) {
        continue ;
      }
      flag = true ;
      if( this.count > count )
        count = this.count ;
    }
    this.addElement( this.factory.create( params[ i ], fighter ) ) ;
  }
  if( flag )
    this.laserCounts[id] = count ;
} ;


__copyParentMethod(BulletManager, ElementManager, 'checkCollisionWith');
BulletManager.prototype.checkCollisionWithEnemies = function(enemies) {
  var self = this;
  for(var i = 0; i < enemies.length; i++) {
    this.ElementManager_checkCollisionWith(null, enemies[i], this);
  }
};


BulletManager.prototype.notifyCollision = function(id, enemy, bullet) {
  // TODO: temporal
  if(bullet._ID !== this._ID_LASER)
    bullet.die();
  // TODO: temporal
  enemy.vital -= bullet.power;
  this.gameState.notifyBulletHit(bullet, enemy);
  if(enemy.vital <= 0) {
    this.gameState.notifyEnemyVanished(bullet, enemy);
    enemy.die();
  }
};


/**
 * TODO: temporal
 */
__copyParentMethod(BulletManager, ElementManager, 'checkCollisionWith2');
BulletManager.prototype.checkCollisionWithBoss = function(boss) {
  if(boss.isFlagSet(boss._FLAG_UNHITTABLE))
    return;

  var self = this;
  this.ElementManager_checkCollisionWith2(null, boss, this);
};


BulletManager.prototype.notifyCollision2 = function(id, boss, bullet) {
  // TODO: temporal
  if(bullet._ID !== this._ID_LASER)
    bullet.die();
  boss.vital -= bullet.power;
  this.gameState.notifyBulletHit(bullet, boss);
};



function BulletFactory( gameState, maxX, maxY ) {
  this.parent = ElementFactory ;

  this.homingFreelist = null ;
  this.laserFreelist = null ;

  this.parent.call( this, gameState, maxX, maxY ) ;
  this.types = __bulletTypes ;  // TODO: temporal
  this.image = null; // TODO: temporal
}
__inherit( BulletFactory, ElementFactory ) ;

BulletFactory.prototype._BULLET_NUM = 100 ;
BulletFactory.prototype._HOMING_NUM = 100 ;
BulletFactory.prototype._LASER_NUM  = 10 ;


BulletFactory.prototype._initFreelist = function() {
  this.freelist       = new BulletFreeList(this._BULLET_NUM, this.gameState);
  this.homingFreelist = new HomingFreeList(this._HOMING_NUM, this.gameState);
  this.laserFreelist  = new LaserFreeList( this._LASER_NUM,  this.gameState);
};


BulletFactory.prototype.create = function( params, fighter ) {
  if( params.laser ) {
    var laser = this.laserFreelist.get( ) ;
    laser.init( params, this._getImage( params ), 
                fighter.getOption(params.option), // TODO: temporal
                this.types[ 3 ]) ; // TODO: temporal
    return laser ;
  }
  if( params.homing ) {
    var homing = this.homingFreelist.get( ) ;
    homing.init( params, this._getImage( params ),
                 fighter.getOption(params.option), // TODO: temporal
                 this.types[ 2 ]) ; // TODO: temporal
    return homing ;
  }
  var key = fighter.characterIndex ;
  var bullet = this.freelist.get( ) ;
  bullet.init( params, this._getImage( params ), this.types[ key ], fighter ) ;
  return bullet ;
} ;


BulletFactory.prototype.free = function( bullet ) {
  switch(bullet._ID) {
    case this.BulletManager._ID_BULLET:
      this.freelist.free( bullet ) ;
      return;
    case this.BulletManager._ID_LASER:
      this.laserFreelist.free( bullet ) ;
      return;
    case this.BulletManager._ID_HOMING:
      this.homingFreelist.free( bullet ) ;
      return;
    default:
      // throw exception?
  }
};


/**
 * TODO: temporal
 */
BulletFactory.prototype._getImage = function(params) {
  if(this.image === null)
    this.image = this.gameState.getImage(Game._IMG_SHOT);
  return this.image;
};



function BulletFreeList( num, gameState ) {
  this.parent = ElementFreeList ;
  this.parent.call( this, num, gameState ) ;
}
__inherit( BulletFreeList, ElementFreeList ) ;


BulletFreeList.prototype._generateElement = function( ) {
  return new Bullet( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;
} ;



function BulletDrawer(elementManager, layer, image) {
  this.parent = ElementDrawer;
  this.parent.call(this, elementManager, layer, image);
};
__inherit(BulletDrawer, ElementDrawer);


function BulletView(element) {
  this.parent = ElementView;
  this.parent.call(this, element);
  this.a = 0.8;
};
__inherit(BulletView, ElementView);



function Bullet( gameState, maxX, maxY ) {
  this.parent = Element ;
  this.parent.call( this, gameState, maxX, maxY ) ;
  this.rotate = null ;
  this.power = null ;
  this.fighter = null;
}
__inherit( Bullet, Element ) ;

Bullet.prototype._WIDTH = 16 ;
Bullet.prototype._HEIGHT = 32 ;


/**
 * TODO: temporal. params2 should be renamed.
 */
__copyParentMethod(Bullet, Element, 'init');
Bullet.prototype.init = function(params, image, params2, fighter) {

  this.fighter = fighter;
  this.Element_init(params, image);

  this.setX(this.getX() + this.fighter.getX());
  this.setY(this.getY() + this.fighter.getY());

  // TODO: temporal. Wanna combine this logic with parent init( ).
  this.indexX = params2.indexX !== void 0 ? params2.indexX : 0;
  this.indexY = params2.indexY !== void 0 ? params2.indexY : 0;
  this.width  = params2.width  !== void 0 ? params2.width  : 0;
  this.height = params2.height !== void 0 ? params2.height : 0;
  this.collisionWidth  = params2.collisionWidth  !== void 0 ? params2.collisionWidth  : 0;
  this.collisionHeight = params2.collisionHeight !== void 0 ? params2.collisionHeight : 0;

  this.power  = params.power   !== void 0 ? params.power   : 1;
  this.rotate = params2.rotate !== void 0 ? params2.rotate : 0;
  this._initView();
};


Bullet.prototype._generateView = function() {
  return new BulletView(this);
};


/**
 * TODO: which is faster save&restore or doing by my hand?
 */
Bullet.prototype.display = function( surface ) {
//  surface.save( ) ;
  surface.globalAlpha = 0.8 ;
  this.parent.prototype.display.call( this, surface, true ) ;
  surface.globalAlpha = 1.0 ;
//  surface.restore( ) ;
} ;



function LaserFreeList( num, gameState ) {
  this.parent = ElementFreeList ;
  this.parent.call( this, num, gameState ) ;
}
__inherit( LaserFreeList, ElementFreeList ) ;


LaserFreeList.prototype._generateElement = function( ) {
  return new Laser( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;
} ;



/**
 * TODO: consider the option to use add blend.
 */
function LaserView(element) {
  this.parent = ElementView;
  this.parent.call(this, element);
};
__inherit(LaserView, ElementView);


LaserView.prototype._getElementX = function() {
  return this.element.option.getCenterX() + this.element.getX();
};


LaserView.prototype._getElementY = function() {
  return this.element.option.getCenterY() + this.element.getY();
};


LaserView.prototype._getElementZ = function() {
  return this.element.option.getZ();
};


/**
 * assumes that image height is 256 and master image size is 256.
 * TODO: temporal
 */
__copyParentMethod(LaserView, ElementView, '_initVertices');
LaserView.prototype._initVertices = function() {
  this.ElementView_initVertices();
  this.vertices[1]   = 0;
  this.vertices[4]   = 0;
  this.vertices[7]  *= 4;
  this.vertices[10] *= 4;
};


/**
 * assumes that image height is 256 and master image size is 256.
 * TODO: temporal
 */
__copyParentMethod(LaserView, ElementView, '_initCoordinates');
LaserView.prototype._initCoordinates = function() {
  this.ElementView_initCoordinates();
  this.coordinates[1] *= 2;
  this.coordinates[3] *= 2;
};


/**
 * TODO: should be in Laser?
 */
LaserView.prototype.animate = function() {
  if(this.element.count < this.element.waitCount ||
     this.element.count + 10 > this.element.keepAlive )
    this.a = 0.2;
  else
    this.a = 0.8;
};



/**
 * TODO: temporal
 */
function Laser( gameState, maxX, maxY ) {
  this.parent = Element ;
  this.parent.call( this, gameState, maxX, maxY ) ;
  this.rotate = null ;
  this.option = null ;
  this.power  = null ;
}
__inherit( Laser, Element ) ;

Laser.prototype._WIDTH = 16 ;
Laser.prototype._HEIGHT = 16 ;


__copyParentMethod(Laser, Element, 'init');
Laser.prototype.init = function(params, image, option, params2) {

  this.Element_init(params, image);

  this.option = option;

  // TODO: temporal. Wanna combine this logic with parent init( ).
  this.keepAlive = this._getValueOrDefaultValue(params.keep, 0);
  this.indexX = params2.indexX !== void 0 ? params2.indexX : 0;
  this.indexY = params2.indexY !== void 0 ? params2.indexY : 0;
  this.width  = params2.width  !== void 0 ? params2.width  : 0;
  this.height = params2.height !== void 0 ? params2.height : 0;
  this.collisionWidth  = params2.collisionWidth  !== void 0 ? params2.collisionWidth  : 0;
  this.collisionHeight = params2.collisionHeight !== void 0 ? params2.collisionHeight : 0;

  this.power     = params.power     !== void 0 ? params.power     : 1;
  this.waitCount = params.waitCount !== void 0 ? params.waitCount : 50;
  this.rotate    = params2.rotate   !== void 0 ? params2.rotate   : 0;
  this._initView();
};


Laser.prototype._generateView = function() {
  return new LaserView(this);
};


/**
 * TODO: temporal
 */
Laser.prototype.display = function( surface ) {

  var x = Math.round( this.option.getCenterX( ) + this.getLeftX( ) ) ;
  var y = Math.round( this.option.getCenterY( ) + this.getCenterY( ) ) ;
//  surface.save( ) ;
  if( this.count < this.waitCount || this.count + 10 > this.keepAlive )
    surface.globalAlpha = 0.2 ;
  else
    surface.globalAlpha = 0.6 ;
  while( y > 0 ) {
    surface.drawImage( this.image,
                       this.width  * this.indexX, this.height * this.indexY,
                       this.width,                this.height,
                       x,                         y,
                       this.width,                -this.height ) ;
    y -= this.height ;
  }
  surface.globalAlpha = 1.0 ;
//  surface.restore( ) ;

} ;


/**
 * TODO: temporal
 */
Laser.prototype.checkCollision = function( enemy ) {
  if( this.count < this.waitCount )
    return false ;

  // TODO: temporal
  if( this.count % 3 != 0 )
    return false ;

  // TODO: temporal
  if( this.vector.theta != 270 )
    return false ;

  if( enemy.getCollisionUpY( ) > this.y + this.option.getCenterY( ) )
    return false ;

  if( enemy.getCollisionRightX( ) < this.x + this.option.getCenterX( ) - this.width/2 )
    return false ;

  if( enemy.getCollisionLeftX( ) > this.x + this.option.getCenterX( ) + this.width/2 )
    return false ;

  return true ;

} ;


/**
 * TODO: temporal
 */
Laser.prototype.checkLoss = function( ) {
  if( this.isDead( ) )
    return true ;
  if( this.keepAlive && this.count >= this.keepAlive )
    return true ;
  return false ;
} ;



function HomingFreeList( num, gameState ) {
  this.parent = ElementFreeList ;
  this.parent.call( this, num, gameState ) ;
}
__inherit( HomingFreeList, ElementFreeList ) ;


HomingFreeList.prototype._generateElement = function( ) {
  return new Homing( this.gameState, this.gameState.getWidth( ), this.gameState.getHeight( ) ) ;
} ;



/**
 * TODO: temporal
 */
function Homing( gameState, maxX, maxY ) {
  this.parent = Element ;
  this.parent.call( this, gameState, maxX, maxY ) ;
  this.rotate = null ;
  this.option = null ;
  this.power  = null ;
  this.target = null ;
  this.targetIsDead = false ;
}
__inherit( Homing, Element ) ;

Homing.prototype.Math = Math;

Homing.prototype._SEARCH_SPAN = 1000;
Homing.prototype._HOMING_SPAN = 2;
Homing.prototype._HOMING_COUNT = 50;
Homing.prototype._HOMING_LAG = 5;
Homing.prototype._HOMING_REACH = 10;

Homing.prototype._OUT_RANGE = 30;


__copyParentMethod(Homing, Element, 'init');
Homing.prototype.init = function(params, image, option, params2) {

  this.Element_init(params, image);

  this.option = option;
  this.setX(this.getX() + option.getCenterX());
  this.setY(this.getY() + option.getCenterY());

  // TODO: temporal. Wanna combine this logic with parent init( ).
  this.keepAlive = this._getValueOrDefaultValue(params.keep, 0);
  this.indexX = params2.indexX !== void 0 ? params2.indexX : 0;
  this.indexY = params2.indexY !== void 0 ? params2.indexY : 0;
  this.width  = params2.width  !== void 0 ? params2.width  : 0;
  this.height = params2.height !== void 0 ? params2.height : 0;
  this.collisionWidth  = params2.collisionWidth  !== void 0 ? params2.collisionWidth  : 0;
  this.collisionHeight = params2.collisionHeight !== void 0 ? params2.collisionHeight : 0;

  this.power     = params.power     !== void 0 ? params.power     : 1;
  this.waitCount = params.waitCount !== void 0 ? params.waitCount : 50;
  this.rotate    = params2.rotate   !== void 0 ? params2.rotate   : false;

  this.target = null;
  this.targetIsDead = false;
  this._initView();
};


/**
 * unnecessary to have Homing special view.
 */
Homing.prototype._generateView = function() {
  return new BulletView(this);
};


Homing.prototype.display = function( surface ) {
//  surface.save( ) ;
  surface.globalAlpha = 0.8 ;
  this.parent.prototype.display.call( this, surface, true ) ;
  surface.globalAlpha = 1.0 ;
//  surface.restore( ) ;

} ;


/**
 * TODO: temporal
 */
__copyParentMethod(Homing, Element, 'runStep');
Homing.prototype.runStep = function() {
  if(this.count % this._SEARCH_SPAN == 0)
    this._searchNearestEnemy();
  if(this.count % this._HOMING_SPAN == 0)
    this._calculateHomingPoint();

  this.Element_runStep(this);
};


/**
 * TODO: temporal
 */
Homing.prototype._searchNearestEnemy = function( ) {
  // TODO: temporal
  if( this.targetIsDead)
    return ;

  var min = 1000 * 1000 ; // TODO: temporary
  var nearest = null ;
  for( var i = 0; i < this.gameState.enemyManager.elements.length; i++ ) {
    var e = this.gameState.enemyManager.elements[ i ] ;
    var d = this.Math.pow( this.getX( ) - e.getX( ), 2 ) + this.Math.pow( this.getY( ) - e.getY( ), 2 ) ;
    if( d < min ) {
      min = d ;
      nearest = e ;
    }
  }
  if( this.gameState.bossManager.existBoss( ) ) {
    var b = this.gameState.bossManager.getBoss( ) ;
    if(! b.vanishing && ! b.escaping) {
      var d = this.Math.pow( this.getX( ) - b.getX( ), 2 ) + this.Math.pow( this.getY( ) - b.getY( ), 2 ) ;
      if( d < min ) {
        min = d ;
        nearest = b ;
      }
    }
  }

  // TODO: temporary
  if( nearest )
    this.target = nearest ;
} ;


/**
 * TODO: temporal
 */
Homing.prototype._calculateHomingPoint = function( ) {
  if( ! this.target )
    return ;
  // TODO: how handles the case if target is used for the other alive element soon again?
  if(this.target.isDead() || this.target.isFlagSet(this._FLAG_UNHITTABLE) ||
      this.target.isVanishingOrEscaping()) {
    this.targetIsDead = true ;
    return ;
  }
  var ax = this.target.getX( ) - this.getX( ) ;
  var ay = this.target.getY( ) - this.getY( ) ;
  var t = this._calculateTheta( this.Math.atan2( ay, ax ) ) ;
/*
  var diff = t - this.vector.theta ;
  if( Math.cos( this._calculateRadian( diff ) ) >
      Math.cos( this._calculateRadian( Homing._HOMING_REACH ) ) ) {
    this.vector.theta = t ;
  } else if( Math.sin( this._calculateRadian( diff ) ) > 0 ) {
    this.vector.theta += Homing._HOMING_REACH ;
  } else if( Math.sin( this._calculateRadian( diff ) ) < 0 ) {
    this.vector.theta -= Homing._HOMING_REACH ;
  } else {
*/
    this.vector.theta = t ;
/*
  }
*/
  return ;
} ;


Homing.prototype._outOfTheField = function( ) {
  if( this.getX( ) < -this._OUT_RANGE || this.getX( ) > this.maxX + this._OUT_RANGE ||
      this.getY( ) < -this._OUT_RANGE || this.getY( ) > this.maxY + this._OUT_RANGE )
    return true ;
  return false ;
} ;



// TODO: remove the followings because they complicate the design.

BulletManager.prototype._ID_BULLET = 0;
BulletManager.prototype._ID_LASER  = 1;
BulletManager.prototype._ID_HOMING = 2;

BulletFactory.prototype.BulletManager = BulletManager.prototype;

Bullet.prototype._ID = BulletManager.prototype._ID_BULLET;
Laser.prototype._ID  = BulletManager.prototype._ID_LASER;
Homing.prototype._ID = BulletManager.prototype._ID_HOMING;


================================================
FILE: source/CharacterSelectState.js
================================================
function CharacterSelectState( game ) {
  this.parent = GameState ;
  this.parent.call( this, game ) ;
  this.elements = [ ] ;
  this.index = 0 ;
  this.count = 0 ;
}
__inherit( CharacterSelectState, GameState ) ;


CharacterSelectState._APPEAR_SPAN = 10 ;

CharacterSelectState.prototype.init = function( ) {
  this.count = 0 ;
  // TODO: magic number
  for( var i = 0; i < 2; i++ ) {
    this.elements[ i ] = { } ;
    this.elements[ i ].width = 400 ;
    this.elements[ i ].height = 600 ;
  }
  this.index = 0 ;
} ;


CharacterSelectState.prototype.runStep = function( ) {
  this.count++ ;
} ;


CharacterSelectState.prototype.updateDisplay = function( surface ) {
  this.game.clear( surface ) ;
  this._displayBG( surface ) ;
  this._displayMessage( surface ) ;
  this._displayCharacters( surface ) ;
} ;


/**
 * TODO: temporal
 */
CharacterSelectState.prototype._displayBG = function( surface ) {
  surface.save( ) ;
  surface.fillStyle = 'rgb( 0, 0, 0 )' ;
  surface.fillRect( 0, 0, this.getWidth( ), this.getHeight( ) ) ;
  surface.fillStyle = 'rgb( 255, 255, 255 )' ;
  surface.fillRect( 0, 50, this.getWidth( ), this.getHeight( ) - 100 ) ;

  surface.globalAlpha = 0.05 ;
  surface.drawImage( this.game.getImage( Game._IMG_TITLE_BG ),
                     0,                 
                     0,
                     TitleState._WIDTH,
                     TitleState._HEIGHT,
                     0,
                     0,
                     this.getWidth( ),
                     this.getHeight( ) ) ;

  surface.restore( ) ;
} ;


CharacterSelectState.prototype._displayMessage = function( surface ) {
  surface.save( ) ;
  surface.font = "30px 'Comic Sans MS'" ;
  surface.textAlign = 'center' ;
  surface.textBaseAlign = 'middle' ;
  surface.fillStyle = 'rgb( 255, 255, 255 )' ;
  surface.fillText( 'Character Select', this.getWidth( ) / 2, 35 ) ;
  surface.restore( ) ;
} ;


CharacterSelectState.prototype._displayCharacters = function( surface ) {
  surface.save( ) ;
  if( this.index == 0 ) {
    surface.globalAlpha = 0.6 ;
    this._displayMarisa( surface ) ;
    surface.globalAlpha = 1.0 ;
    this._displayReimu( surface ) ;
  } else {
    surface.globalAlpha = 0.6 ;
    this._displayReimu( surface ) ;
    surface.globalAlpha = 1.0 ;
    this._displayMarisa( surface ) ;
  }
  surface.restore( ) ;
} ;


CharacterSelectState.prototype._displayReimu = function( surface ) {
  surface.save( ) ;
  var target = 0 ;
  var from = this.getWidth( ) ;
  var w = from - ( from - target ) * this.count / CharacterSelectState._APPEAR_SPAN ;
  if( w < target )
    w = target ;
  surface.drawImage( this.game.getImage( Game._IMG_STAND_REIMU ),
                     w,
                     0 ) ;
  surface.restore( ) ;
} ;


CharacterSelectState.prototype._displayMarisa = function( surface ) {
  surface.save( ) ;
  var target = this.getWidth( ) - this.elements[ 1 ].width ;
  var from = -this.elements[ 1 ].width ;
  var w = from - ( from - target ) * this.count / CharacterSelectState._APPEAR_SPAN ;
  if( w > target )
    w = target ;
  surface.drawImage( this.game.getImage( Game._IMG_STAND_MARISA ),
                     w,
                     0 ) ;
  surface.restore( ) ;
} ;


CharacterSelectState.prototype.handleKeyDown = function( e ) {
  // TODO: temporal
  if( this.count < CharacterSelectState._APPEAR_SPAN )
    return ;

  switch( e.keyCode ) {
    case 37: // left
      this.index++ ;
      if( this.index > 1 )
        this.index = 0 ;
      this._soundEffect( Game._SE_SELECT ) ;
      break ;
    case 39: // right
      this.index-- ;
      if( this.index < 0 )
        this.index = 1 ;
      this._soundEffect( Game._SE_SELECT ) ;
      break ;
    case 88: // x
      this.game.notifyLoadingConclusion( this.index ) ; // TODO: temporal
      break ;
    case 90: // z
      this.game.notifyCharacterSelectConclusion( this.index ) ;
      break ;
  } ;
} ;


CharacterSelectState.prototype.handleKeyUp = function( e ) {

} ;


================================================
FILE: source/Effect.js
================================================
/**
 * TODO: optimize this file.
 *       some codes and parameters are no longer used
 *       because of the design change.
 */

/**
 * Effect represents an element which just shows on a screen,
 * and not affect any other elements.
 */
function EffectManager(gameState) {
  this.parent = ElementManager;
  this.parent.call(this, gameState);
};
__inherit(EffectManager, ElementManager);

// only for reference
EffectManager.prototype.Layer = Layer;
EffectManager.prototype.Math = Math;

EffectManager.prototype._MAX_NUM = 200; // TODO: for each so far


EffectManager.prototype._initMaxNum = function() {
  return this._MAX_NUM;
};


EffectManager.prototype._initFactory = function() {
  this.factory = new EffectFactory(this.gameState,
                                   this.gameState.getWidth(),
                                   this.gameState.getHeight());
};



/**
 * TODO: consider the design. To use drawers is easy to handle,
 *       but not smart. To extend Drawer could be smarter and
 *       performance could be better.
 */
EffectManager.prototype.initDrawer = function(layer, image) {
  this.drawers = [];
  this.drawers.push(this._generateShockWaveDrawer(layer));
  this.drawers.push(this._generateGrazeDrawer(layer));
  this.drawers.push(this._generateExplosionDrawer(layer));
  this.drawers.push(this._generateDamageDrawer(layer));
  this.drawers.push(this._generateBigShockWaveDrawer(layer));
  this.drawers.push(this._generateBigExplosionDrawer(layer));
};


EffectManager.prototype._generateShockWaveDrawer = function(layer) {
  return new ShockWaveDrawer(this, layer,
                             this._generateShockWaveImage());
};


EffectManager.prototype._generateGrazeDrawer = function(layer) {
  return new GrazeDrawer(this, layer,
                         this._generateGrazeImage());
};


EffectManager.prototype._generateExplosionDrawer = function(layer) {
  return new ExplosionDrawer(this, layer,
                             this._generateExplosionImage());
};


EffectManager.prototype._generateBigShockWaveDrawer = function(layer) {
  return new BigShockWaveDrawer(this, layer,
                                this._generateBigShockWaveImage());
};


EffectManager.prototype._generateBigExplosionDrawer = function(layer) {
  return new BigExplosionDrawer(this, layer,
                                this._generateBigExplosionImage());
};


EffectManager.prototype._generateDamageDrawer = function(layer) {
  return new DamageDrawer(this, layer,
                          this._generateDamageImage());
};


/**
 * create ShockWaveEffect.
 * TODO: rename or combine with other create methods.
 */
EffectManager.prototype.create = function(element, type, params) {
  this.addElement(this.factory.create(element, type, params));
};


/**
 * TODO: temporal. combine with create()?
 */
EffectManager.prototype.createGraze = function(element, params) {
  this.addElement(this.factory.createGraze(element, params));
};


/**
 * TODO: temporal. combine with create()?
 */
EffectManager.prototype.createDamageEffect = function(enemy) {
  this.addElement(this.factory.createDamageEffect(enemy));
};


/**
 * TODO: temporal. combine with create()?
 */
EffectManager.prototype.createExplosion = function(enemy) {
  this.addElement(this.factory.createExplosion(enemy));
};


/**
 * TODO: temporal. combine with create()?
 */
EffectManager.prototype.createBigShockWave = function(enemy, type, params) {
  this.addElement(this.factory.createBigShockWave(enemy, type, params));
};


/**
 * TODO: temporal. combine with create()?
 */
EffectManager.prototype.createBigExplosion = function(enemy) {
  this.addElement(this.factory.createBigExplosion(enemy));
};


/**
 * TODO: should move into ShockWave?
 */
EffectManager.prototype._generateShockWaveImage = function() {
  var cvs = document.createElement('canvas');
  cvs.width = this.Layer.calculateSquareValue(this.ShockWaveEffect._WIDTH);
  cvs.height = this.Layer.calculateSquareValue(
                 this.ShockWaveEffect._HEIGHT*this.ShockWaveEffect._END_COUNT);
  var ctx = cvs.getContext('2d');

  var w = this.ShockWaveEffect._WIDTH;
  var h = this.ShockWaveEffect._HEIGHT;
  for(var i = 0; i < this.ShockWaveEffect._END_COUNT; i++) {
    var x = w/2;
    var y = h*i + h/2;
    var r = this.ShockWaveEffect._SPEED * i;
    var s = 1 - this.ShockWaveEffect._GRADATION/(this.ShockWaveEffect._SPEED*i);

    if(r <= 1)
      r = 1;
    if(s < 0)
      s = 0.0;

    ctx.beginPath();
    var g = ctx.createRadialGradient(x, y, 0, x, y, r);
    g.addColorStop(s, 'rgba(255, 255, 255, 0.0)');
    g.addColorStop(1.00, 'rgba(255, 255, 255, 1.0)');
    ctx.fillStyle = g;
    ctx.arc(x, y, r, 0, this.Math.PI * 2);
    ctx.fill();
  }
  return cvs;
};


/**
 * TODO: should move into Graze?
 */
EffectManager.prototype._generateGrazeImage = function() {
  var cvs = document.createElement('canvas');
  cvs.width = this.Layer.calculateSquareValue(this.GrazeEffect._SIZE);
  cvs.height = this.Layer.calculateSquareValue(this.GrazeEffect._SIZE);
  var ctx = cvs.getContext('2d');

  var w = this.GrazeEffect._SIZE;
  var h = this.GrazeEffect._SIZE;
  ctx.fillStyle = 'rgb(255, 255, 255)';
  ctx.fillRect(0, 0, w, h);
  return cvs;
};


/**
 * TODO: should move into Explosion?
 */
EffectManager.prototype._generateExplosionImage = function() {
  var cvs = document.createElement('canvas');
  cvs.width = this.Layer.calculateSquareValue(this.ExplosionEffect._WIDTH);
  cvs.height = this.Layer.calculateSquareValue(
                 this.ExplosionEffect._HEIGHT*this.ExplosionEffect._END_COUNT);
  var ctx = cvs.getContext('2d');

  var w = this.ExplosionEffect._WIDTH;
  var h = this.ExplosionEffect._HEIGHT;
  for(var i = 0; i < this.ExplosionEffect._END_COUNT; i++) {
    var x = w/2;
    var y = h*i + h/2;
    var r = w/2 * i/this.ExplosionEffect._END_COUNT - 2;
    if(r <= 1)
      r = 1;

    ctx.beginPath();
    ctx.fillStyle = 'rgb(255, 255, 255)';
    ctx.globalAlpha = 0.5;
    ctx.arc(x, y, r, 0, this.Math.PI * 2);
    ctx.fill();

    ctx.beginPath();
    ctx.strokeStyle = 'rgb(255, 255, 255)';
    ctx.globalAlpha = 1;
    ctx.lineWidth = 4;
    ctx.arc(x, y, r, 0, this.Math.PI * 2);
    ctx.stroke();
  }
  return cvs;
};


/**
 * TODO: should move into DamageEffect?
 */
EffectManager.prototype._generateDamageImage = function() {
  var cvs = document.createElement('canvas');
  cvs.width = this.Layer.calculateSquareValue(this.DamageEffect._WIDTH);
  cvs.height = this.Layer.calculateSquareValue(this.DamageEffect._HEIGHT);
  var ctx = cvs.getContext('2d');

  var w = this.DamageEffect._WIDTH;
  var h = this.DamageEffect._HEIGHT;
  var x = w/2;
  var y = h/2;
  var r = w/2-4;

  ctx.beginPath();
  ctx.fillStyle = 'rgb(255, 255, 255)';
  ctx.globalAlpha = 0.5;
  ctx.arc(x, y, r, 0, this.Math.PI * 2);
  ctx.fill();

  return cvs;
};


/**
 * TODO: should move into BigShockWave?
 * TODO: can share the logic with _generateShockWaveImage()?
 */
EffectManager.prototype._generateBigShockWaveImage = function() {
  var cvs = document.createElement('canvas');
  cvs.width = this.Layer.calculateSquareValue(this.BigShockWaveEffect._WIDTH);
  cvs.height = this.Layer.calculateSquareValue(this.BigShockWaveEffect._HEIGHT);
  var ctx = cvs.getContext('2d');

  var w = this.BigShockWaveEffect._WIDTH;
  var h = this.BigShockWaveEffect._HEIGHT;
  var x = w/2;
  var y
Download .txt
gitextract_2g3v46sm/

├── README.md
├── TODO.txt
├── data/
│   ├── bosses_params.js
│   ├── bullets_params.js
│   ├── danmaku_helper.js
│   ├── enemies_params.js
│   ├── stage_params.js
│   └── talk_params.js
├── index.html
├── index2.html
├── replay/
│   ├── replay1.txt
│   ├── replay2.txt
│   └── replay_list.txt
├── source/
│   ├── Background.js
│   ├── Bomb.js
│   ├── Boss.js
│   ├── Bullet.js
│   ├── CharacterSelectState.js
│   ├── Effect.js
│   ├── Element.js
│   ├── EndingState.js
│   ├── Enemy.js
│   ├── EnemyBullet.js
│   ├── Fighter.js
│   ├── FighterOption.js
│   ├── Game.js
│   ├── GameSocket.js
│   ├── GameState.js
│   ├── Item.js
│   ├── LoadingState.js
│   ├── MoveVector.js
│   ├── OpeningState.js
│   ├── PostReplayState.js
│   ├── ReplaySelectState.js
│   ├── SpellCard.js
│   ├── StaffRollState.js
│   └── StageState.js
├── utility/
│   ├── Draw.js
│   ├── FreeList.js
│   ├── Inherit.js
│   ├── Peer.js
│   ├── Random.js
│   └── WebGL.js
├── webgl_test.html
├── webrtc_test.html
└── webrtc_trial.html
Download .txt
SYMBOL INDEX (130 symbols across 31 files)

FILE: data/danmaku_helper.js
  function DanmakuHelper (line 1) | function DanmakuHelper( ) {

FILE: source/Background.js
  function BackgroundManager (line 1) | function BackgroundManager(gameState) {
  function BackgroundView (line 125) | function BackgroundView(element) {
  function BackgroundDrawer (line 172) | function BackgroundDrawer(elementManager, gl, image) {
  function Background (line 214) | function Background(gameState, maxX, maxY) {

FILE: source/Bomb.js
  function BombManager (line 1) | function BombManager( gameState ) {
  function BombFactory (line 35) | function BombFactory( gameState, maxX, maxY ) {
  function BombFreeList (line 89) | function BombFreeList( num, gameState ) {
  function BombDrawer (line 102) | function BombDrawer(elementManager, layer, image) {
  function BombView (line 116) | function BombView(element) {
  function Bomb (line 128) | function Bomb( gameState, maxX, maxY ) {

FILE: source/Boss.js
  function BossManager (line 1) | function BossManager( gameState, params ) {
  function BossFactory (line 190) | function BossFactory( gameState, maxX, maxY ) {
  function BossFreeList (line 220) | function BossFreeList( num, gameState ) {
  function BossDrawer (line 232) | function BossDrawer(elementManager, layer, image) {
  function BossView (line 240) | function BossView(element) {
  function Boss (line 297) | function Boss( gameState, maxX, maxY ) {

FILE: source/Bullet.js
  function BulletManager (line 1) | function BulletManager( gameState, params ) {
  function BulletFactory (line 107) | function BulletFactory( gameState, maxX, maxY ) {
  function BulletFreeList (line 181) | function BulletFreeList( num, gameState ) {
  function BulletDrawer (line 194) | function BulletDrawer(elementManager, layer, image) {
  function BulletView (line 201) | function BulletView(element) {
  function Bullet (line 210) | function Bullet( gameState, maxX, maxY ) {
  function LaserFreeList (line 267) | function LaserFreeList( num, gameState ) {
  function LaserView (line 283) | function LaserView(element) {
  function Laser (line 347) | function Laser( gameState, maxX, maxY ) {
  function HomingFreeList (line 456) | function HomingFreeList( num, gameState ) {
  function Homing (line 472) | function Homing( gameState, maxX, maxY ) {

FILE: source/CharacterSelectState.js
  function CharacterSelectState (line 1) | function CharacterSelectState( game ) {

FILE: source/Effect.js
  function EffectManager (line 11) | function EffectManager(gameState) {
  function EffectFactory (line 325) | function EffectFactory(gameState, maxX, maxY) {
  function ShockWaveEffectFreeList (line 480) | function ShockWaveEffectFreeList( num, gameState ) {
  function ShockWaveDrawer (line 495) | function ShockWaveDrawer(elementManager, layer, image) {
  function ShockWaveView (line 508) | function ShockWaveView(element) {
  function ShockWaveEffect (line 535) | function ShockWaveEffect( gameState, maxX, maxY ) {
  function BigShockWaveEffectFreeList (line 703) | function BigShockWaveEffectFreeList(num, gameState) {
  function BigShockWaveDrawer (line 718) | function BigShockWaveDrawer(elementManager, layer, image) {
  function BigShockWaveView (line 731) | function BigShockWaveView(element) {
  function BigShockWaveEffect (line 764) | function BigShockWaveEffect(gameState, maxX, maxY) {
  function ExplosionEffectFreeList (line 846) | function ExplosionEffectFreeList(num, gameState) {
  function ExplosionDrawer (line 860) | function ExplosionDrawer(elementManager, layer, image) {
  function ExplosionView (line 873) | function ExplosionView(element) {
  function ExplosionEffect (line 897) | function ExplosionEffect(gameState, maxX, maxY) {
  function GrazeDrawer (line 997) | function GrazeDrawer(elementManager, layer, image) {
  function GrazeView (line 1010) | function GrazeView(element) {
  function GrazeEffectFreeList (line 1028) | function GrazeEffectFreeList(num, gameState) {
  function GrazeEffect (line 1043) | function GrazeEffect(gameState, maxX, maxY) {
  function DamageEffectFreeList (line 1145) | function DamageEffectFreeList( num, gameState ) {
  function DamageDrawer (line 1158) | function DamageDrawer(elementManager, layer, image) {
  function DamageView (line 1171) | function DamageView(element) {
  function DamageEffect (line 1193) | function DamageEffect( gameState, maxX, maxY ) {
  function BigExplosionEffectFreeList (line 1305) | function BigExplosionEffectFreeList(num, gameState) {
  function BigExplosionDrawer (line 1320) | function BigExplosionDrawer(elementManager, layer, image) {
  function BigExplosionView (line 1333) | function BigExplosionView(element) {
  function BigExplosionEffect (line 1366) | function BigExplosionEffect(gameState, maxX, maxY) {

FILE: source/Element.js
  function ElementManager (line 4) | function ElementManager(gameState) {
  function ElementFactory (line 167) | function ElementFactory( gameState, maxX, maxY ) {
  function ElementFreeList (line 206) | function ElementFreeList( num, gameState ) {
  function ElementView (line 227) | function ElementView(element) {
  function ElementDrawer (line 464) | function ElementDrawer(e, layer, image) {
  function Element (line 682) | function Element( gameState, maxX, maxY ) {

FILE: source/EndingState.js
  function EndingState (line 1) | function EndingState( game ) {

FILE: source/Enemy.js
  function EnemyManager (line 1) | function EnemyManager( gameState, params ) {
  function EnemyFactory (line 101) | function EnemyFactory( gameState, maxX, maxY ) {
  function EnemyFreeList (line 137) | function EnemyFreeList( num, gameState ) {
  function EnemyDrawer (line 150) | function EnemyDrawer(elementManager, layer, image) {
  function EnemyView (line 158) | function EnemyView(element) {
  function Enemy (line 184) | function Enemy( gameState, maxX, maxY ) {

FILE: source/EnemyBullet.js
  function EnemyBulletManager (line 1) | function EnemyBulletManager( gameState, params ) {
  function EnemyBulletFactory (line 218) | function EnemyBulletFactory( gameState, maxX, maxY ) {
  function EnemyBulletFreeList (line 312) | function EnemyBulletFreeList( num, gameState ) {
  function EnemyBulletDrawer (line 325) | function EnemyBulletDrawer(elementManager, layer, image) {
  function EnemyBulletView (line 338) | function EnemyBulletView(element) {
  function EnemyBullet (line 346) | function EnemyBullet( gameState, maxX, maxY ) {
  function EnemyLaserFreeList (line 385) | function EnemyLaserFreeList( num, gameState ) {
  function EnemyLaserView (line 398) | function EnemyLaserView(element) {
  function EnemyLaser (line 459) | function EnemyLaser( gameState, maxX, maxY ) {
  function EnemyBeamFreeList (line 691) | function EnemyBeamFreeList(num, gameState) {
  function EnemyBeamDrawer (line 712) | function EnemyBeamDrawer(elementManager, layer, image) {
  function EnemyBeamView (line 725) | function EnemyBeamView(element) {
  function EnemyBeam (line 876) | function EnemyBeam(gameState, maxX, maxY, hFreelist, pFreelist) {
  function EnemyBeamHistoryFreeList (line 1098) | function EnemyBeamHistoryFreeList( num ) {
  function EnemyBeamPositionFreeList (line 1119) | function EnemyBeamPositionFreeList( num ) {

FILE: source/Fighter.js
  function FighterManager (line 4) | function FighterManager(gameState) {
  function FighterDrawer (line 128) | function FighterDrawer(elementManager, layer, image) {
  function FighterView (line 139) | function FighterView(element) {
  function Fighter (line 168) | function Fighter(gameState, maxX, maxY, image, id) {

FILE: source/FighterOption.js
  function FighterOptionManager (line 1) | function FighterOptionManager(gameState, fighters) {
  function FighterOptionFactory (line 84) | function FighterOptionFactory( gameState, maxX, maxY ) {
  function FighterOptionFreeList (line 110) | function FighterOptionFreeList( num, gameState ) {
  function FighterOptionDrawer (line 124) | function FighterOptionDrawer(elementManager, layer, image) {
  function FighterOptionView (line 132) | function FighterOptionView(element) {
  function FighterOption (line 178) | function FighterOption(gameState, maxX, maxY) {

FILE: source/Game.js
  function Game (line 1) | function Game(mainCanvas, bgCanvas) {

FILE: source/GameSocket.js
  function GameSocket (line 4) | function GameSocket(game) {

FILE: source/GameState.js
  function GameState (line 1) | function GameState( game ) {

FILE: source/Item.js
  function ItemManager (line 1) | function ItemManager( gameState ) {
  function ItemFactory (line 83) | function ItemFactory( gameState, maxX, maxY ) {
  function ItemFreeList (line 124) | function ItemFreeList( num, gameState ) {
  function ItemDrawer (line 137) | function ItemDrawer(elementManager, layer, image) {
  function ItemView (line 145) | function ItemView(element) {
  function Item (line 165) | function Item( gameState, maxX, maxY ) {

FILE: source/LoadingState.js
  function LoadingState (line 1) | function LoadingState( game ) {

FILE: source/MoveVector.js
  function MoveVectorManager (line 1) | function MoveVectorManager( ) {
  function MoveVectorFactory (line 34) | function MoveVectorFactory( num ) {
  function MoveVectorFreeList (line 61) | function MoveVectorFreeList( num ) {
  function MoveVector (line 79) | function MoveVector( ) {

FILE: source/OpeningState.js
  function OpeningState (line 1) | function OpeningState( game ) {

FILE: source/PostReplayState.js
  function PostReplayState (line 1) | function PostReplayState( game ) {

FILE: source/ReplaySelectState.js
  function ReplaySelectState (line 1) | function ReplaySelectState( game ) {

FILE: source/SpellCard.js
  function SpellCardManager (line 5) | function SpellCardManager( gameState ) {
  function SpellCardFactory (line 23) | function SpellCardFactory( gameState, maxX, maxY ) {
  function SpellCardFreeList (line 79) | function SpellCardFreeList( num, gameState ) {
  function SpellCard (line 96) | function SpellCard( gameState, maxX, maxY ) {

FILE: source/StaffRollState.js
  function StaffRollState (line 1) | function StaffRollState( game ) {

FILE: source/StageState.js
  function StageState (line 1) | function StageState( game ) {
  function KeyFlagQueue (line 1251) | function KeyFlagQueue() {
  function StageAbstractState (line 1344) | function StageAbstractState( stage ) {
  function ShootingState (line 1400) | function ShootingState(stage) {
  function TalkState (line 1493) | function TalkState( stage ) {
  function ClearState (line 1638) | function ClearState( stage ) {
  function GameOverState (line 1727) | function GameOverState( stage ) {

FILE: utility/Draw.js
  function __drawComplexRect (line 4) | function __drawComplexRect( surface, image, p, width, height,
  function __toBase64Pdf (line 61) | function __toBase64Pdf( image ) {

FILE: utility/FreeList.js
  function FreeList (line 4) | function FreeList( num ) {

FILE: utility/Inherit.js
  function __inherit (line 4) | function __inherit( child, parent ) {
  function __copyParentMethod (line 18) | function __copyParentMethod(child, parent, methodName) {

FILE: utility/Peer.js
  function Peer (line 4) | function Peer(room, wsURL, receiver) {

FILE: utility/Random.js
  function Randomizer (line 1) | function Randomizer() {

FILE: utility/WebGL.js
  function Layer (line 1) | function Layer(canvas) {
Condensed preview — 46 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (539K chars).
[
  {
    "path": "README.md",
    "chars": 1248,
    "preview": "# toho-like-js\n\nThis is a touhou style danmaku shooter game which runs on your chrome.\n\n## Demo\n[Demo](http://takahirox."
  },
  {
    "path": "TODO.txt",
    "chars": 252,
    "preview": "stage2\n  - bgm\n  - bg\nboss finish bonus\nboss time limit\nspell card finish bonus\nvanish bullet\n\nenemy variation\nBoss effe"
  },
  {
    "path": "data/bosses_params.js",
    "chars": 9160,
    "preview": "var __stage1BossParams = [ ] ;\n\n__stage1BossParams.push(\n  {\n    'count': 2100,\n    'character': 'rumia',\n    'width': 1"
  },
  {
    "path": "data/bullets_params.js",
    "chars": 39362,
    "preview": "var __danmakuHelper = new DanmakuHelper( ) ;\n\nvar __bulletTypes = [\n  {\n    'image':            0,\n    'indexX':        "
  },
  {
    "path": "data/danmaku_helper.js",
    "chars": 3283,
    "preview": "function DanmakuHelper( ) {\n\n}\n\nDanmakuHelper.prototype._calculateRadian = function( theta ) {\n  return theta * Math.PI "
  },
  {
    "path": "data/enemies_params.js",
    "chars": 20791,
    "preview": "var __stage1EnemiesParams = [ ] ;\n\n\n/*\n__stage1EnemiesParams.push(\n  { 'count': 100,\n    'x': 240,\n    'y': 100,\n    'vi"
  },
  {
    "path": "data/stage_params.js",
    "chars": 612,
    "preview": "var __stage1Params = {\n  'title': 'Nothing Special',\n  'bgScale': [\n    { 'beginCount':    0, 'endCount':    1, 'a': 0.5"
  },
  {
    "path": "data/talk_params.js",
    "chars": 3094,
    "preview": "var __reimuBossTalkParams = [ ] ;\nvar __marisaBossTalkParams = [ ] ;\n\n__reimuBossTalkParams.push(\n  { 'serif': 'Hi, how\\"
  },
  {
    "path": "index.html",
    "chars": 5575,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<title>Toho like shooting with JavaScript</title>\n<script type=\"tex"
  },
  {
    "path": "index2.html",
    "chars": 8526,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<title>Toho like shooting with JavaScript</title>\n<script type=\"tex"
  },
  {
    "path": "replay/replay1.txt",
    "chars": 14951,
    "preview": "{\n  user: 'takahirox',\n  characterIndex: 0,\n  seed: 57914,\n  params: [\n    {count: 34, z: true},\n    {count: 46, l: true"
  },
  {
    "path": "replay/replay2.txt",
    "chars": 35846,
    "preview": "{\n  user: 'takahirox',\n  characterIndex: 1,\n  seed: 11249,\n  params: [\n    {count: 26, d: true},\n    {count: 33, d: fals"
  },
  {
    "path": "replay/replay_list.txt",
    "chars": 155,
    "preview": "[\n  { id: 1, user: 'takahirox', characterIndex: 0, datetime: 1381201800000 },\n  { id: 2, user: 'takahirox', characterInd"
  },
  {
    "path": "source/Background.js",
    "chars": 5934,
    "preview": "function BackgroundManager(gameState) {\n  this.parent = ElementManager;\n  this.parent.call(this, gameState);\n  this.acti"
  },
  {
    "path": "source/Bomb.js",
    "chars": 4170,
    "preview": "function BombManager( gameState ) {\n  this.parent = ElementManager ;\n  this.parent.call( this, gameState ) ;\n}\n__inherit"
  },
  {
    "path": "source/Boss.js",
    "chars": 16013,
    "preview": "function BossManager( gameState, params ) {\n  this.parent = ElementManager ;\n  this.parent.call( this, gameState ) ;\n  f"
  },
  {
    "path": "source/Bullet.js",
    "chars": 17341,
    "preview": "function BulletManager( gameState, params ) {\n  this.parent = ElementManager ;\n  this.parent.call( this, gameState ) ;\n "
  },
  {
    "path": "source/CharacterSelectState.js",
    "chars": 3969,
    "preview": "function CharacterSelectState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n  this.elements ="
  },
  {
    "path": "source/Effect.js",
    "chars": 36912,
    "preview": "/**\n * TODO: optimize this file.\n *       some codes and parameters are no longer used\n *       because of the design ch"
  },
  {
    "path": "source/Element.js",
    "chars": 34959,
    "preview": "/**\n * TODO: should rename Element to Entity?\n */\nfunction ElementManager(gameState) {\n  this.gameState = gameState;\n  t"
  },
  {
    "path": "source/EndingState.js",
    "chars": 1347,
    "preview": "function EndingState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n  this.count = 0 ;\n}\n__inh"
  },
  {
    "path": "source/Enemy.js",
    "chars": 7437,
    "preview": "function EnemyManager( gameState, params ) {\n  this.parent = ElementManager ;\n  this.parent.call( this, gameState ) ;\n  "
  },
  {
    "path": "source/EnemyBullet.js",
    "chars": 30179,
    "preview": "function EnemyBulletManager( gameState, params ) {\n  this.parent = ElementManager ;\n  this.parent.call( this, gameState "
  },
  {
    "path": "source/Fighter.js",
    "chars": 10225,
    "preview": "/**\n * care for two players in the future.\n */\nfunction FighterManager(gameState) {\n  this.parent = ElementManager;\n  th"
  },
  {
    "path": "source/FighterOption.js",
    "chars": 7366,
    "preview": "function FighterOptionManager(gameState, fighters) {\n  this.parent = ElementManager;\n  this.parent.call(this, gameState)"
  },
  {
    "path": "source/Game.js",
    "chars": 18243,
    "preview": "function Game(mainCanvas, bgCanvas) {\n  this.gs = new GameSocket(this);\n  this.gs.connect();\n\n  this.surface = mainCanva"
  },
  {
    "path": "source/GameSocket.js",
    "chars": 2946,
    "preview": "/**\n *  transferred data: state and activeNum.\n */\nfunction GameSocket(game) {\n  this.game = game;\n  this.ws = null;\n  t"
  },
  {
    "path": "source/GameState.js",
    "chars": 1446,
    "preview": "function GameState( game ) {\n  this.game = game ;\n  this.flags = 0 ;\n  this.state = 0 ;\n}\n\n\nGameState.prototype.init = f"
  },
  {
    "path": "source/Item.js",
    "chars": 5887,
    "preview": "function ItemManager( gameState ) {\n  this.parent = ElementManager ;\n  this.parent.call( this, gameState ) ;\n} ;\n__inher"
  },
  {
    "path": "source/LoadingState.js",
    "chars": 2144,
    "preview": "function LoadingState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n  this.loadImageNum = 0 ;"
  },
  {
    "path": "source/MoveVector.js",
    "chars": 4897,
    "preview": "function MoveVectorManager( ) {\n  this.elements = [ ] ;\n  this.factory = null ;\n  this._initFactory( ) ;\n}\n\nMoveVectorMa"
  },
  {
    "path": "source/OpeningState.js",
    "chars": 8319,
    "preview": "function OpeningState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n\n  this.initialized = fal"
  },
  {
    "path": "source/PostReplayState.js",
    "chars": 4533,
    "preview": "function PostReplayState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n  this.count = 0 ;\n  t"
  },
  {
    "path": "source/ReplaySelectState.js",
    "chars": 6006,
    "preview": "function ReplaySelectState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n  this.count = 0 ;\n "
  },
  {
    "path": "source/SpellCard.js",
    "chars": 4459,
    "preview": "/**\n * no plan to port this class to WebGL so far cuz\n * it cannot be performance critical.\n */\nfunction SpellCardManage"
  },
  {
    "path": "source/StaffRollState.js",
    "chars": 3386,
    "preview": "function StaffRollState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n  this.count = 0 ;\n  th"
  },
  {
    "path": "source/StageState.js",
    "chars": 47457,
    "preview": "function StageState( game ) {\n  this.parent = GameState ;\n  this.parent.call( this, game ) ;\n\n  this.fighter            "
  },
  {
    "path": "utility/Draw.js",
    "chars": 1726,
    "preview": "/**\n *\n */\nfunction __drawComplexRect( surface, image, p, width, height,\n                            ax, ay, awidth, ahe"
  },
  {
    "path": "utility/FreeList.js",
    "chars": 1521,
    "preview": "/**\n * This class manages object resources to reduce GC.\n */\nfunction FreeList( num ) {\n  this.num = num ;\n  this.head ="
  },
  {
    "path": "utility/Inherit.js",
    "chars": 581,
    "preview": "/**\n *\n */\nfunction __inherit( child, parent ) {\n  var getPrototype = function( p ) {\n    if( Object.create ) {\n      re"
  },
  {
    "path": "utility/Peer.js",
    "chars": 6139,
    "preview": "/**\n * TODO: optimize\n */\nfunction Peer(room, wsURL, receiver) {\n  this.room = room;\n  this.peopleInTheRoom = 0;\n  this."
  },
  {
    "path": "utility/Random.js",
    "chars": 669,
    "preview": "function Randomizer() {\n};\n\nRandomizer.prototype._xors = {\n  x: 123456789,\n  y: 362436069,\n  z: 521288629,\n  w: 88675123"
  },
  {
    "path": "utility/WebGL.js",
    "chars": 10582,
    "preview": "function Layer(canvas) {\n  this.canvas = canvas;\n  this.gl = this._initGl(canvas);\n  this.gl.clearColor(0.0, 0.0, 0.0, 1"
  },
  {
    "path": "webgl_test.html",
    "chars": 30742,
    "preview": "<!DOCTYPE HTML>\n<html lang=\"en\">\n<head>\n<title></title>\n<meta charset=\"utf-8\">\n<script type=\"text/javascript\" src=\"lib/g"
  },
  {
    "path": "webrtc_test.html",
    "chars": 33274,
    "preview": "<!DOCTYPE HTML>\n<html lang=\"en\">\n<head>\n<title></title>\n<meta charset=\"utf-8\">\n<script type=\"text/javascript\" src=\"lib/g"
  },
  {
    "path": "webrtc_trial.html",
    "chars": 2614,
    "preview": "<html>\n<head>\n<script type=\"text/javascript\" src=\"utility/Peer.js\"></script>\n<script type=\"text/javascript\">\nvar peer;\n/"
  }
]

About this extraction

This page contains the full source code of the takahirox/toho-like-js GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 46 files (504.2 KB), approximately 162.9k tokens, and a symbol index with 130 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!