2

所以我来自一些处理背景(虽然不多),我习惯于使用在应用程序运行时反复运行的绘制循环。

我似乎在 xcode 和 C4 中找不到类似的东西。有什么人可以建议的吗?

我基本上在做的只是使用 C4 向量作为自定义类中的属性创建一个弹跳球应用程序

这是我的自定义类头/实现文件:

@interface splitSquare : C4Shape

@property C4Vector *accel;
@property C4Vector *velocity;
@property C4Vector *location;

-(id)initWithPoint:(CGPoint)point;

@end

-(id)initWithPoint:(CGPoint)point{
    self = [super init];
    if (self){

        CGRect frame = CGRectMake(0, 0, 50, 50);
        [self ellipse:frame];
        self.lineWidth = 0.0f;
        self.fillColor = [UIColor colorWithRed:[C4Math randomInt:100]/100.0f
                                         green:[C4Math randomInt:100]/100.0f
                                          blue:0.5f
                                         alpha:1.0f];

        _location = [C4Vector vectorWithX:point.x Y:point.y Z:0.0f];

        self.origin = _location.CGPoint;


        _accel = [C4Vector vectorWithX:0.04f Y:0.05f Z:0.0f];
        _velocity = [C4Vector vectorWithX:0.004f Y:0.0005f Z:0.0f];
        C4Log(@"The current value of velocity x is %f and y is %f", _velocity.x, _velocity.y);


}

我正在做一些非常简单的事情(将加速度添加到速度和速度到位置,然后将位置分配给形状原点)。在主 C4WorkSpace 中,我有以下代码:

@interface C4WorkSpace()
-(void)updateVectors;
@end

@implementation C4WorkSpace

{
    splitSquare *testShape;
    C4Timer *timer;
}
-(void)setup {

testShape = [[splitSquare alloc] initWithPoint:point2];

        [self.canvas addShape:testShape];
    testShape.animationDuration = 0.25f;

    timer = [C4Timer automaticTimerWithInterval:0.25f target:self method:@"updateVectors" repeats:YES];

}

-(void)updateVectors{
    //accel add to vel, vel added to location
    [testShape.velocity add:testShape.accel];
    [testShape.location add:testShape.velocity];
    testShape.origin = testShape.location.CGPoint;
    testShape.fillColor = [UIColor colorWithRed:[C4Math randomInt:100]/100.0f
                                          green:[C4Math randomInt:100]/100.0f
                                           blue:0.5f
                                          alpha:1.0f];   
}
@end

所以这就是我现在正在做的事情,一个 C4 计时器被调用,但我觉得必须有一种更优雅的方式来做到这一点。现在动画很跳跃,虽然它没有抛出错误,但它似乎无法正常工作(每次我运行 iOS 模拟器时,它都会运行一秒钟,然后跳回 xcode 并向我显示当前线程)。

任何/所有建议都会很棒,谢谢!

4

1 回答 1

2

实际上,您使用计时器创建更新循环是正确的。C4 不会对屏幕进行整个更新,而是仅更新它在任何给定时间需要更新的内容。这就是为什么没有像其他 api 那样的绘制循环。这样做的一个主要原因是系统资源更轻(即更少的绘图/更少的更新=更长的移动设备电池寿命)。

为了解决您的上述问题,我稍微修改了您发送过来的代码。

这是splitSquare标题:

#import "C4Shape.h"

@interface splitSquare : C4Shape

@property C4Vector *accel;
@property C4Vector *velocity;
@property C4Vector *location;

-(id)initWithPoint:(CGPoint)point;
-(void)beginUpdating;
@end

注意:beginUpdating在标题中添加了一个方法。

这是splitSquare实现:

#import "splitSquare.h"

@implementation splitSquare {
    C4Timer *updateVectorTimer;
}

-(id)initWithPoint:(CGPoint)point{
    self = [super init];
    if (self){

        CGRect frame = CGRectMake(0, 0, 50, 50);
        [self ellipse:frame];
        self.lineWidth = 0.0f;
        self.fillColor = [UIColor colorWithRed:[C4Math randomInt:100]/100.0f
                                         green:[C4Math randomInt:100]/100.0f
                                          blue:0.5f
                                         alpha:1.0f];

        _location = [C4Vector vectorWithX:point.x Y:point.y Z:0.0f];

        self.origin = _location.CGPoint;


        _accel = [C4Vector vectorWithX:0.04f Y:0.05f Z:0.0f];
        _velocity = [C4Vector vectorWithX:0.004f Y:0.0005f Z:0.0f];
        C4Log(@"The current value of velocity x is %f and y is %f",
              _velocity.x,
              _velocity.y);
    }
    return self;
}

-(void)beginUpdating {
    updateVectorTimer = [C4Timer automaticTimerWithInterval:1/60.0f
                                                     target:self
                                                     method:@"updateVectors"
                                                    repeats:YES];
}

-(void)updateVectors{
    //accel add to vel, vel added to location
    [self.velocity add:self.accel];
    [self.location add:self.velocity];
    self.origin = self.location.CGPoint;
    self.fillColor = [UIColor colorWithRed:[C4Math randomInt:100]/100.0f
                                     green:[C4Math randomInt:100]/100.0f
                                      blue:0.5f
                                     alpha:1.0f];
}
@end

注意:我将计时器直接添加到splitSquare对象中。

beginUpdating当您创建更新计时器时,使您的动画更流畅的主要事情发生在该方法中。

最初,您在每秒钟0.25更新和触发计时器之前制作了几秒钟的动画0.25。我更改了动画持续时间,使其立即生效(0.0f 秒)。

然后,我通过在 '1/60.0f' 秒触发计时器来更改更新计时器以运行,60fps以使动画更流畅。

splitSquare通过将动画和计时器添加到方法本身,我做了一个替代实现(只是为了表明它也可以这样做) 。C4WorkSpace更改为以下内容:

#import "C4WorkSpace.h"
#import "splitSquare.h"

@implementation C4WorkSpace {
    splitSquare *testShape;
}

-(void)setup {
    testShape = [[splitSquare alloc] initWithPoint:CGPointMake(100,100)];
    [self.canvas addShape:testShape];
    [testShape beginUpdating];
}

@end

工作区不是管理对象本身的动画,而是简单地开始告诉对象beginUpdating


有点关于发生了什么。

如您所知,主要区别之一是没有默认的绘制循环。造成这种情况的部分原因是,作为开发人员,您几乎从不真正处理将对象实际绘制/渲染到屏幕上。当您创建一个视觉对象并将其添加到画布时,渲染由系统本身完成,因此绘图在系统资源上的效率更高。这是处理媒体的理想方式,不仅在 C4 中,而且在 iOS 编程中。

没有绘制循环肯定是不同的,需要一些时间来适应。但是,这确实是一种很好的工作方式。

本质上,其他 api 中的绘图循环每 30 或 60 秒由诸如计时器之类的东西触发。因此,如果您需要类似循环的功能,则以更新形状的方式添加计时器正是您想要做的。

在 C4 中没有计时器的好处是您可以简单地添加一个到您的工作区来控制更新的触发。更好的是,您可以将计时器添加到各个对象,以便它们可以自我更新。这意味着您还可以让多个对象中的多个计时器在不同的时间/延迟进行更新,以创建比仅使用单个运行循环所能获得的更动态的操作集。

于 2013-06-15T16:03:26.593 回答