0
votes

I'm trying to build a super simpel physics engine just as a form of training and to understand at least the basics of creating game physics. I'm aware of things like box2d and chipmunk that offer a lot more possibilities. But that's not what I want to achieve right now. I'd like to take my simple code to the next level and try to have more realistic behavior. I'm trying to follow this general purpose tutorial http://www.wildbunny.co.uk/blog/2011/04/06/physics-engines-for-dummies/ but the syntax confuses me and I'm not completely sure how to apply some things.

right now I have a simple ball class which is derived from CCNode(using the cocos2D framework) the class has it's own update method that makes it move in a random direction and bounce of the edges.

-(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);
    }
}

in my main class I have an array of these balls that move around randomly and I use the following code to detect collisions between them

- (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];
        }
    }
}

}

when a collision is detected following method in my ball class is executed

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

this works.... but it looks rather clumsy (both the code and visual result). I know that to have more realistic collisions I have to calculate the reflection vector. I have found the formula for it. but I don't know how to apply it to my ball class. Any help to improve and develop this code would be much appreciated.

1

1 Answers

0
votes

Some ideas for you. to reduce the CPU load.

Instead of calculating your distance which can cost a lot in term of CPU. You could just test on a simpler value

static inline BOOL isClose(a,b) return { return ( abs(Xa - Xb) < epsilon || abs(Ya - Yb) < epsilon );}

another improvement could be:

if isFar(a,b) refresh distance in 10 loops of time. I guess it is not necessary to show you how to implement isFar. Then you need an array to store a kind of counter to know when to refresh the distance. At each step of time you decrease all the counter by one. If is close counter=1 (refresh at next step) If is far counter=10