scheduleTimerWithTimeInterval срабатывает только один раз, когда Repeats установлен на YES - PullRequest
2 голосов
/ 20 июня 2011

Я работаю через упражнения в одной из книг Apress. В этом фрагменте кода создается объект NSTimer, который должен многократно вызывать и вызывать функцию gameloop. Я установил контрольные точки в gameloop, и он срабатывает только один раз. Я пытаюсь понять почему. Это кажется довольно простым с точки зрения того, что он должен делать. У кого-нибудь есть указания о том, что здесь может происходить?

#define RANDOM_SEED() srandom(time(NULL))
#define RANDOM_INT(__MIN__, __MAX__) ((__MIN__) + random() % ((__MAX__+1) - (__MIN__)))
#define kSteps 8
#define kSpeed 200
#define kFPS 20.0
#define kBounce 30
#define kDirForward 0
#define kDirBackward 1
#define kDirUp 2
#define kDirDown 3
static int kForward[] =  {0,1,2,3,4,5,6,7};
static int kUpward[] =   {8,9,10,11,12,13,14,15};
static int kDownward[] = {16,17,18,19,20,21,22,23};
static int kBackward[] = {24,24,25,26,27,28,29,30};


/** for mario.png
#define kSteps 6
static int kForward[] = {10,11,11,10,9,9};
static int kBackward[] = {22,23,23,22,21,21};
static int kUpward[] = {4,5,5,4,3,3};
static int kDownward[] = {16,17,17,16,15,15};
**/

- (id) initWithCoder: (NSCoder *) coder {
    if (self = [super initWithCoder: coder]) {
        test = [AtlasSprite fromFile: @"walk.png" withRows: 4 withColumns: 8];
        test.angle = 0;
        test.speed = kSpeed;
        direction = kDirForward;
        timer = [NSTimer scheduledTimerWithTimeInterval: 1.0/kFPS
                                                     target:self 
                                               selector:@selector(gameLoop) 
                                               userInfo:nil 
                                                repeats:YES];
        self.backgroundColor = [UIColor whiteColor];
    }
    return self;
}

- (void) gameLoop
{
    frame = (frame+1)%kSteps;
    [test tic: 1.0/kFPS];
    if (test.offScreen) {
        RANDOM_SEED();
        int toCenter = round(atan2(-test.y,-test.x)*180.0/3.141592);
        if (toCenter < 0) toCenter += 360;
        int bounce = (toCenter+RANDOM_INT(-kBounce,kBounce))%360;
        if (bounce <= 60 || bounce >= 300) direction = kDirForward;
        else if (bounce > 60 && bounce < 120) direction = kDirUp;
        else if (bounce >= 120 && bounce <= 240) direction = kDirBackward;
        else direction = kDirDown;
        test.angle = bounce;
        test.scale = 0.4+1.6*RANDOM_INT(0,10)/10.0;
        while (test.offScreen) [test tic: 1.0/kFPS];
    }
    switch (direction) {
        case kDirForward:       test.frame = kForward[frame]; break;
        case kDirBackward:      test.frame = kBackward[frame]; break;
        case kDirUp:            test.frame = kUpward[frame]; break;
        case kDirDown:          test.frame = kDownward[frame]; break;
    }
    [self setNeedsDisplay];
}

1 Ответ

0 голосов
/ 30 июня 2011

Рич:

NSTimer - объект с автоматическим освобождением. Поскольку вы хотите, чтобы это повторилось, вам нужно сохранить объект. Попробуйте это:

timer = [[NSTimer scheduledTimerWithTimeInterval: 1.0/kFPS
                                                 target:self 
                                           selector:@selector(gameLoop) 
                                           userInfo:nil 
                                            repeats:YES] retain];

Сохраняя таймер, вы должны будете убедиться, что вы отпустите его, когда он вам больше не нужен. Также убедитесь, что вы сделали недействительным таймер, когда закончите с ним.

Надеюсь, это решит вашу проблему.

...