まず第一に、これはオープンソースであり、あなたはヘルプのためにメンションされます.
学校向けの Cocos2d を使用して、iPhone 向けのスーパー マリオ リメイクをプログラミングしています。
かなり良さそうですが、著作権の問題で利益が得られないため、オープン ソースにすることにしました。
私たちは独自に物理をプログラムしましたが、いくつか問題があります。
衝突は常にチェックされます。これが私が行う方法です。
衝突処理
- (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;
}
基本的に、四角形のどの衝突エッジが最小であるか (調整が最も簡単か) をチェックします。
今問題なのは以下
ご覧のとおり、マリオが下端でレンガを折りたたんだ場合、最小の Y 端で衝突があったように見えます。しかし、そうではありません。これにより、このエッジでは実際の衝突はなく、最小の X エッジであったとしても、常にブロックが破壊されます。
これを解決する方法はありますか?