Cocos2D和ccDrawLine - 绘制平滑线条

4
我在使用cocos2d绘制线条时遇到了一些问题!我将从touchMoved方法得到的点存储在NSMutableArray中,并将该数组传递给CCNode子类Lines,以便从点数组绘制线条。问题是,当我缓慢滑动时,线条不流畅,但当我快速滑动时,线条则更加平滑。请参见下面的图片:
慢滑动: Slow swipe 快速滑动: Fast swipe 我尝试使用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;
    }
}

我的线路类:

- (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多个点也没有任何问题,但以防万一...

非常感谢您的帮助!提前致谢!


为了实现100%平滑无故障的线条,您必须将整条线作为单个多边形绘制,否则在两条线相交处总会出现微小的切口。 - CodeSmile
2个回答

4

好的,我找到了一个网站,非常清晰地解释了如何画出平滑的线条,并且效果非常好!虽然还有抗锯齿要做,但是在视网膜设备上看起来已经非常棒了。这是网站链接:使用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越低,线条将越平滑,但您的数组中将有更多的点,这可能会影响性能!无论如何,感谢您们的建议和帮助,它们帮助我找到了正确的道路!

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)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接