iOS có CADisplayLink, trong Mac OS X có CVDisplayLink, nhưng tôi không thể tìm cách sử dụng nó, tất cả các ví dụ đều liên quan đến OpenGL.Phương án CADisplayLink cho Mac OS X
Tôi tạo ra tùy chỉnh này UIView và tôi muốn dịch nó vào một NSView
#import "StarView.h"
#import <QuartzCore/QuartzCore.h>
#define MAX_FPS (100.0)
#define MIN_FPS (MAX_FPS/40.0)
#define FRAME_TIME (1.0/MAX_FPS)
#define MAX_CPF (MAX_FPS/MIN_FPS)
#define aEPS (0.0001f)
@implementation StarView
@synthesize starImage = _starImage;
@synthesize x, y;
- (void)baseInit {
_starImage = nil;
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(runLoop)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self baseInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
[self baseInit];
}
return self;
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
[self.starImage drawAtPoint:CGPointMake(self.x, self.y)];
}
-(void) cycle {
self.x += 5;
if (self.x > 230) {
self.x = 0;
}
}
- (void) runLoop {
//NSLog(@"called");
static CFTimeInterval last_time = 0.0f;
static float cycles_left_over = 0.0f;
static float dt2 = 0.0f;
float dropAnimRate = (2.1f/25.0f);
CFTimeInterval current_time = CACurrentMediaTime();
float dt = current_time - last_time + cycles_left_over;
dt2 += dt;
[self setNeedsDisplay];
if (dt > (MAX_CPF * FRAME_TIME)) {
dt = (MAX_CPF * FRAME_TIME);
}
while (dt > FRAME_TIME) {
if (dt2 > (dropAnimRate - aEPS)){
[self cycle];
dt2 = 0.0f;
}
dt -= FRAME_TIME;
}
cycles_left_over = dt;
last_time = current_time;
}
@end
Phần mà tôi không thể dịch là này một
- (void)baseInit {
_starImage = nil;
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(runLoop)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
tôi biết rằng tôi có thể sử dụng một NSTimer, nhưng nó không có cùng độ chính xác
´quay lại [(__bridge SPVideoView *) displayLinkContext renderTime: inOutputTime]; 'Tôi không hiểu dòng này, tôi đoán rằng thay vì SPVideoView tôi nên sử dụng MyView, nhưng tôi không hiểu tôi nên sử dụng gì thay vì renderTime . Bạn có thể giải thích cho tôi mục đích của các hàm này (cả renderCallback và renderTime)? – AR89
@ AR89 - Bởi vì CVDisplayLink có chức năng gọi lại, không phải là phương thức, bạn có thể gọi lại phương thức thích hợp trong lớp của mình. Ở trên, lớp tôi đang sử dụng là SPVideoView và tôi có một phương thức lấy dấu thời gian inOutputTime. Bạn sẽ sử dụng dấu thời gian đó để xác định xem bạn có muốn kích hoạt cập nhật hiển thị chưa. Ngoài ra, tôi cũng có thể chỉ ra rằng bạn nên cẩn thận với các bản cập nhật hiển thị bằng cách sử dụng điều này, bởi vì lời gọi này xuất hiện trên một chuỗi nền, vì vậy bạn sẽ cần phải chắc chắn rằng bản vẽ của bạn xuất hiện trên chuỗi chính nếu sử dụng Core Graphics. –
đây là một câu trả lời hay, nhưng điều quan trọng là bạn sẽ kết thúc với việc gọi lại được kích hoạt trên một luồng khác với nơi mà một khung nhìn sẽ được vẽ? tôi nghĩ rằng nó có thể được cho OpenGL rendering ít nhất. – jheriko