0

私は、トレーニングの一形態としてスーパーシンペル物理エンジンを構築し、少なくともゲーム物理の作成の基本を理解しようとしています。私はbox2dやシマリスのようなもっと多くの可能性を提供するものを知っています。しかし、それは私が今達成したいことではありません。単純なコードを次のレベルに引き上げて、より現実的な動作を試みたいと思います。この汎用チュートリアルhttp://www.wildbunny.co.uk/blog/2011/04/06/physics-engines-for-dummies/に従おうとしていますが、構文が混乱していて、完全にはわかりません。いくつかのものを適用する方法。

現在、CCNodeから派生した単純なボールクラスがあります(cocos2Dフレームワークを使用)。クラスには、ランダムな方向に移動してエッジをバウンスさせる独自の更新メソッドがあります。

-(void) update:(ccTime ) time {
   [self moveCircle:time];
}

- (void) moveCircle: (ccTime) time {
    CGSize screenSize = [[CCDirector sharedDirector]winSize];

    // limit the velocity 

    if (self.vx > maxVel) {
        self.vx = maxVel;
    } else if (self.vx < minVel) {
    self.vx = minVel;
    } else if (self.vy > maxVel){
        self.vy = maxVel;
    } else if (self.vy < minVel){
        self.vy = minVel;
    } else {
        self.vx += accelx;
        self.vy += accely;
    }

    self.position = ccp(self.position.x+(self.vx*time), self.position.y+(self.vy *time));

    // bounce of the edges 

    if (self.position.x > screenSize.width-offset) {
        self.vx *=-1;
        accelx *=-1;
        self.position = ccp(screenSize.width-offset, self.position.y);
    } else if (self.position.x < offset) {
        self.vx *=-1;
        accelx *=-1;
        self.position = ccp(offset, self.position.y);
    } else if (self.position.y < offset) {
        self.vy *=-1;
        accely *=-1;
        self.position = ccp(self.position.x,offset);
    } else if (self.position.y > screenSize.height-offset) {
        self.vy *=-1;
        accely *=-1;    
        self.position = ccp(self.position.x, screenSize.height-offset);
    }
}

私のメインクラスには、ランダムに動き回るこれらのボールの配列があり、次のコードを使用してそれらの間の衝突を検出します

- (void) detectCollision {

for (int i=0;i<[circlesP1 count];i++){
    for (int j=i+1;j<[circlesP1 count];j++){
        if(ccpDistance([[circlesP1 objectAtIndex:i]position],[[circlesP1 objectAtIndex:j]position])<80) {

            P1Circle *circle1 = [circlesP1 objectAtIndex:i];
            [circle1 reverseDirection];
            P1Circle *circle2 = [circlesP1 objectAtIndex:j];
            [circle2 reverseDirection];
        }
    }
}

}

私のボールクラスの次のメソッドが実行されたときに衝突が検出されたとき

- (void) reverseDirection {
    self.vx *=-1;
    accelx *=-1;
    self.vy *=-1;
    accely *=-1;
}

これは機能します....しかし、それはかなり不器用に見えます(コードと視覚的な結果の両方)。より現実的な衝突を行うには、反射ベクトルを計算する必要があることを知っています。私はそれの公式を見つけました。しかし、それを私のボールクラスに適用する方法がわかりません。このコードを改善および開発するための助けをいただければ幸いです。

4

1 に答える 1

0

あなたのためのいくつかのアイデア。CPU の負荷を軽減します。

距離を計算する代わりに、CPU に関して多くのコストがかかる可能性があります。より単純な値でテストできます

static inline BOOL isClose(a,b) return { return ( abs(Xa - Xb) < イプシロン || abs(Ya - Yb) < イプシロン );}

別の改善点は次のとおりです。

if isFar(a,b) 時間の 10 ループで距離を更新します。isFar の実装方法を説明する必要はないと思います。次に、距離を更新するタイミングを知るために、一種のカウンターを格納する配列が必要です。時間の各ステップで、すべてのカウンターを 1 ずつ減らします。カウンタが近い場合 = 1 (次のステップでリフレッシュ) カウンタが遠い場合 = 10

于 2013-03-06T21:37:28.320 に答える