2013年4月17日 星期三

CADisplayLink的基本使用

CADisplayLink Class,這個 Class 的功能類似於 Timer。由於能支援每秒高達 60 fps 的畫面同步功能,所以更適合用在製作遊戲動畫上面,相較之下 Timer 較常使用在背景處理層面 。

以下是實做測試,沿用NSTimer基本使用的例子來作修改,加入計數Frame的功能,此功能就由CADisplayLink來實作,並與NSTimer的計數來作比對。原來NSTimer的例子是用倒數的,在此就改成正數了。

資料參考 :http://furnacedigital.blogspot.tw/2010/11/cadisplaylink.html

1.  使先在專案中加入QuartzCore的FrameWork



2. 加入一個新的Label來顯示Frame數,並將畫面重新排列。



3. 在timerViewController.h加入所需變數

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import <QuartzCore/CADisplayLink.h>


@interface timerViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *timerLabel;

@property (strong, nonatomic) IBOutlet UILabel *frameLabel;


@property (weak, nonatomic) IBOutlet UIButton *countDownButton;
@property (weak, nonatomic) IBOutlet UIButton *resetButton;

@property (nonatomic) NSTimer  *timer;
@property (nonatomic) CADisplayLink  *displayTimer;

@property (nonatomic) int  min;
@property (nonatomic) int  sec;
@property (nonatomic) int  minSec;

@property (nonatomic) int  nowTime;
@property (nonatomic) int  lastTime;

@property (nonatomic) NSString  *fpsString;

@end


4. 在timerViewController.m加入所需程式碼
#import "timerViewController.h"


@interface timerViewController ()

@end

#define CountDownTime  10000

#define TimeUnin  0.01   // 0.01 sec

@implementation timerViewController

@synthesize timerLabel;
@synthesize frameLabel;

@synthesize countDownButton;
@synthesize timer;

@synthesize displayTimer;

@synthesize min;
@synthesize sec;
@synthesize minSec;

@synthesize nowTime;
@synthesize lastTime;

@synthesize fpsString;
BOOL isRunning = NO;

int  frameCount = 0;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
   
    lastTime = CountDownTime;
   
    nowTime = lastTime;
   
    [self showNowTime];
   
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (IBAction)countDown:(id)sender {
    if (isRunning == NO) {
       
        isRunning = YES;
       
        [self init_timer];
       
        [countDownButton setTitle:@"暫停" forState:UIControlStateNormal];
       
       
    }
    else {
       
        isRunning = NO;
       
        lastTime = nowTime;
       
        [timer invalidate];
       
        [displayTimer invalidate];
       
        timer = nil;
       
        displayTimer = nil;
       
        [countDownButton setTitle:@"計數" forState:UIControlStateNormal];
       
       
    }
   
}

- (void) showNowTime
{
    min = nowTime  / 6000;
    sec = (nowTime % 6000) /100 ;
   
    minSec = nowTime %100;
   
    timerLabel.text =   [NSString stringWithFormat:@"%02d:%02d:%02d", min, sec, minSec];

   
   
}


- (void) init_timer
{
   
    //nowTime = lastTime;
   
    nowTime =0;
   
    timer = [NSTimer scheduledTimerWithTimeInterval:TimeUnin target:self selector:@selector(GameTimer_Count) userInfo:nil repeats:YES];

    [self init_displayTimer];

   
}

- (void) init_displayTimer
{
    displayTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(frame_Count)];
   
    [displayTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
   
    //CADisplayLink內定值就是每秒60張(參數=1),參數=2就是每秒30張,以此類推
    double fps = 60 / displayTimer.frameInterval;
    fpsString = [NSString stringWithFormat:@"%0.1f" , fps];
}

- (void)frame_Count
{
    frameCount ++;
    frameLabel.text = [NSString stringWithFormat:@"現在的Frame數 %d / %@", frameCount, fpsString];
}


/*
- (void)GameTimer_Count {
   
    if (nowTime > 0)
    {
        nowTime-- ;
       
        [self showNowTime];
       
    }
    else
        nowTime = CountDownTime;
}
*/

- (void)GameTimer_Count {
   
    nowTime++ ;
       
   [self showNowTime];
       
}


- (IBAction)reset:(id)sender {

    frameCount =0;
   
    lastTime = CountDownTime;
   
    //[countDownButton setTitle:@"倒數計數" forState:UIControlStateNormal];
   
    [countDownButton setTitle:@"開始計數" forState:UIControlStateNormal];
   

   
    [timer invalidate];
   
    [displayTimer invalidate];
   
    timer = nil;
   
    displayTimer = nil;
   
    isRunning = NO;
   
    //nowTime = lastTime;
   
    nowTime =0;
   
    frameCount =0;
   
    frameLabel.text = [NSString stringWithFormat:@"現在的Frame數 %d / %@", frameCount, fpsString];
   

    [self showNowTime];
   
   
}


@end



5. 結果顯示


沒有留言: