Tôi mới dùng iPhone dev, nhưng cố gắng xây dựng trò chơi 2D. Tôi đã theo dõi một cuốn sách, nhưng vòng lặp trò chơi mà nó tạo ra về cơ bản đã nói:Đây có phải là cách hay để tạo vòng lặp trò chơi cho trò chơi trên iPhone không?
function gameLoop
update()
render()
sleep(1/30th second)
gameLoop
Lý do là điều này sẽ chạy ở tốc độ 30 khung hình/giây. Tuy nhiên, điều này có vẻ hơi tinh thần, bởi vì nếu khung hình của tôi mất 1/30 giây, sau đó nó sẽ chạy ở tốc độ 15 khung hình/giây (vì nó sẽ dành nhiều thời gian ngủ khi cập nhật).
Vì vậy, tôi đã tìm hiểu và tìm thấy lớp CADisplayLink sẽ đồng bộ hóa các cuộc gọi đến chức năng gameLoop của tôi với tốc độ làm mới (hoặc một phần nhỏ của nó). Tôi không thể tìm thấy nhiều mẫu của nó, vì vậy tôi gửi bài ở đây để xem xét lại mã :-) Có vẻ như nó hoạt động như mong đợi, và nó bao gồm việc chuyển thời gian trôi qua (frame) vào phương thức Update để logic của tôi có thể được framerate -independant (tuy nhiên tôi thực sự không thể tìm thấy trong tài liệu CADisplayLink sẽ làm gì nếu khung của tôi mất nhiều thời gian hơn để chạy - Tôi hy vọng nó chỉ làm hết sức mình để bắt kịp, và không sụp đổ!).
//
// 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
Bất kỳ thông tin phản hồi sẽ được đánh giá :-)
PS. Điểm thưởng nếu bạn có thể cho tôi biết tại sao tất cả các sách sử dụng "viewController.view" nhưng đối với mọi thứ khác dường như sử dụng định dạng "[tên đối tượng]". Tại sao không [viewController view]?
Mặc dù mã này hoạt động, có vẻ như nói lắp một chút. Tốc độ khung hình không thấp, nó không có vẻ trơn tru. Tôi nghĩ rằng điều này có thể là vì tôi đang đồng bộ với tốc độ khung hình và sau đó * cập nhật * trong vòng lặp trò chơi của tôi. Kết xuất được thực hiện trong drawRect. Tôi nghĩ mã của tôi nên được vẽ trực tiếp trong phương thức được gọi (và có thể cập nhật sẽ được thực hiện sau khi vẽ), nhưng tôi không thể tìm thấy bất kỳ ví dụ hay về CADisplayLink. –
Tôi đã thay đổi chuyển động của các sprites của tôi thành 30 pixel mỗi giây, và nó có vẻ hoàn toàn trơn tru (với khung hình rất thường xuyên bị rớt), vì vậy tôi nghĩ nó đã giảm xuống tốc độ tôi muốn đặt - ví dụ. di chuyển nhiều hơn một pixel trên mỗi khung hình, điều đó có nghĩa là cuối cùng nó sẽ nhảy hai điểm ảnh trong một khung hình, làm cho nó trông không đồng đều. Tôi đoán điều này là không thể tránh khỏi. –