6

iPhone開発は初めてですが、2Dゲームを構築しようとしています。私は本に従っていましたが、それが作成したゲームループは基本的に次のように述べていました:

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

理由は、これが 30fps で実行されるということでした。ただし、フレームが 1/30 秒かかった場合、15 fps で実行されるため、これは少し精神的に思えました (更新と同じくらい多くの時間をスリープに費やすため)。

そこで、掘り下げて、gameLoop 関数への呼び出しをリフレッシュ レート (またはその一部) に同期する CADisplayLink クラスを見つけました。私はそれの多くのサンプルを見つけることができないので、コードレビューのためにここに投稿しています :-) 期待どおりに動作しているようで、経過 (フレーム) 時間を 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ビュー]ではないのはなぜですか?

4

2 に答える 2

2

質問にCocos2Dがタグとしてリストされていますが、実際にはCocos2Dコードを使用していません。ゲームにCocos2Dを実装することを検討しましたか?それはあなたにいくつかの不必要な手間を省くでしょう。

構文に関しては、質問はメソッドを[myObject view]呼び出すために使用され、インスタンス変数をプロパティとして公開するために使用されます。を使用してインスタンス変数を取得できるかどうかは思い出せませんが、それが機能する場合は、2つの違いは構文だけであり、両方の方法を使用してインスタンス変数を取得できると思います。myObjectmyObject.view[myObject view]

そのとりとめのないもののいくつかがあなたに役立つことを願っています。

于 2010-03-11T20:28:59.333 に答える
-2

Apple による多くの GL の例から、タイマーを使用する必要があると思います。

animationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0/60.0)
                                                  target:self
                                                selector:@selector(updateAndRender)
                                                userInfo:nil
                                                 repeats:TRUE];
于 2010-04-12T08:47:27.597 に答える