Я новичок в разработке для 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]?