[from now] 2013/03/12 01:25:15

diff --git a/src/animation.js b/src/animation.js
index a175681..8ddab28 100644
--- a/src/animation.js
+++ b/src/animation.js
@@ -121,6 +121,14 @@ define(["require", "exports"], function(require, exports) {
         var Vector = Common.Vector;
     })(exports.Common || (exports.Common = {}));
     var Common = exports.Common;
+    // Renderableインターフェースを実装した、何も行わないクラス
+    var NullRenderable = (function () {
+        function NullRenderable() { }
+        NullRenderable.prototype.render = function (context) {
+        };
+        return NullRenderable;
+    })();
+    exports.NullRenderable = NullRenderable;
     // 描画可能なオブジェクトの基底クラス
     var Symbol = (function () {
         // それぞれの値について、初期値を設定する責任は、このクラスを継承した先のクラスにある
diff --git a/src/animation.ts b/src/animation.ts
index f50ec25..c4bb1e6 100644
--- a/src/animation.ts
+++ b/src/animation.ts
@@ -95,6 +95,11 @@ export interface Renderable {
     render(context: Context): void;
 }

+// Renderableインターフェースを実装した、何も行わないクラス
+export class NullRenderable implements Renderable {
+    render(context: Context) {}
+}
+
 // 描画可能なオブジェクトのインターフェース
 export interface Symbolize extends Renderable {
     // 図形における基準となる2D座標。
diff --git a/src/firework.js b/src/firework.js
index 52dc224..ed08472 100644
--- a/src/firework.js
+++ b/src/firework.js
@@ -12,16 +12,15 @@ define(["require", "exports", "util", "animation", "gameLib"], function(require,

     var I = util.Illiegals;
     // �I�u�W�F�N�g�̎��ʂ��\��
-    var ObjectType;
     (function (ObjectType) {
         ObjectType._map = [];
         ObjectType._map[0] = "Wall";
         ObjectType.Wall = 0;
         ObjectType._map[1] = "Star";
         ObjectType.Star = 1;
-    })(ObjectType || (ObjectType = {}));
+    })(exports.ObjectType || (exports.ObjectType = {}));
+    var ObjectType = exports.ObjectType;
     // �I�u�W�F�N�g�̏��Ԃ��\��
-    var ObjectState;
     (function (ObjectState) {
         ObjectState._map = [];
         ObjectState._map[0] = "Free";
@@ -34,7 +33,8 @@ define(["require", "exports", "util", "animation", "gameLib"], function(require,
         ObjectState.PrepareLaunch = 3;
         ObjectState._map[4] = "Launch";
         ObjectState.Launch = 4;
-    })(ObjectState || (ObjectState = {}));
+    })(exports.ObjectState || (exports.ObjectState = {}));
+    var ObjectState = exports.ObjectState;
     // B2Body��userData�ɓo�^��������
     var ObjectInfo = (function () {
         function ObjectInfo(type) {
@@ -42,238 +42,9 @@ define(["require", "exports", "util", "animation", "gameLib"], function(require,
             this.objectState = ObjectState.Free;
         }
         return ObjectInfo;
-    })();
-    // Star�ŗ��p�����Ă����e������
-    var StarUtil;
-    (function (StarUtil) {
-        var StarSize;
-        (function (StarSize) {
-            StarSize._map = [];
-            StarSize._map[0] = "Large";
-            StarSize.Large = 0;
-            StarSize._map[1] = "Medium";
-            StarSize.Medium = 1;
-            StarSize._map[2] = "Small";
-            StarSize.Small = 2;
-            StarSize._map[3] = "VerySmall";
-            StarSize.VerySmall = 3;
-        })(StarSize || (StarSize = {}));
-        // StarSize���烉���_���ł����ꂩ���擾����
-        function getSomeType() {
-            switch(Math.floor(Math.random() * 4)) {
-                case 0:
-                    return StarSize.Large;
-                case 1:
-                    return StarSize.Medium;
-                case 2:
-                    return StarSize.Small;
-                case 3:
-                    return StarSize.VerySmall;
-            }
-        }
-        function getSomeSize() {
-            switch(getSomeType()) {
-                case StarSize.Large:
-                    return 16;
-                case StarSize.Medium:
-                    return 14;
-                case StarSize.Small:
-                    return 12;
-                case StarSize.VerySmall:
-                    return 10;
-            }
-        }
-        StarUtil.getSomeSize = getSomeSize;
-    })(StarUtil || (StarUtil = {}));
+    })();
+    exports.ObjectInfo = ObjectInfo;
     (function (GameObj) {
-        // Star�ɌW�郍�W�b�N���ӂ̏������S�������B
-        // StarLogic���̂�Star�ɃR���|�W�V���������Ă��邪�A
-        // StarLogic�ɂ�Star���n�����Ă����B
-        var StarLogic = (function () {
-            function StarLogic(starShape, data) {
-                this.starShape = starShape;
-                this.data = data;
-                // �estar�ŋ��ʂ���FixtureDefinition
-                this._fixDef = (function () {
-                    var fix = new Box2D.Dynamics.b2FixtureDef();
-                    fix.density = 1.0// ���x
-                    ;
-                    fix.friction = 1.5// ���C�W��
-                    ;
-                    fix.restitution = 0.2// �����W��
-                    ;
-                    return fix;
-                })();
-                this.state = new ObjectInfo(ObjectType.Star);
-                this.scale = 1;
-            }
-            StarLogic.prototype.onreflect = function () {
-                var body = this.starShape.body;
-                var count = 0;
-                var contacts = [];
-                for(var n = body.GetContactList(); n != null; n = n.next) {
-                    if(n.contact.IsTouching()) {
-                        contacts.push(n.other);
-                    }
-                }
-                // �����m��4�ȏ��אڂ������Astatic�ɕύX�����B
-                if(contacts.length >= 4 && this.isConnectable()) {
-                    contacts.filter(function (e) {
-                        var info_e = e.GetUserData();
-                        return info_e.objectState == ObjectState.Free;
-                    }).forEach(function (e) {
-                        var info_e = e.GetUserData();
-                        info_e.objectState = ObjectState.Connected;
-                        if(body != e && info_e.type == ObjectType.Star) {
-                            e.SetType(Box2D.Dynamics.b2Body.b2_staticBody);
-                        }
-                    });
-                    body.SetType(Box2D.Dynamics.b2Body.b2_staticBody);
-                    var info = body.GetUserData();
-                    info.objectState = ObjectState.Connected;
-                    return false;
-                }
-                return true;
-            };
-            StarLogic.prototype.isConnectable = function () {
-                return this.state.objectState === ObjectState.Free;
-            };
-            StarLogic.prototype.ontouchstart = // �^�b�`���J�n�����ۂ̏����B
-            function (scene, e) {
-                var s = this.starShape;
-                if(this.state.objectState === ObjectState.Connected) {
-                    s.x -= s.width;
-                    s.y -= s.height;
-                    this.data.radius *= 2;
-                    s.width *= 2;
-                    s.height *= 2;
-                    this.data.color.a = 0.3;
-                    this.state.objectState = ObjectState.Touched;
-                }
-                return true;
-            };
-            StarLogic.prototype.ontouchend = // �^�b�`���ė����ꂽ�Ƃ��A���̎��_�ł̗̈��ɂ������Ă��鐯��
-            // �����āA���g���g�傷���B
-            // �������A�̈����ɁA���ł�Launch���ԂɂȂ��Ă������̂������ꍇ��
-            // ���ɖ߂��B
-            function (scene, e) {
-                var _this = this;
-                if(this.state.objectState !== ObjectState.Touched) {
-                    return false;
-                }
-                var s = this.starShape;
-                var contain = scene.entities.filter(function (elem) {
-                    if(elem === s) {
-                        return false;
-                    }
-                    return _this.starShape.within(elem, _this.data.radius);
-                });
-                if(contain.length === 0) {
-                    this.data.radius /= 2;
-                    s.width /= 2;
-                    s.height /= 2;
-                    this.state.objectState = ObjectState.Connected;
-                    return false;
-                }
-                contain.forEach(function (elem) {
-                    scene.removeEntity(elem);
-                });
-                // ���̂̏������X�V�����B
-                s.body.SetType(Box2D.Dynamics.b2Body.b2_dynamicBody);
-                s.body.DestroyFixture(s.body.GetFixtureList());
-                var fixDef = this._fixDef;
-                fixDef.shape = new Box2D.Collision.Shapes.b2CircleShape(this.data.radius / this.scale);
-                s.body.CreateFixture(fixDef);
-                // �����i�K�͏I���Ƃ���
-                this.state.objectState = ObjectState.PrepareLaunch;
-                return true;
-            };
-            StarLogic.prototype.createFixture = // �n���ꂽstar�ɓK������body�̐ݒ����쐬�����B
-            function (scale) {
-                var fixDef = this._fixDef;
-                var bodyDef = new Box2D.Dynamics.b2BodyDef();
-                bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;
-                bodyDef.userData = this.state;
-                bodyDef.position.Set((this.data.x + this.data.width / 2) / scale, (this.data.y + this.data.height / 2) / scale);
-                bodyDef.angularVelocity = (Math.random() * 2 % 2 ? -1 : 1) * 10;
-                fixDef.shape = new Box2D.Collision.Shapes.b2CircleShape(this.data.width / 2 / scale);
-                this.scale = scale;
-                return {
-                    bodyDef: bodyDef,
-                    fixtureDef: fixDef
-                };
-            };
-            return StarLogic;
-        })();
-        // ���C���̃I�u�W�F�N�g�ƂȂ�Star
-        var Star = (function (_super) {
-            __extends(Star, _super);
-            function Star() {
-                        _super.call(this);
-                this.data = new animation.Renderer.Circle.Data(0, 0, StarUtil.getSomeSize());
-                this._renderer = new animation.Renderer.Circle.CircleRenderer(this.data);
-                this._logic = new StarLogic(this, this.data);
-                // �o�C���h���Ă���
-                I.propBind([
-                    I.binder("x"),
-                    I.binder("y"),
-                    I.binder("zIndex"),
-                    I.binder("width"),
-                    I.binder("height"),
-                    I.binder("visible"),
-                    I.binder("color")
-                ], this, this.data);
-            }
-            Star.prototype.isValid = function () {
-                return true;
-            };
-            Star.prototype.isConnectable = function () {
-                return this._logic.isConnectable();
-            };
-            Star.prototype.onreflect = // body�����f�[�^�𔽉f�������ۂɌĂяo�������R�[���o�b�N
-            function () {
-                return this._logic.onreflect();
-            };
-            Star.prototype.render = // star�������_�����O�����B�����_�����O�������̂́Acircle��render�ɔC�����B
-            function (context) {
-                var r = this.data.radius;
-                var grad = new animation.Gradation.Radial(context);
-                grad.from(this.x + r * 0.7, this.y + r * 0.5, 1).to(this.x + r, this.y + r, r);
-                var info = this.body.GetUserData();
-                // �A�����Ă����ꍇ�́A�D�F�x�[�X�̐F�ɂ��Ă��܂�
-                switch(this._logic.state.objectState) {
-                    case ObjectState.Connected:
-                        grad.colorStop(0.0, "#fff").colorStop(0.8, "#888").colorStop(1.0, "#000");
-                        break;
-                    case ObjectState.PrepareLaunch:
-                        grad.colorStop(0.0, this.data.color.toFillStyle()).colorStop(1.0, this.data.color.toFillStyle());
-                        break;
-                    default:
-                        grad.colorStop(0.0, "#fff").colorStop(0.5, this.data.color.toFillStyle()).colorStop(1.0, "#000");
-                }
-                this.data.gradient = grad;
-                this._renderer.render(context);
-            };
-            Star.prototype.createFixture = function (scale) {
-                return this._logic.createFixture(scale);
-            };
-            Star.prototype.makeTouchStartHandler = // ontouchstart�̃n���h�����쐬���ĕԂ��B
-            function (scene) {
-                var _this = this;
-                return function (e) {
-                    return _this._logic.ontouchstart(scene, e);
-                };
-            };
-            Star.prototype.makeTouchEndHandler = // ontouchend�̃n���h�����쐬���ĕԂ�
-            function (scene) {
-                var _this = this;
-                return function (e) {
-                    return _this._logic.ontouchend(scene, e);
-                };
-            };
-            return Star;
-        })(gl.BaseClasses.EntityImpl);
-        GameObj.Star = Star;
         var StarCaseOption = (function () {
             function StarCaseOption() {
                 // ���E���ǂ̕�
diff --git a/src/firework.ts b/src/firework.ts
index e1c44a3..01717da 100644
--- a/src/firework.ts
+++ b/src/firework.ts
@@ -11,13 +11,13 @@ export interface ObjectBase {
 }

 // IuWFNg̎íʂð\·
-enum ObjectType {
+export enum ObjectType {
     Wall,
     Star
 }

 // IuWFNg̏óԂð\·
-enum ObjectState {
+export enum ObjectState {
     Free,
     Connected,
     Touched,
@@ -26,248 +26,15 @@ enum ObjectState {
 }

 // B2BodyÌuserDataɓo^·éîñ
-class ObjectInfo {
+export class ObjectInfo {
     objectState: ObjectState;
     constructor(public type: ObjectType) { this.objectState = ObjectState.Free; }
 }

-// Starŗp³êĂ¢éeíîñ
-module StarUtil {
-
-    enum StarSize {
-        Large,
-        Medium,
-        Small,
-        VerySmall
-    }
-
-    // StarSize©烉_ł¢¸ꂩð擾·é
-    function getSomeType(): StarSize {
-        switch (Math.floor(Math.random() * 4)) {
-        case 0: return StarSize.Large;
-        case 1: return StarSize.Medium;
-        case 2: return StarSize.Small;
-        case 3: return StarSize.VerySmall;
-        }
-    }
-
-    export function getSomeSize(): number {
-        switch (getSomeType()) {
-        case StarSize.Large: return 16;
-        case StarSize.Medium: return 14;
-        case StarSize.Small: return 12;
-        case StarSize.VerySmall: return 10;
-        }
-    }
-}
-
-export interface IStar extends gl.Entity, gl.Physics.BodyBindable, ObjectBase {}

 export module GameObj {

-    // StarɌW郍WbNüӂ̏ðS·éB
-    // StarLogic©̂ÍStarɃR|WV³êĂ¢邪A
-    // StarLogicɂàStarªn³êĂ¢éB
-    class StarLogic {
-
-
-        // estarŋ¤ʂ·éFixtureDefinition
-        private _fixDef = (): B2FixtureDef => {
-            var fix = new Box2D.Dynamics.b2FixtureDef();
-            fix.density = 1.0;       // §x
-            fix.friction = 1.5;      // CW
-            fix.restitution = 0.2;   // ½­W
-            return fix;
-        } ();
-
-        state: ObjectInfo = new ObjectInfo(ObjectType.Star);
-        scale: number = 1;
-
-        constructor(public starShape: Star, public data: animation.Renderer.Circle.Data) { }
-
-        onreflect(): bool {
-            var body = this.starShape.body;
-            var count = 0;
-            var contacts = [];
-            for (var n = body.GetContactList(); n != null;
-                 n = n.next) {
-                if (n.contact.IsTouching()) {
-                    contacts.push(n.other);
-                }
-            }
-            // ¯¯mª4ȏãאڂµ½çAstaticɕύX·éB
-            if (contacts.length >= 4 && this.isConnectable()) {
-                contacts.filter((e) => {
-                    var info_e: ObjectInfo = e.GetUserData();
-                    return info_e.objectState == ObjectState.Free;
-                }).forEach((e) => {
-                    var info_e: ObjectInfo = e.GetUserData();
-                    info_e.objectState = ObjectState.Connected;
-                    if (body != e && info_e.type == ObjectType.Star) {
-                        e.SetType(Box2D.Dynamics.b2Body.b2_staticBody);
-                    }
-                });
-                body.SetType(Box2D.Dynamics.b2Body.b2_staticBody);
-                var info: ObjectInfo = body.GetUserData();
-                info.objectState = ObjectState.Connected;
-                return false;
-            }
-
-            return true;
-        }
-
-        isConnectable(): bool {
-            return this.state.objectState === ObjectState.Free;
-        }
-
-        // ^b`ðJnµ½ۂ̏B
-        ontouchstart(scene: gl.Scene, e: Event): bool {
-            var s = this.starShape;
-            if (this.state.objectState === ObjectState.Connected) {
-                s.x -= s.width;
-                s.y -= s.height;
-                this.data.radius *= 2;
-                s.width *= 2;
-                s.height *= 2;
-                this.data.color.a = 0.3;
-                this.state.objectState = ObjectState.Touched;
-            }
-            return true;
-        }
-
-        // ^b`µė£³ꂽƂ«A»̎_ł̗̈æɂ©©��Ă¢鐯ð
-        // ��µāA©gðg傷éB
-        // ½¾µA̈æàɁA·łÉLaunchóԂɂȂ��Ă¢éà̂ª éꍇÍ
-        // ³ɖ߂éB
-        ontouchend(scene: gl.Scene, e: Event): bool {
-
-            if (this.state.objectState !== ObjectState.Touched) {
-                return false;
-            }
-
-            var s = this.starShape;
-            var contain = scene.entities.filter((elem) => {
-                if (elem === s) return false;
-                return this.starShape.within(elem, this.data.radius);
-            });
-
-            // Lª��½ɑ¶݂µȂ¯ê΁A傫³����ɖ߂·B
-            if (contain.length === 0) {
-                this.data.radius /= 2;
-                s.width /= 2;
-                s.height /= 2;
-                this.state.objectState = ObjectState.Connected;
-                return false;
-            }
-
-            contain.forEach((elem) => {scene.removeEntity(elem);});
-
-            // ̂̏îñðXV·éB
-            s.body.SetType(Box2D.Dynamics.b2Body.b2_dynamicBody);
-            s.body.DestroyFixture(s.body.GetFixtureList());
-            var fixDef = this._fixDef;
-            fixDef.shape = new Box2D.Collision.Shapes.b2CircleShape(this.data.radius / this.scale);
-            s.body.CreateFixture(fixDef);
-
-            // õiK͏I¹Ƃ·é
-            this.state.objectState = ObjectState.PrepareLaunch;
-            return true;
-        }
-
-
-        // n³ꂽstarɓK·ébody̐ݒèð쐬·éB
-        createFixture(scale: number): gl.Physics.BodyDefinition {
-            var fixDef = this._fixDef;
-            var bodyDef = new Box2D.Dynamics.b2BodyDef();
-            bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;
-            bodyDef.userData = this.state;
-            bodyDef.position.Set((this.data.x + this.data.width / 2) / scale,
-                                 (this.data.y + this.data.height / 2) / scale);
-            bodyDef.angularVelocity = (Math.random() * 2 % 2 ? -1 : 1) * 10;
-            fixDef.shape = new Box2D.Collision.Shapes.b2CircleShape(this.data.width / 2 / scale);
-
-            this.scale = scale;
-            return { bodyDef: bodyDef, fixtureDef: fixDef };
-        }
-
-    }
-
-    // C̃IuWFNgƂȂéStar
-    export class Star extends gl.BaseClasses.EntityImpl implements IStar {
-
-        private _logic: StarLogic;
-        private _renderer: animation.Renderer.Circle.CircleRenderer;
-
-        body: B2Body;
-        private data: animation.Renderer.Circle.Data;
-
-        color:animation.Common.Color;
-
-        constructor() {
-            super();
-            this.data = new animation.Renderer.Circle.Data(0, 0, StarUtil.getSomeSize());
-            this._renderer = new animation.Renderer.Circle.CircleRenderer(this.data);
-
-            this._logic = new StarLogic(this, this.data);
-
-            // oChµĂ¨­
-            I.propBind([I.binder("x"), I.binder("y"), I.binder("zIndex"),
-                        I.binder("width"), I.binder("height"),
-                        I.binder("visible"), I.binder("color")], this, this.data);
-        }
-
-        isValid(): bool {
-            return true;
-        }
-
-        isConnectable(): bool { return this._logic.isConnectable(); }
-
-        // body©çf[^𔽉f³¹éۂɌĂяo³êéR[obN
-        onreflect(): bool { return this._logic.onreflect(); }
-
-        // star����_O·éB_O©̂́AcircleÌrenderɔC¹éB
-        render(context: animation.Context): void {
-
-            var r = this.data.radius;
-            var grad = new animation.Gradation.Radial(context);
-            grad.from(this.x + r * 0.7, this.y + r * 0.5, 1).to(this.x + r, this.y + r, r);
-            var info: ObjectInfo = this.body.GetUserData();
-
-            // AµĂ¢éꍇ́ADFx[X̐FɂµĂµ܂¤
-            switch (this._logic.state.objectState) {
-            case ObjectState.Connected:
-                grad.colorStop(0.0, "#fff").colorStop(0.8, "#888").colorStop(1.0, "#000");
-                break;
-            case ObjectState.PrepareLaunch:
-                grad.colorStop(0.0, this.data.color.toFillStyle()).colorStop(1.0, this.data.color.toFillStyle());
-                break;
-            default:
-                grad.colorStop(0.0, "#fff").colorStop(0.5, this.data.color.toFillStyle()).
-                    colorStop(1.0, "#000");
-            }
-            this.data.gradient = grad;
-            this._renderer.render(context);
-        }
-
-        createFixture(scale: number): gl.Physics.BodyDefinition {
-            return this._logic.createFixture(scale);
-        }
-
-        // ontouchstart̃nhð쐬µĕԂ·B
-        makeTouchStartHandler(scene: gl.Scene): (e: Event) => bool {
-            return (e: Event) => {
-                return this._logic.ontouchstart(scene, e);
-            }
-        }
-
-        // ontouchend̃nhð쐬µĕԂ·
-        makeTouchEndHandler(scene: gl.Scene): (e: Event) => bool {
-            return (e: Event) => {
-                return this._logic.ontouchend(scene, e);
-            }
-        }
-    }
-
+    export interface IStar extends gl.Entity, gl.Physics.BodyBindable, ObjectBase {}
     export interface IStarCase extends gl.Entity, gl.Physics.BodyBindable {}

     export class StarCaseOption {
diff --git a/src/gameLib.ts b/src/gameLib.ts
index 79bfeca..38e3c87 100644
--- a/src/gameLib.ts
+++ b/src/gameLib.ts
@@ -233,7 +233,7 @@ export module BaseClasses {
             if (distance === -1) {
                 // distanceが設定されない場合、互いのwidth/heightの平均値が利用される
                 distance = (one.width + other.width + one.height + other.height) / 4;
-            }
+             }

             // Entityのx/y座標は、すべて矩形の左上座標を表すため、一度それぞれの中心座標を計算する。
             var vec = animation.Common.Vector;
diff --git a/src/star.js b/src/star.js
new file mode 100644
index 0000000..d27a309
--- /dev/null
+++ b/src/star.js
@@ -0,0 +1,319 @@
+var __extends = this.__extends || function (d, b) {
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+define(["require", "exports", "util", "animation", "gameLib", "firework"], function(require, exports, __util__, __animation__, __gl__, __fw__) {
+    var util = __util__;
+
+    var animation = __animation__;
+
+    var gl = __gl__;
+
+    var fw = __fw__;
+
+    var I = util.Illiegals;
+    // Starで利用されている各種情報
+    var StarUtil;
+    (function (StarUtil) {
+        var StarSize;
+        (function (StarSize) {
+            StarSize._map = [];
+            StarSize._map[0] = "Large";
+            StarSize.Large = 0;
+            StarSize._map[1] = "Medium";
+            StarSize.Medium = 1;
+            StarSize._map[2] = "Small";
+            StarSize.Small = 2;
+            StarSize._map[3] = "VerySmall";
+            StarSize.VerySmall = 3;
+        })(StarSize || (StarSize = {}));
+        // StarSizeからランダムでいずれかを取得する
+        function getSomeType() {
+            switch(Math.floor(Math.random() * 4)) {
+                case 0:
+                    return StarSize.Large;
+                case 1:
+                    return StarSize.Medium;
+                case 2:
+                    return StarSize.Small;
+                case 3:
+                    return StarSize.VerySmall;
+            }
+        }
+        function getSomeSize() {
+            switch(getSomeType()) {
+                case StarSize.Large:
+                    return 16;
+                case StarSize.Medium:
+                    return 14;
+                case StarSize.Small:
+                    return 12;
+                case StarSize.VerySmall:
+                    return 10;
+            }
+        }
+        StarUtil.getSomeSize = getSomeSize;
+    })(StarUtil || (StarUtil = {}));
+    (function (GameObj) {
+        // Starに係るロジック周辺の処理を担当する。
+        // StarLogic自体はStarにコンポジションされているが、
+        // StarLogicにもStarが渡されている。
+        var StarLogic = (function () {
+            function StarLogic(starShape, data) {
+                this.starShape = starShape;
+                this.data = data;
+                // 各starで共通するFixtureDefinition
+                this._fixDef = (function () {
+                    var fix = new Box2D.Dynamics.b2FixtureDef();
+                    fix.density = 1.0// 密度
+                    ;
+                    fix.friction = 1.5// 摩擦係数
+                    ;
+                    fix.restitution = 0.2// 反発係数
+                    ;
+                    return fix;
+                })();
+                this.state = new fw.ObjectInfo(fw.ObjectType.Star);
+                this.scale = 1;
+            }
+            StarLogic.prototype.onreflect = function () {
+                var body = this.starShape.body;
+                var count = 0;
+                var contacts = [];
+                for(var n = body.GetContactList(); n != null; n = n.next) {
+                    if(n.contact.IsTouching()) {
+                        contacts.push(n.other);
+                    }
+                }
+                // 星同士が4つ以上隣接したら、staticに変更する。
+                if(contacts.length >= 4 && this.isConnectable()) {
+                    contacts.filter(function (e) {
+                        var info_e = e.GetUserData();
+                        return info_e.objectState == fw.ObjectState.Free;
+                    }).forEach(function (e) {
+                        var info_e = e.GetUserData();
+                        info_e.objectState = fw.ObjectState.Connected;
+                        if(body != e && info_e.type == fw.ObjectType.Star) {
+                            e.SetType(Box2D.Dynamics.b2Body.b2_staticBody);
+                        }
+                    });
+                    body.SetType(Box2D.Dynamics.b2Body.b2_staticBody);
+                    var info = body.GetUserData();
+                    info.objectState = fw.ObjectState.Connected;
+                    return false;
+                }
+                return true;
+            };
+            StarLogic.prototype.isConnectable = function () {
+                return this.state.objectState === fw.ObjectState.Free;
+            };
+            StarLogic.prototype.ontouchstart = // タッチを開始した際の処理。
+            function (scene, e) {
+                var s = this.starShape;
+                if(this.state.objectState === fw.ObjectState.Connected) {
+                    s.x -= s.width;
+                    s.y -= s.height;
+                    this.data.radius *= 2;
+                    s.width *= 2;
+                    s.height *= 2;
+                    this.data.color.a = 0.3;
+                    this.state.objectState = fw.ObjectState.Touched;
+                }
+                return true;
+            };
+            StarLogic.prototype.ontouchend = // タッチして離されたとき、その時点での領域にかかっている星を
+            // 消して、自身を拡大する。
+            // ただし、領域内に、すでにLaunch状態になっているものがある場合は
+            // 元に戻る。
+            function (scene, e) {
+                var _this = this;
+                if(this.state.objectState !== fw.ObjectState.Touched) {
+                    return false;
+                }
+                var s = this.starShape;
+                var contain = scene.entities.filter(function (elem) {
+                    if(elem === s) {
+                        return false;
+                    }
+                    return _this.starShape.within(elem, _this.data.radius);
+                });
+                // 広がった中に存在しなければ、大きさを元に戻す。
+                if(contain.length === 0) {
+                    this.data.radius /= 2;
+                    s.width /= 2;
+                    s.height /= 2;
+                    this.state.objectState = fw.ObjectState.Connected;
+                    return false;
+                }
+                contain.forEach(function (elem) {
+                    scene.removeEntity(elem);
+                });
+                // 剛体の情報を更新する。
+                s.body.SetType(Box2D.Dynamics.b2Body.b2_dynamicBody);
+                s.body.DestroyFixture(s.body.GetFixtureList());
+                var fixDef = this._fixDef;
+                fixDef.shape = new Box2D.Collision.Shapes.b2CircleShape(this.data.radius / this.scale);
+                s.body.CreateFixture(fixDef);
+                // 準備段階は終了とする
+                this.state.objectState = fw.ObjectState.PrepareLaunch;
+                return true;
+            };
+            StarLogic.prototype.createFixture = // 渡されたstarに適合するbodyの設定を作成する。
+            function (scale) {
+                var fixDef = this._fixDef;
+                var bodyDef = new Box2D.Dynamics.b2BodyDef();
+                bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;
+                bodyDef.userData = this.state;
+                bodyDef.position.Set((this.data.x + this.data.width / 2) / scale, (this.data.y + this.data.height / 2) / scale);
+                bodyDef.angularVelocity = (Math.random() * 2 % 2 ? -1 : 1) * 10;
+                fixDef.shape = new Box2D.Collision.Shapes.b2CircleShape(this.data.width / 2 / scale);
+                this.scale = scale;
+                return {
+                    bodyDef: bodyDef,
+                    fixtureDef: fixDef
+                };
+            };
+            return StarLogic;
+        })();
+        var Renderer;
+        (function (Renderer) {
+            // 通常状態のStarをレンダリングする。
+            var NormalStarRenderer = (function () {
+                function NormalStarRenderer(data) {
+                    this.data = data;
+                    this._renderer = new animation.Renderer.Circle.CircleRenderer(this.data);
+                }
+                NormalStarRenderer.prototype.render = function (context) {
+                    var r = this.data.radius;
+                    var d = this.data;
+                    var grad = new animation.Gradation.Radial(context);
+                    grad.from(d.x + r * 0.7, d.y + r * 0.5, 1).to(d.x + r, d.y + r, r);
+                    grad.colorStop(0.0, "#fff").colorStop(0.5, d.color.toFillStyle()).colorStop(1.0, "#000");
+                    d.gradient = grad;
+                    this._renderer.render(context);
+                };
+                return NormalStarRenderer;
+            })();
+            // 連結状態のStarをレンダリングする。
+            var ConnectedStarRenderer = (function () {
+                function ConnectedStarRenderer(data) {
+                    this.data = data;
+                    this._renderer = new animation.Renderer.Circle.CircleRenderer(this.data);
+                }
+                ConnectedStarRenderer.prototype.render = function (context) {
+                    var r = this.data.radius;
+                    var d = this.data;
+                    var grad = new animation.Gradation.Radial(context);
+                    grad.from(d.x + r * 0.7, d.y + r * 0.5, 1).to(d.x + r, d.y + r, r);
+                    grad.colorStop(0.0, "#fff").colorStop(0.8, "#888").colorStop(1.0, "#000");
+                    d.gradient = grad;
+                    this._renderer.render(context);
+                };
+                return ConnectedStarRenderer;
+            })();
+            // PrepareLaunch状態のレンダリングを行う。
+            var PrepareLaunchRenderer = (function () {
+                function PrepareLaunchRenderer(data) {
+                    this.data = data;
+                    this._renderer = new animation.Renderer.Circle.CircleRenderer(this.data);
+                }
+                PrepareLaunchRenderer.prototype.render = function (context) {
+                    var r = this.data.radius;
+                    var d = this.data;
+                    var grad = new animation.Gradation.Radial(context);
+                    grad.from(d.x + r * 0.7, d.y + r * 0.5, 1).to(d.x + r, d.y + r, r);
+                    grad.colorStop(0.0, d.color.toFillStyle()).colorStop(1.0, d.color.toFillStyle());
+                    this.data.gradient = grad;
+                    this._renderer.render(context);
+                };
+                return PrepareLaunchRenderer;
+            })();
+            // Starで利用するrenderの切り替えをコントロールするためのクラス
+            var StarRenderController = (function () {
+                function StarRenderController(data) {
+                    this.data = data;
+                    this._renderStock = [];
+                    this._renderStock.push({
+                        state: fw.ObjectState.Free,
+                        render: new NormalStarRenderer(data)
+                    });
+                    this._renderStock.push({
+                        state: fw.ObjectState.Touched,
+                        render: new NormalStarRenderer(data)
+                    });
+                    this._renderStock.push({
+                        state: fw.ObjectState.Connected,
+                        render: new ConnectedStarRenderer(data)
+                    });
+                    this._renderStock.push({
+                        state: fw.ObjectState.PrepareLaunch,
+                        render: new PrepareLaunchRenderer(data)
+                    });
+                }
+                StarRenderController.prototype.getRenderer = function (state) {
+                    var render = this._renderStock.filter(function (elem) {
+                        return elem.state === state;
+                    });
+                    return render.length === 0 ? new animation.NullRenderable() : render[0].render;
+                };
+                return StarRenderController;
+            })();
+            Renderer.StarRenderController = StarRenderController;
+        })(Renderer || (Renderer = {}));
+        // メインのオブジェクトとなるStar
+        var Star = (function (_super) {
+            __extends(Star, _super);
+            function Star() {
+                        _super.call(this);
+                this.data = new animation.Renderer.Circle.Data(0, 0, StarUtil.getSomeSize());
+                this._controller = new Renderer.StarRenderController(this.data);
+                this._logic = new StarLogic(this, this.data);
+                // バインドしておく
+                I.propBind([
+                    I.binder("x"),
+                    I.binder("y"),
+                    I.binder("zIndex"),
+                    I.binder("width"),
+                    I.binder("height"),
+                    I.binder("visible"),
+                    I.binder("color")
+                ], this, this.data);
+            }
+            Star.prototype.isValid = function () {
+                return true;
+            };
+            Star.prototype.isConnectable = function () {
+                return this._logic.isConnectable();
+            };
+            Star.prototype.onreflect = // bodyからデータを反映させる際に呼び出されるコールバック
+            function () {
+                return this._logic.onreflect();
+            };
+            Star.prototype.render = // starをレンダリングする。レンダリング処理自体は、circleのrenderに任せる。
+            function (context) {
+                this._controller.getRenderer(this._logic.state.objectState).render(context);
+            };
+            Star.prototype.createFixture = function (scale) {
+                return this._logic.createFixture(scale);
+            };
+            Star.prototype.makeTouchStartHandler = // ontouchstartのハンドラを作成して返す。
+            function (scene) {
+                var _this = this;
+                return function (e) {
+                    return _this._logic.ontouchstart(scene, e);
+                };
+            };
+            Star.prototype.makeTouchEndHandler = // ontouchendのハンドラを作成して返す
+            function (scene) {
+                var _this = this;
+                return function (e) {
+                    return _this._logic.ontouchend(scene, e);
+                };
+            };
+            return Star;
+        })(gl.BaseClasses.EntityImpl);
+        GameObj.Star = Star;
+    })(exports.GameObj || (exports.GameObj = {}));
+    var GameObj = exports.GameObj;
+})
diff --git a/src/star.ts b/src/star.ts
new file mode 100644
index 0000000..17c8a52
--- /dev/null
+++ b/src/star.ts
@@ -0,0 +1,324 @@
+
+import util = module("util");
+import animation = module("animation");
+import gl = module("gameLib");
+import fw = module("firework");
+import I = util.Illiegals
+
+// Starで利用されている各種情報
+module StarUtil {
+
+    enum StarSize {
+        Large,
+        Medium,
+        Small,
+        VerySmall
+    }
+
+    // StarSizeからランダムでいずれかを取得する
+    function getSomeType(): StarSize {
+        switch (Math.floor(Math.random() * 4)) {
+        case 0: return StarSize.Large;
+        case 1: return StarSize.Medium;
+        case 2: return StarSize.Small;
+        case 3: return StarSize.VerySmall;
+        }
+    }
+
+    export function getSomeSize(): number {
+        switch (getSomeType()) {
+        case StarSize.Large: return 16;
+        case StarSize.Medium: return 14;
+        case StarSize.Small: return 12;
+        case StarSize.VerySmall: return 10;
+        }
+    }
+}
+
+export module GameObj {
+
+    // Starに係るロジック周辺の処理を担当する。
+    // StarLogic自体はStarにコンポジションされているが、
+    // StarLogicにもStarが渡されている。
+    class StarLogic {
+
+
+        // 各starで共通するFixtureDefinition
+        private _fixDef = (): B2FixtureDef => {
+            var fix = new Box2D.Dynamics.b2FixtureDef();
+            fix.density = 1.0;       // 密度
+            fix.friction = 1.5;      // 摩擦係数
+            fix.restitution = 0.2;   // 反発係数
+            return fix;
+        } ();
+
+        state: fw.ObjectInfo = new fw.ObjectInfo(fw.ObjectType.Star);
+        scale: number = 1;
+
+        constructor(public starShape: Star, public data: animation.Renderer.Circle.Data) { }
+
+        onreflect(): bool {
+            var body = this.starShape.body;
+            var count = 0;
+            var contacts = [];
+            for (var n = body.GetContactList(); n != null;
+                 n = n.next) {
+                if (n.contact.IsTouching()) {
+                    contacts.push(n.other);
+                }
+            }
+            // 星同士が4つ以上隣接したら、staticに変更する。
+            if (contacts.length >= 4 && this.isConnectable()) {
+                contacts.filter((e) => {
+                    var info_e: fw.ObjectInfo = e.GetUserData();
+                    return info_e.objectState == fw.ObjectState.Free;
+                }).forEach((e) => {
+                    var info_e: fw.ObjectInfo = e.GetUserData();
+                    info_e.objectState = fw.ObjectState.Connected;
+                    if (body != e && info_e.type == fw.ObjectType.Star) {
+                        e.SetType(Box2D.Dynamics.b2Body.b2_staticBody);
+                    }
+                });
+                body.SetType(Box2D.Dynamics.b2Body.b2_staticBody);
+                var info: fw.ObjectInfo = body.GetUserData();
+                info.objectState = fw.ObjectState.Connected;
+                return false;
+            }
+
+            return true;
+        }
+
+        isConnectable(): bool {
+            return this.state.objectState === fw.ObjectState.Free;
+        }
+
+        // タッチを開始した際の処理。
+        ontouchstart(scene: gl.Scene, e: Event): bool {
+            var s = this.starShape;
+            if (this.state.objectState === fw.ObjectState.Connected) {
+                s.x -= s.width;
+                s.y -= s.height;
+                this.data.radius *= 2;
+                s.width *= 2;
+                s.height *= 2;
+                this.data.color.a = 0.3;
+                this.state.objectState = fw.ObjectState.Touched;
+            }
+            return true;
+        }
+
+        // タッチして離されたとき、その時点での領域にかかっている星を
+        // 消して、自身を拡大する。
+        // ただし、領域内に、すでにLaunch状態になっているものがある場合は
+        // 元に戻る。
+        ontouchend(scene: gl.Scene, e: Event): bool {
+
+            if (this.state.objectState !== fw.ObjectState.Touched) {
+                return false;
+            }
+
+            var s = this.starShape;
+            var contain = scene.entities.filter((elem) => {
+                if (elem === s) return false;
+                return this.starShape.within(elem, this.data.radius);
+            });
+
+            // 広がった中に存在しなければ、大きさを元に戻す。
+            if (contain.length === 0) {
+                this.data.radius /= 2;
+                s.width /= 2;
+                s.height /= 2;
+                this.state.objectState = fw.ObjectState.Connected;
+                return false;
+            }
+
+            contain.forEach((elem) => {scene.removeEntity(elem);});
+
+            // 剛体の情報を更新する。
+            s.body.SetType(Box2D.Dynamics.b2Body.b2_dynamicBody);
+            s.body.DestroyFixture(s.body.GetFixtureList());
+            var fixDef = this._fixDef;
+            fixDef.shape = new Box2D.Collision.Shapes.b2CircleShape(this.data.radius / this.scale);
+            s.body.CreateFixture(fixDef);
+
+            // 準備段階は終了とする
+            this.state.objectState = fw.ObjectState.PrepareLaunch;
+            return true;
+        }
+
+
+        // 渡されたstarに適合するbodyの設定を作成する。
+        createFixture(scale: number): gl.Physics.BodyDefinition {
+            var fixDef = this._fixDef;
+            var bodyDef = new Box2D.Dynamics.b2BodyDef();
+            bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody;
+            bodyDef.userData = this.state;
+            bodyDef.position.Set((this.data.x + this.data.width / 2) / scale,
+                                 (this.data.y + this.data.height / 2) / scale);
+            bodyDef.angularVelocity = (Math.random() * 2 % 2 ? -1 : 1) * 10;
+            fixDef.shape = new Box2D.Collision.Shapes.b2CircleShape(this.data.width / 2 / scale);
+
+            this.scale = scale;
+            return { bodyDef: bodyDef, fixtureDef: fixDef };
+        }
+
+    }
+
+    module Renderer {
+
+        // 通常状態のStarをレンダリングする。
+        class NormalStarRenderer implements animation.Renderable {
+
+            private _renderer : animation.Renderer.Circle.CircleRenderer;
+
+            constructor(public data: animation.Renderer.Circle.Data) {
+                this._renderer = new animation.Renderer.Circle.CircleRenderer(this.data);
+            }
+
+            render(context:animation.Context) : void {
+                var r = this.data.radius;
+                var d = this.data;
+                var grad = new animation.Gradation.Radial(context);
+                grad.from(d.x + r * 0.7, d.y + r * 0.5, 1).to(d.x + r, d.y + r, r);
+
+                grad.colorStop(0.0, "#fff").colorStop(0.5, d.color.toFillStyle()).
+                    colorStop(1.0, "#000");
+
+                d.gradient = grad;
+                this._renderer.render(context);
+            }
+        }
+
+        // 連結状態のStarをレンダリングする。
+        class ConnectedStarRenderer implements animation.Renderable {
+
+            private _renderer : animation.Renderer.Circle.CircleRenderer;
+
+            constructor(public data: animation.Renderer.Circle.Data) {
+                this._renderer = new animation.Renderer.Circle.CircleRenderer(this.data);
+            }
+
+            render(context:animation.Context) : void {
+                var r = this.data.radius;
+                var d = this.data;
+                var grad = new animation.Gradation.Radial(context);
+                grad.from(d.x + r * 0.7, d.y + r * 0.5, 1).to(d.x + r, d.y + r, r);
+
+                grad.colorStop(0.0, "#fff").colorStop(0.8, "#888").colorStop(1.0, "#000");
+                d.gradient = grad;
+                this._renderer.render(context);
+            }
+        }
+
+        // PrepareLaunch状態のレンダリングを行う。
+        class PrepareLaunchRenderer implements animation.Renderable {
+
+            private _renderer : animation.Renderer.Circle.CircleRenderer;
+
+            constructor(public data: animation.Renderer.Circle.Data) {
+                this._renderer = new animation.Renderer.Circle.CircleRenderer(this.data);
+            }
+
+            render(context:animation.Context) : void {
+                var r = this.data.radius;
+                var d = this.data;
+                var grad = new animation.Gradation.Radial(context);
+                grad.from(d.x + r * 0.7, d.y + r * 0.5, 1).to(d.x + r, d.y + r, r);
+
+                grad.colorStop(0.0, d.color.toFillStyle()).
+                    colorStop(1.0, d.color.toFillStyle());
+                this.data.gradient = grad;
+                this._renderer.render(context);
+            }
+        }
+
+        // Starで利用するrenderの切り替えをコントロールするためのクラス
+        export class StarRenderController {
+
+            private _renderStock: {state: fw.ObjectState; render: animation.Renderable;}[];
+
+            constructor(public data : animation.Renderer.Circle.Data) {
+                this._renderStock = []
+
+                this._renderStock.push({
+                    state : fw.ObjectState.Free, render : new NormalStarRenderer(data)
+                });
+                this._renderStock.push({
+                    state : fw.ObjectState.Touched, render : new NormalStarRenderer(data)
+                });
+                this._renderStock.push({
+                    state : fw.ObjectState.Connected, render : new ConnectedStarRenderer(data)
+                });
+                this._renderStock.push({
+                    state : fw.ObjectState.PrepareLaunch, render : new PrepareLaunchRenderer(data)
+                });
+            }
+
+            getRenderer(state:fw.ObjectState) : animation.Renderable {
+                var render = this._renderStock.filter((elem) => {
+                    return elem.state === state
+                });
+
+                return render.length === 0 ? new animation.NullRenderable : render[0].render;
+            }
+        }
+    }
+
+    // メインのオブジェクトとなるStar
+    export class Star extends gl.BaseClasses.EntityImpl implements fw.GameObj.IStar {
+
+        private _logic: StarLogic;
+        private _controller: Renderer.StarRenderController;
+
+        body: B2Body;
+        private data: animation.Renderer.Circle.Data;
+
+        color:animation.Common.Color;
+
+        constructor() {
+            super();
+            this.data = new animation.Renderer.Circle.Data(0, 0, StarUtil.getSomeSize());
+            this._controller = new Renderer.StarRenderController(this.data);
+
+            this._logic = new StarLogic(this, this.data);
+
+            // バインドしておく
+            I.propBind([I.binder("x"), I.binder("y"), I.binder("zIndex"),
+                        I.binder("width"), I.binder("height"),
+                        I.binder("visible"), I.binder("color")], this, this.data);
+        }
+
+        isValid(): bool {
+            return true;
+        }
+
+        isConnectable(): bool { return this._logic.isConnectable(); }
+
+        // bodyからデータを反映させる際に呼び出されるコールバック
+        onreflect(): bool { return this._logic.onreflect(); }
+
+        // starをレンダリングする。レンダリング処理自体は、circleのrenderに任せる。
+        render(context: animation.Context): void {
+
+            this._controller.getRenderer(this._logic.state.objectState).render(context);
+        }
+
+        createFixture(scale: number): gl.Physics.BodyDefinition {
+            return this._logic.createFixture(scale);
+        }
+
+        // ontouchstartのハンドラを作成して返す。
+        makeTouchStartHandler(scene: gl.Scene): (e: Event) => bool {
+            return (e: Event) => {
+                return this._logic.ontouchstart(scene, e);
+            }
+        }
+
+        // ontouchendのハンドラを作成して返す
+        makeTouchEndHandler(scene: gl.Scene): (e: Event) => bool {
+            return (e: Event) => {
+                return this._logic.ontouchend(scene, e);
+            }
+        }
+    }
+}
[from now] 2013/03/12 09:11:31

diff --git a/MyOMake/TypeScript.om b/MyOMake/TypeScript.om
index 627f028..23c32c8 100644
--- a/MyOMake/TypeScript.om
+++ b/MyOMake/TypeScript.om
@@ -42,7 +42,16 @@ public.Tsc() =
 # Dependecies on TypeScript are automatic calculating by TypeScript compiler, so
 # this file does not include scanner for .ts files.
 %.js : %.ts
-	$(Tsc) $<
+	match $<
+	case $"\(.*\)\.d\.ts"
+		eprintln(declaration file can not compile to .js)
+	case $"\(.*\)\.ts"
+		$(Tsc) $<
+	default
+    	eprintln(not target file)
+
+%.d.js : %.d.ts
+	eprintln(do not compile)

 # build rules
 # ======================================================================
diff --git a/src/firework.js b/src/firework.js
index ed08472..9d02d96 100644
--- a/src/firework.js
+++ b/src/firework.js
@@ -4,6 +4,7 @@ var __extends = this.__extends || function (d, b) {
     d.prototype = new __();
 };
 define(["require", "exports", "util", "animation", "gameLib"], function(require, exports, __util__, __animation__, __gl__) {
+    /// <reference path='star.d.ts' />
     var util = __util__;

     var animation = __animation__;
diff --git a/src/firework.ts b/src/firework.ts
index 01717da..7aa352f 100644
--- a/src/firework.ts
+++ b/src/firework.ts
@@ -1,3 +1,4 @@
+/// <reference path='star.d.ts' />

 import util = module("util");
 import animation = module("animation");