Cocos2D& ccDrawLine - 绘制流畅的线条

时间:2013-07-28 05:42:40

标签: ios objective-c opengl-es cocos2d-iphone

当我尝试用cocos2d绘制线条时,我遇到了一些麻烦!我在一个NSMutableArray中存储了从touchMoved方法得到的点,并将该数组传递给CCNode的子类,称为Lines,用于从点数组中绘制线条。问题是当我慢慢滑动时线条不平滑,但是当我刷得更快时,线条更加平滑。见下图:

慢速滑动 Slow swipe

快速刷卡: Fast swipe

我尝试用ccpDistance解决问题,ccpDistance计算最后保存点之间的距离,如果不够远,我就不保存它。我还尝试在每个保存的位置绘制小圆圈,但这也不是很好。这是我的代码:

在我的GameScene中:

- (void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
    CGPoint location = [touch locationInView:[touch view]];
    location = [[CCDirector sharedDirector] convertToGL:location];

    if (ccpDistance(lastPoint, location) > 10) {
        //SAVE THE POINT
        [linePoints addObject:[NSValue valueWithCGPoint:location]];

        [line updatePoints:linePoints];

        lastPoint = location;
    }
}

我的Line Class:

- (void) updatePoints:(NSMutableArray *)_point
{
    points = _point;
}

- (void) draw
{
    if ([points count] > 0) {
        ccGLEnable(GL_LINE_STRIP);

        ccDrawColor4B(209, 75, 75, 255);

        float lineWidth = 6.0 * CC_CONTENT_SCALE_FACTOR();

        glLineWidth(lineWidth);

        int count = [points count];

        for (int i = 0; i < (count - 1); i++){
            CGPoint pos1 = [[points objectAtIndex:i] CGPointValue];
            CGPoint pos2 = [[points objectAtIndex:i+1] CGPointValue];

            ccDrawLine(pos1, pos2);
            ccDrawSolidCircle(pos2, 2.5, 20);
        }
    }
}

此外,我的代码中是否有一些可以更好地提高性能?现在即使有1000多分,我也没有任何问题,但以防万一...

任何帮助将不胜感激!提前谢谢!

2 个答案:

答案 0 :(得分:4)

好的,我发现一个网站非常清楚地解释了如何做到流畅的线条,并且效果非常好!仍然有抗锯齿作用,但也许我永远不会做,因为它在视网膜设备上看起来非常棒。这是网站:Drawing Smooth Lines with Cocos2D

以下是结果: Smooth Lines

此外,对于那些对完成代码感兴趣的人,这里是:

<强> Line.m

- (void) drawCurPoint:(CGPoint)curPoint PrevPoint:(CGPoint)prevPoint
{
    float lineWidth = 6.0;
    ccColor4F red = ccc4f(209.0/255.0, 75.0/255.0, 75.0/255.0, 1.0);

    //These lines will calculate 4 new points, depending on the width of the line and the saved points
    CGPoint dir = ccpSub(curPoint, prevPoint);
    CGPoint perpendicular = ccpNormalize(ccpPerp(dir));
    CGPoint A = ccpAdd(prevPoint, ccpMult(perpendicular, lineWidth / 2));
    CGPoint B = ccpSub(prevPoint, ccpMult(perpendicular, lineWidth / 2));
    CGPoint C = ccpAdd(curPoint, ccpMult(perpendicular, lineWidth / 2));
    CGPoint D = ccpSub(curPoint, ccpMult(perpendicular, lineWidth / 2));

    CGPoint poly[4] = {A, C, D, B};

    //Then draw the poly, and a circle at the curPoint to get smooth corners
    ccDrawSolidPoly(poly, 4, red);
    ccDrawSolidCircle(curPoint, lineWidth/2.0, 20);
}

- (void) draw
{
    if ([points count] > 0) {
        ccGLEnable(GL_LINE_STRIP);

        ccColor4F red = ccc4f(209.0/255.0, 75.0/255.0, 75.0/255.0, 1.0);
        ccDrawColor4F(red.r, red.g, red.b, red.a);

        float lineWidth = 6.0 * CC_CONTENT_SCALE_FACTOR();

        glLineWidth(lineWidth);

        int count = [points count];

        for (int i = 0; i < (count - 1); i++){
            CGPoint pos1 = [[points objectAtIndex:i] CGPointValue];
            CGPoint pos2 = [[points objectAtIndex:i+1] CGPointValue];

            [self drawCurPoint:pos2 PrevPoint:pos1];
        }
    }
}

对于GameScene,没有任何改变(请参阅代码问题)!请注意,您可以更改行if (ccpDistance(lastPoint, location) > X),其中X是游戏保存另一个点之前两点之间的最小距离。 X越低,线条越平滑,但阵列中的点数会更多,这可能会影响性能!

无论如何,谢谢你们的建议和帮助,这有助于我以正确的方式行事!

答案 1 :(得分:0)

我认为你可以通过一些平均来平滑你的线条画。

- (void) updatePoints:(NSMutableArray *)_point
{
    points = _point;
    int count = [points count];
    for (int i = 3; i < (count - 4); i++) {
        CGPoint pos1 = [[points objectAtIndex:i - 2] CGPointValue];
        CGPoint pos2 = [[points objectAtIndex:i - 1] CGPointValue];
        CGPoint pos3 = [[points objectAtIndex:i] CGPointValue];
        CGPoint pos4 = [[points objectAtIndex:i + 1] CGPointValue];
        CGPoint pos5 = [[points objectAtIndex:i + 2] CGPointValue];
        CGFloat xpos = (pos1.x + pos2.x + 2 * pos3.x + pos4.x + pos5.x)/6;

        ...
        (now calcuclate ypos similarly and store the point into an array)
    }
}