2010-03-11 5 views
6

저는 dev에 익숙하지만 2D 게임을 만들려고합니다. 나는 책을 읽고 있었지만 게임 루프는 기본적으로 다음과 같이 말했습니다.아이폰 게임을위한 게임 루프를 만드는 좋은 방법일까요?

function gameLoop 
    update() 
    render() 
    sleep(1/30th second) 
    gameLoop 

이것은 30fps에서 실행되는 것이 었습니다. 그러나 이것은 약간 정신적 인 것처럼 보였습니다. 제 프레임이 1/30 초가 걸리면 15fps로 실행될 것이기 때문입니다 (업데이트하는 데 많은 시간을 할애하기 때문에).

그래서 파고 들었고 내 gameLoop 함수에 대한 호출을 새로 고침 빈도 (또는 그 일부)와 동기화하는 CADisplayLink 클래스를 찾았습니다. 많은 샘플을 찾을 수 없으므로 여기에 코드 검토를 위해 게시하고 있습니다. :-) 예상대로 작동하는 것 같습니다. 그리고 경과 된 (프레임) 시간을 Update 메서드에 전달하여 내 논리가 프레임 속도가 될 수 있도록합니다. -independant (단, 프레임이 허용 된 시간보다 오래 걸리면 CADisplayLink가 수행 할 작업을 실제로 문서에서 찾을 수 없습니다. 따라 잡기 위해 최선을 다하고 충돌을 일으키지 않기를 바랍니다!).

// 
// GameAppDelegate.m 
// 
// Created by Danny Tuppeny on 10/03/2010. 
// Copyright Danny Tuppeny 2010. All rights reserved. 
// 

#import "GameAppDelegate.h" 
#import "GameViewController.h" 
#import "GameStates/gsSplash.h" 

@implementation GameAppDelegate 

@synthesize window; 
@synthesize viewController; 

- (void) applicationDidFinishLaunching:(UIApplication *)application 
{ 
// Create an instance of the first GameState (Splash Screen) 
[self doStateChange:[gsSplash class]]; 

// Set up the game loop 
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameLoop)]; 
[displayLink setFrameInterval:2]; 
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
} 

- (void) gameLoop 
{ 
// Calculate how long has passed since the previous frame 
CFTimeInterval currentFrameTime = [displayLink timestamp]; 
CFTimeInterval elapsed = 0; 

// For the first frame, we want to pass 0 (since we haven't elapsed any time), so only 
// calculate this in the case where we're not the first frame 
if (lastFrameTime != 0) 
{ 
    elapsed = currentFrameTime - lastFrameTime; 
} 

// Keep track of this frames time (so we can calculate this next time) 
lastFrameTime = currentFrameTime; 

NSLog([NSString stringWithFormat:@"%f", elapsed]); 

// Call update, passing the elapsed time in 
[((GameState*)viewController.view) Update:elapsed]; 
} 

- (void) doStateChange:(Class)state 
{ 
// Remove the previous GameState 
if (viewController.view != nil) 
{ 
    [viewController.view removeFromSuperview]; 
    [viewController.view release]; 
} 

// Create the new GameState 
viewController.view = [[state alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT) andManager:self]; 

// Now set as visible 
[window addSubview:viewController.view]; 
[window makeKeyAndVisible]; 
} 

- (void) dealloc 
{ 
[viewController release]; 
    [window release]; 
    [super dealloc]; 
} 

@end 

상관 피드백

PS :-) 이해 될 것이다. 보너스 포인트는 모든 책들이 "viewController.view"를 사용하는 이유를 말해 줄 수 있지만 다른 모든 것들은 "[object name]"형식을 사용하는 것처럼 보입니다. 왜 [viewController보기]가 아닌가?

+0

이 코드는 작동하지만 다소 더듬어 보입니다. 프레임 속도는 낮지 만 부드럽게 보이지 않습니다. 내 게임 루프에서 프레임 속도를 동기화 한 다음 * 업데이트 *하기 때문일 수 있습니다. 렌더링은 drawRect에서 수행됩니다. 내 코드가 직접 호출해야한다고 생각합니다. (그리고 어쩌면 업데이트는 그리기 후에 수행해야합니다.) CADisplayLink의 좋은 예를 찾을 수 없습니다. –

+0

필자의 스프라이트의 움직임을 초당 30 픽셀로 바 꾸었습니다. 매우 가끔씩 프레임이 떨어지는 것처럼 보였습니다. 그래서 나는 그것이 내가 정했을 때의 스피드에 불과하다고 생각합니다. 프레임 당 픽셀보다 약간 더 움직이면 결국 한 프레임에서 두 픽셀을 뛰어 넘어 고르지 않게 보일 것입니다. 나는 이것이 어쩔 수 없다고 생각한다. –

답변

2

귀하의 질문에 Cocos2D가 태그로 등록되어 있지만 실제로 Cocos2D 코드를 사용하고 있지 않습니다. 게임에 Cocos2D 구현을 고려한 적이 있습니까? 불필요한 번거 로움을 덜어줍니다.

구문 질문의 경우 myObject에서 [myObject view] 메서드를 호출하는 데 사용되며 myObject.view은 속성으로 노출 된 인스턴스 변수를 설정/가져 오는 데 사용됩니다. [myObject view]을 사용하여 인스턴스 변수를 검색 할 수 있다면 기억하지 못합니다. 그렇다면 작동하는 경우 두 가지 유일한 차이점은 구문 및 두 인스턴스 변수를 검색 할 수있는 방법을 모두 사용할 수 있습니다.

그 중 일부는 당신에게 유용 할 것입니다.

+0

웁스! 당신에게 내가 뭘하고 있는지 몰랐다고 말해 줬어! 태그를 삭제했습니다. 구문에 대해 약간 읽었습니까? 더 잘 이해했습니다. [myclass property]와 myclass.property가 다른 일을 할 수 있다고합니다. 첫 번째 변수는 코드를 실행할 수있는 속성입니다.하지만 대부분의 경우 변수를 반환하는 것으로 의심되는 반면 코드는 변수에 직접 액세스하는 반면 사용자 지정 코드는 필요하지 않습니다. C#에서 비공개 필드와 속성을 노출하는 것의 차이점과 비슷하지만 여기서는 둘 다 동일한 이름을 가질 수 있습니다! –

+0

사실 나는 오류가 발생하기 때문에 혼란스러워합니다. 알 수없는 'rect'getter 메소드에 액세스 그러면 점을 사용하면 get/set 메서드를 사용하는 것과 완전히 동일하다고 생각하게됩니다! –

+0

점을 사용하는 경우 속성으로 검색하려는 인스턴스 변수를 정의한 다음이를 합성해야합니다. "@property"및 "@synthesize"호출에 대한 구문을 조회합니다. Getter/Setter 메서드는 암시 적으로 만들어 지지만 @synthesize를 사용한 후에 만 ​​나타납니다. 이것이 알려지지 않은 'rect'getter 메소드를 얻는 이유입니다. –

-2

애플의 많은 GL 예제에서 타이머를 사용해야한다고 생각합니다.

animationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0/60.0) 
                target:self 
               selector:@selector(updateAndRender) 
               userInfo:nil 
               repeats:TRUE]; 
+0

CADisplayLink가 더 좋은 방법으로 추가되었다고 생각하지만 최근에 추가 되었기 때문에 문서/샘플이 거의없는 것으로 보입니다. ( –

관련 문제