Стирание рисунка какао, выполненного NSRectFill? - PullRequest
2 голосов
/ 02 июля 2011

У меня есть NSBox, внутри которого я рисую маленькие прямоугольники с NSRectFill().Мой код для этого выглядит следующим образом:

for (int i = 0; i <= 100; i++){


    int x = (rand() % 640) + 20;
    int y = (rand() % 315) + 196;

    array[i] = NSMakeRect(x, y, 4, 4);
    NSRectFill(array[i]);
}

Этот цикл for создает 100 случайно размещенных прямоугольников в сетке.То, что я пытался сделать, это создать своего рода анимацию, создаваемую этим кодом, повторяющимся снова и снова, создавая анимацию случайно появляющихся прямоугольников, с этим кодом:

for (int i = 0; i <= 10; i++) {      

   [self performSelector:@selector(executeFrame) withObject:nil afterDelay:(.05*i)];   

    }

Первый цикл forКстати, единственная вещь внутри функции executeFrame.Итак, что мне нужно сделать, это стереть все прямоугольники между кадрами, чтобы их количество оставалось неизменным, и они выглядели так, как будто они движутся.Я попытался сделать это, просто нарисовав фон снова, вызвав [myNsBox display]; перед вызовом executeFrame, но это выглядело так, как будто не было нарисовано прямоугольников.Вызов его после сделал то же самое, так же как и переключение setNeedsDisplay вместо отображения.Я не могу понять это, любая помощь будет оценена.

Кстати, дополнительная вещь заключается в том, что, когда я пытаюсь запустить свой код для выполнения фреймов, не пытаясь стереть прямоугольники между ними, всетак получилось, что нарисовано еще 100 прямоугольников.Даже если бы я попросил сделать 1000 или 10 000.Но тогда, если я покину окно и вернусь к нему (немедленно, время здесь не имеет значения), страница обновится, и прямоугольники появятся.Я попытался преодолеть это с помощью [box setNeedsDisplayInRect:array[i]];, который работал странным образом, заставляя его обновлять каждый кадр, но стирая части прямоугольников.Любая помощь в этом также будет оценена.

Ответы [ 2 ]

1 голос
/ 02 июля 2011

Я недавно написал пример программы для кого-то, кто пытается сделать что-то подобное с кругами.Подход, который я выбрал, состоял в том, чтобы создать массив спецификаций окружностей и нарисовать их в drawRect.Это работает довольно хорошо.Может быть, это поможет.Если вы хотите весь проект, вы можете скачать его отсюда

@implementation CircleView

@synthesize maxCircles, circleSize;

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        maxCircles = 1000;
        circles = [[NSMutableArray alloc] initWithCapacity:maxCircles];
    }
    return self;
}

- (void)dealloc {
    [circles release];
    [super dealloc];
}

- (void)drawRect:(NSRect)dirtyRect {
    NSArray *myCircles;
    @synchronized(circles) {
        myCircles = [circles copy];
    }
    NSRect bounds = [self bounds];
    NSRect circleBounds;
    for (NSDictionary *circleSpecs in myCircles) {
        NSColor *color = [circleSpecs objectForKey:colorKey];
        float size = [[circleSpecs objectForKey:sizeKey] floatValue];
        NSPoint origin = NSPointFromString([circleSpecs objectForKey:originKey]);
        circleBounds.size.width = size * bounds.size.width;
        circleBounds.size.height = size * bounds.size.height;
        circleBounds.origin.x = origin.x * bounds.size.width - (circleBounds.size.width / 2);
        circleBounds.origin.y = origin.y * bounds.size.height - (circleBounds.size.height / 2);
        NSBezierPath *drawingPath = [NSBezierPath bezierPath];
        [color set];
        [drawingPath appendBezierPathWithOvalInRect:circleBounds];
        [drawingPath fill];
    }
    [myCircles release];
}

#pragma mark Public Methods

-(void)makeMoreCircles:(BOOL)flag {
    if (flag) {
        circleTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(makeACircle:) userInfo:nil repeats:YES];
    }
    else {
        [circleTimer invalidate];
    }
}

-(void)makeACircle:(NSTimer*)theTimer {
    // Calculate a random color
    NSColor *color;        
    color = [NSColor colorWithCalibratedRed:(arc4random() % 255) / 255.0
                                      green:(arc4random() % 255) / 255.0
                                       blue:(arc4random() % 255) / 255.0
                                      alpha:(arc4random() % 255) / 255.0];
    //Calculate a random origin from 0 to 1
    NSPoint origin;
    origin.x = (double)arc4random() / (double)0xFFFFFFFF;
    origin.y = (double)arc4random() / (double)0xFFFFFFFF;
    NSDictionary *circleSpecs = [NSDictionary dictionaryWithObjectsAndKeys:color, colorKey, 
                                 [NSNumber numberWithFloat:circleSize], sizeKey, 
                                 NSStringFromPoint(origin), originKey,
                                 nil];
    @synchronized(circles) {
        [circles addObject:circleSpecs];
        if ([circles count] > maxCircles) {
            [circles removeObjectsInRange:NSMakeRange(0, [circles count] - maxCircles)];
        }
    }
    [self setNeedsDisplay:YES];
}

@end
1 голос
/ 02 июля 2011

Звучит так, будто вы рисуете вне drawRect:. Если это так, переместите свой чертежный код в метод drawRect: метод представления (блока или некоторого подпредставления). В противном случае ваш рисунок будет растоптан системой рисования Какао, как вы видите. Вы также захотите использовать таймеры или анимацию, а не циклы для повторного рисования.

...