2014-04-05 7 views
1

내가 GLKit으로 만드는 응용 프로그램에서 사용자가 빈 타일에 인접한 타일을 탭하고 타일이 새 위치로 슬라이드하는 슬라이더 퍼즐이 있습니다. 단일 태스크를 수행해야하는 메소드의 수를 줄이기 위해 전체 슬라이딩 애니메이션을 하나의 단일 루프로 처리하기로 결정했습니다.메인 루프 외부에서 OpenGL ES 객체를 렌더링하는 방법은 무엇입니까?

- (void)slideSelectedTile 
{ 
    while (!self.selectedTile.hasFinishedMoving) 
    { 
     [self.selectedTile moveByVector:self.tileDisplacement]; 
     [self render]; 
     [NSThread sleepForTimeInterval:.1]; 
    } 
} 

문제는 렌더링 호출이이 루프 내에서 작동하지 않는다는 것입니다. 타일은 전체 루프가 끝나고 게임이 다음 glkViewDrawInRect 호출에 도달하면 렌더링됩니다. 여기서 render을 호출합니다. 물론 각 타일 렌더링 코드가 포함되어 있습니다.

루프에있을 때 현재 스레드가 주 스레드이고 루프를 사용하지 않고 수동으로 렌더링을 호출 할 수 있다는 것을 확인했습니다. 여기서 내가 뭘 잘못하고 있니?

답변

1

여기서 잘못된 것은 전체 개념을 놓친 것입니다. 이 while 루프는 화면에 그리기 및 표시 할 때 사용하는 스레드를 차단합니다. 버퍼가 다시 그려지지만 N 번보기는 않습니다.

render 메서드에서 주 스레드에서 perform selector를 호출 할 수도 있고 완료 될 때까지 기다릴 수도 있습니다. 이런 식으로 당신은 아마도 수면 요소를 잃을 수도 있습니다. 또 다른 방법은 slideSelectedTile이 호출 될 다른 애니메이터 스레드를 만드는 것이지만, 다시 render이 메인 스레드에서 호출되어야합니다.

좋은 코드 디자인을 만들지 않고도 나중에 어떤 문제가 발생할 수 있습니다. 객체 저장소에 소스 위치, 대상 위치 및 현재 위치를 저장해야합니다. 선형 보간은 source + (target-source)*(currentTime/animationTime)이 될 것입니다 : move 현재 위치를 계산하는 방법을 구현해야합니다. 대부분의 경우에 currentTimeanimationTime은 사실상 프레임 수가 될 수 있습니다. animationTime이 6 인 프레임에서 애니메이션을 수행하고 currentTime을 반복하고 [012] 032에서 반복하고 currentTime==animationTime 일 때 애니메이션이 수행됩니다. 결국 currentTime을 0으로 설정하고 animationTimeframeCount, source을 현재 위치로, targetlocation으로 설정하는 animateTo:(CGPoint)location in:(NSInteger)frameCount과 같은 이름을 부릅니다.

이 시점에서 질문은 move 메서드를 호출하는 것이며 무엇이 현재 위치를 차지합니까? 현재 위치는 렌더링 메서드의 주 스레드에서 사용해야합니다. move 메서드는 호출하는 빈도를 제어 할 수있는 새로운 스레드에서 호출 될 수 있지만 render 메서드의 전 (또는 내부) 프레임마다 호출 될 수도 있습니다.

제 제안은 디스플레이 링크를 사용하는 경우와 같이 render 메소드에서 반복 호출이 필요한 일부 openGL 기반 코드를 애니메이션으로 만들 때입니다. 이 호출을 사용하여 모든 렌더링을 렌더링을 수행하는 동안 렌더링 또는 OpenGL과 전혀 관련이없는 일부 외부 메소드로 분리합니다. 이렇게하면 별도의 스레드 또는 동일한 스레드에서 이동을 제어 할 수 있습니다.

모션 애니메이션 방법과 보간법을 복잡하게하는 방법 : 내가 설명한대로 구현하면 애니메이션 중간에 멈추고 전혀 문제가없는 다른 위치에 애니메이션을 적용 할 수 있습니다.

+0

놀랍게도 잘 작동했습니다. 고마워요! 나는 특별히 선형 보간이라고 말했어. 선형 보간 이외에 다른 것이 있습니까? – michaelsnowden

+0

예, 꽤 많은 수입니다. 당신은 안락함과 같은 것을하거나 쉽게 할 수 있습니다.pow (currentTime/animationTime), .75)를 사용하는 동안 천천히 시작하고 빠르게 끝내는 pow ((currentTime/animationTime), .1.5에서와 같이)이 두 가지는 가장 쉽게 power (currentTime/animationTime) 천천히 끝내라. 안락함과 안락함을 모두하기 위해서는 좀 더 많은 작업이 필요합니다. 일반적으로 F (X)는 F (0) = 0이고 F (1) = 1이고, X는 (currentTime/animationTime)이고 간격은 [0,1]입니다. –

+0

나는 메인 루프에서 타일에 대한 업데이트를 호출 할 필요가 없도록 애니메이션 메서드 내에서 별도의 스레드를 만드는 아이디어를 좋아합니다. 이 작업을 수행하는 방법에 대해 올바른 방향으로 알려줄 수 있습니까? 마지막 질문으로 약속드립니다. – michaelsnowden