Это хороший способ сделать игровой цикл для игры для iPhone? - PullRequest
6 голосов
/ 11 марта 2010

Я новичок в разработке для iPhone, но пытаюсь создать 2D-игру. Я следил за книгой, но созданный ею игровой цикл в основном гласил:

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

Причина в том, что это будет работать на скорости 30 кадров в секунду. Тем не менее, это казалось немного умственным, потому что если бы мой кадр занимал 1/30 секунды, то он работал бы со скоростью 15 кадров в секунду (так как он потратил бы столько же времени на сон, сколько и обновление).

Итак, я немного покопался и нашел класс CADisplayLink, который синхронизировал бы вызовы моей функции gameLoop с частотой обновления (или ее частью). Я не могу найти много примеров этого, поэтому я публикую здесь для обзора кода :-) Кажется, он работает как ожидалось, и он включает передачу истекшего (frame) времени в метод Update, чтобы моя логика могла быть частотой кадров -независимый (однако я не могу найти в документах, что бы сделал 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", а для всего остального, похоже, используется формат "[имя объекта]". Почему бы не [viewController view]?

Ответы [ 2 ]

2 голосов
/ 11 марта 2010

Вы указали Cocos2D в качестве тега в своем вопросе, но на самом деле вы не используете какой-либо код Cocos2D. Рассматривали ли вы сделать реализацию Cocos2D для ваших игр? Это избавит вас от ненужных хлопот.

Что касается вашего вопроса о синтаксисе, [myObject view] используется для вызова методов на myObject, в то время как myObject.view используется для установки / получения переменных экземпляра, представленных в виде свойств. Я не помню, можете ли вы извлекать переменные экземпляра, используя [myObject view], но если это работает, то, я думаю, единственное различие между ними заключается в синтаксисе, и вы можете использовать оба метода для извлечения переменных экземпляра.

Надеюсь, некоторые из этих бессвязных полезны для вас.

0 голосов
/ 12 апреля 2010

Из многих примеров GL от Apple я думаю, что вы должны использовать таймер.

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