First of all, this will be Open Source, and you will be mentioned for the help.
We've been programming a Super Mario Remake for the iPhone with Cocos2d for school.
It looks pretty great, and we decided to make it Open Source, because we can't get any profit because of Copyright issues.
We programmed the physics on our own, but it has a few issues.
Collisions are constantly checked, and this is how I do it:
Collision Handling
- (void)updateCollisions:(ccTime)delta {
for (STGameObject *child in self.gameObjects) {
for (STGameObject *child2 in self.gameObjects) {
// Don't check same object
if (child == child2) {
break;
}
if (STRectIntersect(child.boundingBox, child2.boundingBox)) {
// Position objects
STRectEdge edge1 = [self updateCollisionOfGameObject:child withGameObject:child2 delta:delta];
STRectEdge edge2 = [self updateCollisionOfGameObject:child2 withGameObject:child delta:delta];
// Send notifications
[child collisionWithGameObject:child2 edge:edge1];
[child2 collisionWithGameObject:child edge:edge2];
}
}
}
}
- (STRectEdge)updateCollisionOfGameObject:(STGameObject *)gameObject
withGameObject:(STGameObject *)gameObject2
delta:(ccTime)delta {
STRectEdge rectEdge;
float edgeLeft = (gameObject.boundingBox.origin.x - gameObject2.boundingBox.origin.x - gameObject.boundingBox.size.width) * -1;
float edgeRight = (gameObject.boundingBox.origin.x + gameObject2.boundingBox.size.width - gameObject2.boundingBox.origin.x);
float edgeTop = (gameObject.boundingBox.origin.y + gameObject.boundingBox.size.height - gameObject2.boundingBox.origin.y);
float edgeBottom = (gameObject.boundingBox.origin.y - gameObject2.boundingBox.size.height - gameObject2.boundingBox.origin.y) * -1;
float offset = 0.0;
if (edgeLeft < edgeRight) {
rectEdge = STRectEdgeMinX;
offset = edgeLeft;
} else {
rectEdge = STRectEdgeMaxX;
offset = edgeRight;
}
if (edgeTop < edgeBottom) {
float cached = edgeTop;
if (cached < offset) {
rectEdge = STRectEdgeMaxY;
offset = cached;
}
} else {
float cached = edgeBottom;
if (cached < offset) {
rectEdge = STRectEdgeMinY;
offset = cached;
}
}
if (gameObject.bodyType != STGameObjectBodyTypeStatic) {
if (gameObject2.bodyType != STGameObjectBodyTypeStatic) {
offset /= 2.0;
}
if ([gameObject bodyType] != STGameObjectBodyTypeNonColliding && [gameObject2 bodyType] != STGameObjectBodyTypeNonColliding) {
switch (rectEdge) {
case STRectEdgeMinX:
{
[gameObject move:ccp(offset, 0)];
}
break;
case STRectEdgeMaxX:
{
[gameObject move:ccp(-offset, 0)];
}
break;
case STRectEdgeMinY:
{
[gameObject move:ccp(0, offset)];
}
break;
case STRectEdgeMaxY:
{
[gameObject move:ccp(0, -offset)];
}
break;
}
if (rectEdge == STRectEdgeMinY && gameObject.velocity.y < 0) {
gameObject.velocity = ccp(gameObject.velocity.x, 0);
}
if (rectEdge == STRectEdgeMaxY && gameObject.velocity.y > 0) {
gameObject.velocity = ccp(gameObject.velocity.x, 0);
}
}
}
return rectEdge;
}
It basically checks which collision edge of the rect is the smallest (easiest to adjust).
The problem now is the following
As you can see, if Mario collapses a brick at it's bottom edge, it will look like there was a collision at the minimum Y edge. However, this is not the case. This causes to constantly destroy blocks, even though there was no real collision at this edge, but rather at the minimum X edge.
Any ideas how to resolve this?