3

私の質問はiOS開発についてです。低レベルのコアグラフィックス機能(コンテキスト、レイヤーなど)をテストし、それを実際の単純なビューと混合する方法をテストするために、単純なゲームを書いています...説明します:画面に単純なスプライトがあります。プロパティでアニメーション化されるUIImageViewため、フレームレートは完全に機能します。その後、でオンザフライで生成される無限の背景を追加しました bezier curves。これをアニメーション化するために、バックグラウンドでCADisplayLinkメソッド"animate"を呼び出してポイントを移動するを使用してbezier curveから、を呼び出しますsetNeedsDisplay。「多かれ少なかれ」うまく機能しますが、背景を削除すると(またはsetNeedsDisplay呼び出し元なので、フレームごとに再生成されないため)、フレームレートが大幅に増加するため、この部分では「何か」が正しく機能しません。

ダブルバッファリングシステムも試しましたが、現在のコードよりもうまく機能しません。私もスレッドを使用することについては考えていますが、CPUがバックグラウンドで実行するのは難しいことではありません。

コードは次のとおりです。

//This is called automatically with CADDisplayLink.
- (void) animate:(CADisplayLink *)sender
{
    //Check for deleting the first point.
    float x = points[firstPoint].x;
    if ( x < -2*DIST ) {
        CGFloat lastX = points[lastPoint].x;
        lastPoint = firstPoint;
        firstPoint = ((firstPoint + 1) % (TOTAL_POINTS));
        points[lastPoint] = CGPointMake(lastX + DIST, [self getNextY]);
    }

    //Move points
    for(int i = 0; i < TOTAL_POINTS; i++) {
        points[i].x -= 7;
    }

    //Mark as "needed to redraw"
    [self setNeedsDisplay];

}

- (void)drawRect:(CGRect)rect
{    
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetLineWidth(context, 3.0);
    CGContextSetRGBStrokeColor(context, 0, 0, 0, 1.0);
    CGContextSetRGBFillColor(context, 1.0, 0, 0, 1.0);
    CGContextSetLineCap(context, kCGLineCapRound);

    //Create path
    CGMutablePathRef path = CGPathCreateMutable();

    //Draw the curve
    [self drawBezierCurveInPath:path];

    //Close and add path
    CGPathAddLineToPoint(path, NULL, 485, -5);
    CGPathAddLineToPoint(path, NULL, -5, -5);
    CGPathCloseSubpath(path);

    CGContextAddPath(context, path);

    CGContextSetFillColorWithColor(context, bg2);

    //    [[UIColor redColor] setFill];
    [[UIColor blackColor] setStroke];

    CGContextDrawPath(context, kCGPathFillStroke);    

    //Release
    CGPathRelease(path);

    //Paint time.
    playintIntervalView.text = [NSString stringWithFormat:@"%f", playingInterval];
}

- (void) drawBezierCurveInPath: (CGMutablePathRef) path
{
    CGPoint fp = midPoint(points[firstPoint], points[(firstPoint+1)%TOTAL_POINTS]);
    CGPathMoveToPoint(path, NULL, fp.x, fp.y);

    int i = firstPoint;
    for (int k = 0; k < TOTAL_POINTS-2; k++) {
        previousPoint2 = points[i];
        previousPoint1 = points[(i+1)%TOTAL_POINTS];
        currentPoint = points[(i+2)%TOTAL_POINTS];

        // calculate mid point
        CGPoint mid2 = midPoint(currentPoint, previousPoint1);

        CGPathAddQuadCurveToPoint(path, nil, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y); 

        i = (i + 1) % TOTAL_POINTS;        
    }

}

を保存したいのですがUIBezierPath(衝突テストを行うことができます)、1つのポイントを削除することはできません(左側の画面を離れるとき)。そのため、フレームごとに初期化する必要があります。 ..何か足りないのですか?

4

1 に答える 1

2

これはおそらく少し遅いですが、この状況でCADisplayLinkを使用してアニメーション化することはお勧めできません。パスの効率的なアニメーションについては、CoreAnimationを調べる必要があります。

ここでの問題は、1秒間に60回再描画しようとしていて、drawRectのコードがそのためのミリ秒以内に完了しない可能性があることです。setNeedsDisplayを削除すると、基本的に更新しないように指示されます。

于 2013-08-21T21:52:23.890 に答える