如何使用cocos2d为iPhone绘制一个实心圆圈

时间:2009-07-04 08:58:32

标签: iphone opengl-es cocos2d-iphone geometry

是否可以使用cocos2d绘制实心圆? 可以使用drawCircle()函数完成轮廓圆,但有没有办法以某种颜色填充它?也许是通过使用纯OpenGL?

6 个答案:

答案 0 :(得分:21)

在DrawingPrimitives.m中,在drawCricle中更改:

glDrawArrays(GL_LINE_STRIP, 0, segs+additionalSegment);

为:

glDrawArrays(GL_TRIANGLE_FAN, 0, segs+additionalSegment);

您可以在此处阅读有关opengl原语的更多信息: http://www.informit.com/articles/article.aspx?p=461848

alt text

答案 1 :(得分:2)

这里有一个ccDrawCircle()的略微修改,可以让你绘制圆的任何切片。将其粘贴在CCDrawingPrimitives.m中,并将方法标题信息添加到CCDrawingPrimitives.h中:

参数:a:以弧度为单位的起始角度,d:以弧度为单位的增量或角度变化(使用2*M_PI表示完整的圆圈)

更改被评论

void ccDrawFilledCircle( CGPoint center, float r, float a, float d, NSUInteger totalSegs)
{
    int additionalSegment = 2;

    const float coef = 2.0f * (float)M_PI/totalSegs;

    NSUInteger segs = d / coef;
    segs++; //Rather draw over than not draw enough

    if (d == 0) return;

    GLfloat *vertices = calloc( sizeof(GLfloat)*2*(segs+2), 1);
    if( ! vertices )
        return;

    for(NSUInteger i=0;i<=segs;i++)
    {
        float rads = i*coef;
        GLfloat j = r * cosf(rads + a) + center.x;
        GLfloat k = r * sinf(rads + a) + center.y;

        //Leave first 2 spots for origin
        vertices[2+ i*2] = j * CC_CONTENT_SCALE_FACTOR();
        vertices[2+ i*2+1] =k * CC_CONTENT_SCALE_FACTOR();
    }
    //Put origin vertices into first 2 spots
    vertices[0] = center.x * CC_CONTENT_SCALE_FACTOR();
    vertices[1] = center.y * CC_CONTENT_SCALE_FACTOR();

    // Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
    // Needed states: GL_VERTEX_ARRAY, 
    // Unneeded states: GL_TEXTURE_2D, GL_TEXTURE_COORD_ARRAY, GL_COLOR_ARRAY   
    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);

    glVertexPointer(2, GL_FLOAT, 0, vertices);
    //Change to fan
    glDrawArrays(GL_TRIANGLE_FAN, 0, segs+additionalSegment);

    // restore default state
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_TEXTURE_2D);    

    free( vertices );
}

答案 2 :(得分:1)

查看:

  • CGContextAddArc
  • CGContextFillPath

这些将允许您填充圆圈而无需OpenGL

答案 3 :(得分:1)

我也很想知道这一点,但还没有真正做到这一点。我尝试使用Grouchal上面提到的CGContext的东西,但我不能让它在屏幕上绘制任何东西。这就是我尝试过的:

-(void) draw
{
    [self makestuff:UIGraphicsGetCurrentContext()]; 
}

-(void)makestuff:(CGContextRef)context
{
    // Drawing lines with a white stroke color
    CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0);
    // Draw them with a 2.0 stroke width so they are a bit more visible.
    CGContextSetLineWidth(context, 2.0);

    // Draw a single line from left to right
    CGContextMoveToPoint(context, 10.0, 30.0);
    CGContextAddLineToPoint(context, 310.0, 30.0);
    CGContextStrokePath(context);

    // Draw a connected sequence of line segments
    CGPoint addLines[] =
    {
        CGPointMake(10.0, 90.0),
        CGPointMake(70.0, 60.0),
        CGPointMake(130.0, 90.0),
        CGPointMake(190.0, 60.0),
        CGPointMake(250.0, 90.0),
        CGPointMake(310.0, 60.0),
    };
    // Bulk call to add lines to the current path.
    // Equivalent to MoveToPoint(points[0]); for(i=1; i<count; ++i) AddLineToPoint(points[i]);
    CGContextAddLines(context, addLines, sizeof(addLines)/sizeof(addLines[0]));
    CGContextStrokePath(context);

    // Draw a series of line segments. Each pair of points is a segment
    CGPoint strokeSegments[] =
    {
        CGPointMake(10.0, 150.0),
        CGPointMake(70.0, 120.0),
        CGPointMake(130.0, 150.0),
        CGPointMake(190.0, 120.0),
        CGPointMake(250.0, 150.0),
        CGPointMake(310.0, 120.0),
    };
    // Bulk call to stroke a sequence of line segments.
    // Equivalent to for(i=0; i<count; i+=2) { MoveToPoint(point[i]); AddLineToPoint(point[i+1]); StrokePath(); }
    CGContextStrokeLineSegments(context, strokeSegments, sizeof(strokeSegments)/sizeof(strokeSegments[0]));
}

这些方法是在cocos节点类中定义的,而我从代码示例中借用的makestuff方法......

注意: 我正在尝试绘制任何形状或路径并填充它。我知道上面的代码只画线,但我不想继续,直到我开始工作。

编辑: 这可能是一个糟糕的解决方案,但我认为这至少可以工作

每个CocosNode都有一个纹理(Texture2D *)。 Texture2D类可以从UIImage初始化。 UIImage可以从CGImageRef初始化。可以为quartz lib创建CGImageRef上下文。

那么,你要做的是:

  1. 为quartz
  2. 创建CGImageRef上下文
  3. 使用石英
  4. 绘制此图像
  5. 使用此CGImageRef初始化UIImage
  6. 制作使用该图像初始化的Texture2D
  7. 将CocosNode的纹理设置为该Texture2D实例
  8. 问题是,这是否足够快。我更喜欢你是否可以直接从CocosNode获取CGImageRef而不是通过所有这些步骤进入它,但我还没有找到办法做到这一点(而且我在这方面有点像菜鸟)所以实际上很难到达某个地方。

答案 4 :(得分:0)

cocos2d CCDrawingPrimitives中有一个名为ccDrawSolidCircle(CGPoint center, float r, NSUInteger segs)的新功能。对于那些现在正在看这个的人来说,请使用这个方法,然后你不必乱用cocos2d代码,只需导入CCDrawingPrimitives.h

答案 5 :(得分:-1)

我在下面使用过这种方式。

glLineWidth(2);
for(int i=0;i<50;i++){
  ccDrawCircle( ccp(s.width/2,  s.height/2), i,0, 50, NO);
}

我用for循环创建了多个圆圈,看起来像一个圆圈。