About setAnimationInterval on ios for a lower frame rate

I know that to get lower frame rate, I can use

cc.director.setAnimationInterval(1.0 / 40.0);

for example, the code above give me a frame rate at 40.

But on iOS, the code above above will have no effect since :

// CCDirectorCaller-ios

-(void) setAnimationInterval:(double)intervalNew
{
    [self stopMainLoop];
        
    self.interval = 60.0 * intervalNew;
        
    displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doCaller:)];
    [displayLink setFrameInterval: self.interval];
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

The self.interval above will still be 1 (int) so the frame rate in the game will still be at 60 fps.

But, in Mac, the code above forcing 40 fps will have effect since :

// CCApplication-mac

int Application::run()
{
    // ......
    long lastTime = 0L;
    long curTime = 0L;
    
    while (!glview->windowShouldClose())
    {
        lastTime = getCurrentMillSecond();
        
        director->mainLoop();
        glview->pollEvents();

        curTime = getCurrentMillSecond();
        if (curTime - lastTime < _animationInterval)
        {
            usleep(static_cast<useconds_t>((_animationInterval - curTime + lastTime)*1000));
        }
    }
    // ......
}

So I tried to use the same way in iOS by doing :

// CCDirectorCaller-ios

-(void) doCaller: (id) sender
{
    long lastTime = lastTime = getCurrentMillSecond();
    long curTime = 0L;
    if (isAppActive) {
        cocos2d::Director* director = cocos2d::Director::getInstance();
        [EAGLContext setCurrentContext: [(CCEAGLView*)director->getOpenGLView()->getEAGLView() context]];
        director->mainLoop();
        curTime = getCurrentMillSecond();
        long animationInterval = director->getAnimationInterval() * 1000.0f;
        if (curTime - lastTime < animationInterval)
        {
            usleep(static_cast<useconds_t>((animationInterval - curTime + lastTime)*1000));
        }
    }
}

This dose give me the frame rate 40fps I want in the game but I am just not sure if it is good to do it this way since the engine team does not.

Any advice will be appreciated, thanks :slight_smile:

iOS w/CADisplayLink can only support frame rates 60, 30, 15.

If you want 30 fps, try in app delegate:

fps = 30;
director->setAnimationInterval(1.f/fps);

https://developer.apple.com/documentation/quartzcore/cadisplaylink/1621231-frameinterval?changes=latest_minor&language=objc

Yep, I know that iOS w/CADisplayLink can only support frame rates 60, 30, 15.

But in our game, 60 is too high and 30 is too low, so I am trying to find a way to keep the rate in between 30 ~ 6p just like in Mac and Android platform …

Well then you’ll have to live with your hack. My guess is that you just see the same frame twice every few frames. If that looks good for your game then by all means, keep what you’re using.