2013-01-03 97 views
0

我需要通過特定的方式在我的應用程序中組織渲染循環(這是有原因的)。在遊戲中渲染循環

比方說,我有

Sprite *sprite = [[Sprite alloc] initWithContentsOfFile:@"sprite.png"]; // some sprite 

while (true) { 
    [Graphics update]; 
    sprite.x = (sprite.x + 1) % 1024 // moving sprite by one pixel each frame 
    [Input update]; 
    [self update]; 
} 

Graphics.update應該渲染一幀和延遲執行(不渲染),直到下一幀

@interface Graphics() { 
    static BOOL _frozen; 
    static int _count; 
    static int _frameCount; 
    static float _frameRate; 
    static double _lastFrameTimestamp; 
} 

@end 

@implementation Graphics 

+ (void)initialize { 
    _frozen = NO 
    _count = 0 
    _frameCount = 0 
    _frameRate = 30.0 
    _lastFrameTimestamp = CACurrentMediaTime() 
} 

+ (void)freeze { 
    _frozen = YES; 
} 

+ (void)update { 
    if _frozen 
     return 
    end 

    Video.nextFrame // some OpenGL ES magic to render next frame 

    _count++ 

    now = CACurrentMediaTime() 
    waitTill = _lastFrameTimestamp + _count * (1.0/_frameRate) 

    if now <= waitTill 
     sleep(waitTill - now) 
    else 
     _count = 0 
     _lastFrameTimestamp = CACurrentMediaTime() 
    end 

    _frameCount++ 
} 

@end 

不知怎的,它的工作原理和精靈移動。但是當我回家時,應用程序WillResignActive不會被調用,當我回到應用程序時,會出現黑屏,並在一段時間後應用程序崩潰。

這裏是我嘗試口的東西:https://bitbucket.org/lukas/openrgss/src/7d9228cc281207fe00a99f63b507198ea2596ead/src/graphics.cGraphics_update功能)

+1

我建議閱讀Objective-C編程的介紹或複習。您將所有方法聲明爲類方法。以同樣的方式,所有的ivars都是靜態的。你的類接口不支持NSObject(或任何其他類)的子類。你可以在不調用超級實現的情況下重寫初始化名單繼續... – LearnCocos2D

回答

1

如果使用的是麻雀,這是你應如何處理它:

SPSprite *sprite = [[SPSprite alloc] initWithContentsOfFile:@"sprite.png"]; // some sprite 

[self addEventListener:@selector(enterFrame:) atObject:self forType:SP_EVENT_TYPE_ENTER_FRAME]; 

-(void)enterFrame:(SPEnterFrameEvent*)e { 
    [Graphics update]; 
    sprite.x += 1; // moving sprite by one pixel each frame 
    [Input update]; 
    [self update]; 
} 

麻雀管理使用SP_ENTER_FRAME_EVENT你的遊戲循環。每當它再次呈現時,它都會被調用。大約每秒30次(儘管可以配置)。

2

您可以嘗試使用核心動畫DisplayLink的,而不是一個while循環。這就是它通常在圖形框架中完成的方式。 currentRunLoop每1/60秒調用一次你的更新方法。

如果使用NSRunLoop,則應該在更新中刪除睡眠呼叫。

CADisplayLink *displayLink; 

// Set your update method 
displayLink = [CADisplayLink displayLinkWithTarget:[Graphics class] 
              selector:@selector(update)]; 
// Set fps to device refresh rate (60) 
[displayLink setFrameInterval:1.0f]; 

// Add your display link to current run loop 
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

// Stop updating 
[displayLink invalidate]; 

最後一行停止執行,所以在你完成循環之前不要調用它。