2012-03-19 2 views
1

화면에 ~ 10 개의 원이 있고 터치 동작을 통해 화면에서 밀고 끌 수있는 앱을 만듭니다. 이 서클 (원으로 그려진 UIView의 단순한 UIView)도 충돌 감지 기능을 가지고 있으며 충돌시 다른 서클을 밀어 내야한다는 아이디어가 있습니다. 이 앱에는 가속도 또는 중력도 없습니다. 동전을 밀기 만하면됩니다. 동전이 단순히 밀려나는 곳과 움직이는 것을 멈 추면 그렇게합니다.원형 대 원형 충돌 반응 - 동등 우선 순위

나는 touch-to-circle 상호 작용 작업과 circle-to-circle 작업의 기본 원리가 있습니다. 그러나 코드는 Circle01에게 모든 힘을줍니다. IE는 다른 서클에 푸시 될 수 있으며 원하는대로 움직일 수 있습니다. 그러나 다른 서클을 밀어 넣으면 Circle01을 돌아 다니며 움직입니다.

나는 충돌 탐지에 대해 수십 페이지를 읽었지만 모든 서클에 동등한 힘을주기 위해이 코드를 수정하는 방법에 관해서는 난처한 편이다.

관련 코드 :

MyCircle.m

- (void)drawRect:(CGRect)rect 
{ 
CGPoint viewCenter = CGPointMake(50,50); 
bpath = [UIBezierPath bezierPathWithArcCenter:viewCenter radius:50 startAngle:0 endAngle:DEGREES_TO_RADIANS(360) clockwise:YES]; 

[[UIColor blueColor] setFill]; 
[bpath fill]; 
} 

CircleVC.m 어떤 도움

- (void)viewDidLoad 
{ 
    Circle01 = [[MyCircle alloc] initWithFrame:CGRectMake(200, 200, 100, 100)]; 
     Circle01.backgroundColor = [UIColor redColor]; 
     Circle01.alpha = 0.5; 
     [self.view addSubview:Circle01]; 
} 

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    // Testing circle collision detection 
    for (UIView *aView in self.view.subviews) 
    { 
    if (Circle01 == anotherView) 
    continue; 
    if (CGRectIntersectsRect(Circle01.frame, aView.frame)) 
    { 
     float xDistance = aView.center.x - Circle01.center.x; 
     float yDistance = aView.center.y - Circle01.center.y; 
     float distance = xDistance * xDistance + yDistance * yDistance; 
     float angle = atan2(yDistance, xDistance); 
     CGPoint newCenter; 

     if (distance < 100 * 100) 
     { 
     newCenter.x = Circle01.center.x + (Circle01.frame.size.width * cos(angle)); 
     newCenter.y = Circle01.center.y + (Circle01.frame.size.width * sin(angle)); 
     aView.center = newCenter; 
     } 
    } 
    } 
} 

감사합니다.

답변

1

Box2d와 같은 물리 엔진에서 쉽게 오프로드 할 수 있습니다. 적인 Cocos2D는 Box2D의 패키지로되어 있지만, 만에 UIView 기반 애니메이션

_를 사용하고 있기 때문에 당신은 독립 실행 형 버전을 원할 것입니다

옵션 여기에 1

있는 좋은 약간 사용에 대한 자습서를 일자 불구하고 Box2d와 UIKit. http://www.cocoanetics.com/2010/05/physics-101-uikit-app-with-box2d-for-gravity/

몇 가지주의 사항 : 당신은 ARC를 사용하는 경우 당신은 당신의 C 개체로하고 통제 넣어 될 때 ARC 사전 컴파일러를 말해 지독한 브리지 컴파일러 힌트를 사용해야합니다. 예를 들어

:

bodyDef.userData = (__bridge void *)physicalView; 
UIView *oneView = (__bridge UIView*)b -> GetUserData(); 

_

옵션 2

당신은 (또한 위의 "지독한는"문을 아크 브리징 필요) 다람쥐를 사용할 수 있습니다 .여기에 좋은 튜토리얼 : http://www.alexandre-gomes.com/articles/chipmunk/

_

옵션 3-

또는 (저렴한 없음), 당신은 작업을 수행 프로 다람쥐와 함께 제공되는 목표 - 다람쥐 라이브러리를 사용할 수있는 가장 쉬운 ARC와 다음은 UIImageViews에서 Obj-Chipmunk를 사용하는 최근의 "to-the-point"자습서입니다. 이것은 모든 UIView 기반 코드에서 동일합니다. http://www.ayarsanimation.com/frankayars/chipmunk

Obj-Chipmunk는 Chipmunk Pro의 인디 버전 라이센스로 구입할 수 있습니다. http://chipmunk-physics.net/chipmunkPro.php

유료 솔루션을지지하지 않지만 시간을 절약 할 수 있습니다.

+0

답변 해 주셔서 감사합니다. 호기심 때문에, 외부 라이브러리의 도움없이 Objective-C에서 다중 충돌 감지/반응 시스템을 구축하는 것이 가능하지 않습니까? –

0

나는 뭔가를 놓치지 않으면 꽤 간단하게 보입니다. touchesMoved에서 Circle01을 하드 코딩하는 대신 사용자가 터치 한 뷰를 기반으로 히트 감지를 수행하십시오. 그런 식으로, 그들은 어떤 견해를 끌고 있건간에 우선 순위를 얻게 될 것입니다.

+0

글쎄, 나는 그들이 평등 해지고 다른 사람들보다 우선권을 갖기를 원하지 않는다. 현재 Circle01만이 적절한 충돌 감지 기능을 가지고 있으며 다른 어떤 서클도 그것을 덮어 쓰지 않습니다. 반면에 다른 모든 서클은 함께 밀어 넣으면 겹칠 수 있습니다. 이는 내가 지향하는 것이 아닙니다. –

+0

드래그 한 것을 두 번째로 드래그 한 다음 세 번째를 클릭하면 두 번째가 세 번째보다 우선 순위를 갖길 원하십니까? 각 원과 연관된 속도 (속도 + 방향) 벡터를 원하는 것처럼 보입니다. 충돌하는 동안, 관성의 일부 또는 전부를 도청 뷰에서 다음 뷰로 이전합니다. 목록을 여러 번 실행해야합니다. 처음에는 두드려진보기, 두 번째보기, 세 번째보기, 이전에 확인했지만 다른 충돌을 테스트하는보기는 무시합니다. 그것을 최적화하는 방법이 있습니다. – EricS