我有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]];
克服它,它以奇怪的方式工作,导致它更新每一帧,但删除部分矩形。任何帮助也将不胜感激。
答案 0 :(得分:1)
听起来你在drawRect外面画画:。如果是这种情况,请将您的绘图代码移动到视图(框或某些子视图)drawRect:方法中。否则你的绘图将被你所看到的Cocoa绘图系统踩踏。您还需要使用计时器或动画而不是循环来重复绘制。
答案 1 :(得分:1)
我最近为试图与圈子做类似事情的人写了一个示例程序。我采用的方法是创建一个圆规范数组并在drawRect中绘制它们。它工作得很好。也许它会有所帮助。如果您想要整个项目,可以下载from here
@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