如何在没有平局的情况下工作();循环在C4

时间:2013-06-14 17:53:32

标签: c4

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

我似乎无法在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并显示当前线程)。

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

1 个答案:

答案 0 :(得分: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编程中处理媒体的理想方式。

没有绘制循环肯定是不同的,需要一些习惯。但是,这真的是一种很好的工作方式。

从本质上讲,其他apis中的draw-loop会被每30或60秒的定时器触发。因此,如果您需要类似循环的功能,那么按照更新形状的方式添加计时器就是您想要做的事情。

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