일부 컨텍스트 : C++ 및 Objective-C 하이브리드가 포함 된 Cocos2D/Box2D 용 2D Destructible 지형 라이브러리를 작성하고 있습니다. 최근 병렬 배열과 관련이없는 솔루션을 생각할 수없는 상황에 직면했습니다.Objective-C 및 C++로 병렬 배열 피하기
지형 주위에 물리 경계를 정의하려면 지형 경계의 초기 추적을해야합니다. 나는 텍스쳐 내 모든 격리 된 픽셀 몸체를 추적하고 캐쉬하기 위해 함수 호출을한다. 이는 키가 화소의 고유 위치와 동일한 인 NSValue에 싸서 CGPoint 이상임과 함께 다음 데이터 구조
- NSMutableDictionary "borderPixels"를 생성한다. 추적 된 모든 픽셀을 유지합니다. TerPixels는 지형 본체의 '시작'지점을 나타내는 하나의 TerPixel을 보유하고 그들의 다음 이웃 픽셀
- 있는 NSMutableArray "traceBodyPoints"를 가리키는
- 원형 연결리스트. TerPixel *을 여기에 저장하여 물리학 자체를 추적해야합니다. 따라서 지형 본문이 수정 된 경우 수정 된 본문의 모든 TerPixel *을이 배열에 삽입합니다. 그런 다음 각각을 참조하고 링크 된 목록을 탐색하여 물리 구조를 추적 할 수 있습니다. 여기
상황의 더 나은 그림을 그릴 수 있도록 몇 가지 코드 : 나는 해결책을 찾을 수없는 경우
다음-(void)traverseBoundaryPoints:(CGPoint)startPt {
if (!borderPixels) borderPixels = [[NSMutableDictionary alloc] init]; // Temp
if (!traceBodyPoints) traceBodyPoints = [[NSMutableArray alloc] init]; // Temp
TerPixel * start = [[TerPixel alloc] initWithCoords:startPt.x ypt:startPt.y prevx:-1 prevy:0];
TerPixel * next = start;
//CCLOG(@"Start of traverseBoundary next.x and next.y %d, %d", next.x, next.y);
TerPixel * old;
while (true) {
old = next;
next = [self findNextBoundaryPixel:next];
[next setNSP:[old subTerPixel:next]];
old.nextBorderPixel = next;
if (next.x == start.x && next.y == start.y) {
CCLOG(@"SUCCESS :: start = next");
next.nextBorderPixel = start; // Make the linked list circular
NSValue * pixLocVal = [next getAsValueWithPoint];
[borderPixels setObject:next forKey:pixLocVal];
// Add the pixel to the tracePoints array to be traversed/traced later
[traceBodyPoints addObject:start];
break;
} // end if
// Connect the linked list components
NSValue * pixLocVal = [next getAsValueWithPoint];
[borderPixels setObject:next forKey:pixLocVal];
} // end while
} // end traverse function
입니다. traceBodyPoints 배열의 각 TerPixel *을 물리 세계에 만들어지고 추가 될 Box2D b2Body에 연결해야합니다. 내 라이브러리에서 텍스처 내의 각 고립 된 픽셀 본문은 Box2D 본문에 해당합니다. 따라서 지형의 덩어리를 파괴하는 이벤트가 발생하면 파괴 된 픽셀과 관련된 몸체를 파괴하고 변경된 시체 만 되돌아 가야합니다. 즉, 주어진 TerPixel *을 Box2D 본문에 연결하는 방법이 필요합니다 *.
ARC를 사용하는 Objective-C에서 Objective-C 컨테이너에 C++ 객체/포인터를 포함 할 수 없습니다. 문제는 이러한 작업이 믿을 수 없을 정도로 성능이 있어야하고 브리지 캐스팅에 참여하는 것이 매우 비용이 많이 든다는 것입니다. 또한 모든 단일 TerPixel에 Box2D 본문에 대한 포인터를 포함하고 싶지 않습니다. 매달려있는 포인터가 없도록하고 포인터를 없애기 위해 무의미한 반복을 요구하는 것은 악몽입니다.
여기
-(void)createPhysicsBoundaries {
if ([self->traceBodyPoints count] == 0) {
CCLOG(@"createPhysicsBoundaries-> No bodies to trace");
return;
}
// NEED LOGIC HERE TO DELETE ALTERED BODIES
// NEED TO DELETE EXISTING BOX2D BODY AND RE-TRACE A NEW ONE
// For each body that has been altered, traverse linked list to trace the body
for (TerPixel * startPixel in self->traceBodyPoints) {
TerPixel * tracePixel = startPixel.nextBorderPixel;
b2BodyDef tDef;
tDef.position.Set(0, 0);
b2Body * b = self->world->CreateBody(&tDef);
self->groundBodies->push_back(b);
b->SetUserData((__bridge void*) self);
b2EdgeShape edgeShape;
CCLOG(@"StartPixel %d, %d", startPixel.x, startPixel.y);
while (tracePixel != startPixel) {
b2Vec2 start = b2Vec2(tracePixel.x/PTM_RATIO, tracePixel.y/PTM_RATIO);
//CCLOG(@"TracePixel BEFORE %d, %d", tracePixel.x, tracePixel.y);
tracePixel = tracePixel.nextBorderPixel;
//CCLOG(@"TracePixel AFTER %d, %d", tracePixel.x, tracePixel.y);
b2Vec2 end = b2Vec2(tracePixel.x/PTM_RATIO, tracePixel.y/PTM_RATIO);
edgeShape.Set(start,end);
b->CreateFixture(&edgeShape, 0);
} // end while
} // end for
} // end createPhysicsBoundaries
는 희망이 말이 물리학의 경계를 만들기위한 나의 논리입니다. 무슨 일이 일어나고 있는지 시각화가 필요하면 여기 비디오가 있습니다. http://www.youtube.com/watch?v=IUsgjYLr6e0&feature=youtu.be 녹색 경계는 물리 경계입니다.
당신은 Chipmunk Indie/Pro를 고려 했습니까? 파괴 가능한 지형에 자동 기하학이라는 기능이 내장되어 있습니다. http://www.youtube.com/watch?v=oacZwUGP11c – LearnCocos2D
아니요. 들어 본 적이 없습니다. 나는 잠시 동안 Box2D Destructible Terrain 솔루션을 원했습니다. 나는 해결책으로 95 % 정도를 마쳤다. 그래서 나는 그것을 끝내는 것도 좋을 것 같다. 내가 만들고있는 라이브러리를 통해 사용자는 한 번의 호출로 여러 지형 충돌을 피하고 지형을 파괴하고 물리를 재정의 할 수 있습니다. 되돌아 보면 나는 내가 생각했던 것보다 더 많이 둘러 봐야했다. Btw, 너의 책을 읽어라. 좋은 읽을 거리! –