4

当我尝试用 cocos2d 画线时,我遇到了一些麻烦!我将从 touchMoved 方法获得的点存储在 NSMutableArray 中,并将该数组传递给 CCNode 的子类,称为 Lines,我使用它从点数组中绘制线。问题是当我缓慢滑动时线条不平滑,但是当我快速滑动时,线条要平滑得多。请看下面的图片:

慢速滑动: 缓慢滑动

快速滑动: 快速滑动

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

在我的游戏场景中:

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

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

4

2 回答 2

4

好的,我找到了一个网站,非常清楚地解释了如何制作流畅的线条,效果非常好!仍然有抗锯齿要做,但也许我永远不会做,因为它在视网膜设备上看起来真的很棒。这是网站:使用 Cocos2D 绘制平滑线

结果如下: 流畅的线条

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

线.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,那里没有任何改变(参见代码问题)!请注意,您可以更改 line if (ccpDistance(lastPoint, location) > X),其中 X 是游戏保存另一个点之前两点之间的最小距离。X 越低,线条越平滑,但数组中的点会更多,这可能会影响性能!

无论如何,谢谢你们的建议和帮助,它帮助我走上了正确的道路!

于 2013-07-28T17:06:34.090 回答
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)
    }
}
于 2013-07-28T07:23:22.867 回答