在目标c / cocos2d中构建一个迷你物理引擎

时间:2013-03-06 20:35:52

标签: objective-c cocos2d-iphone physics-engine

我试图建立一个超级简单的物理引擎,就像培训一样,至少要了解创建游戏物理的基础知识。我知道像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;
}

这可行....但它看起来相当笨拙(代码和视觉效果)。 我知道要有更逼真的碰撞,我必须计算反射向量。 我找到了它的公式。但我不知道如何将它应用到我的球类。 任何帮助改进和开发此代码都将非常感激。

1 个答案:

答案 0 :(得分:0)

为您提供一些想法。以减少CPU负载。

而不是计算你的距离,这可以在CPU方面花费很多。你可以测试一个更简单的值

静态内联BOOL isClose(a,b)返回{return(abs(Xa - Xb)&lt; epsilon || abs(Ya - Yb)&lt; epsilon);}

另一项改进可能是:

如果isFar(a,b)刷新10个时间循环的距离。我想没有必要向您展示如何实现isFar。 然后你需要一个数组来存储一种计数器来知道何时刷新距离。在每个步骤中,您将所有计数器减少一个。 如果是关闭计数器= 1(下一步刷新) 如果是远计数器= 10