Как нарисовать сплошной круг с cocos2d для iPhone

Можно ли нарисовать заполненный круг с cocos2d? Выделенный круг может быть выполнен с использованием функции drawCircle(), но есть ли способ заполнить его определенным цветом? Возможно, используя чистый OpenGL?

Ответы

Ответ 1

В 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

Ответ 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 );
}

Ответ 3

Посмотрите:

  • CGContextAddArc
  • CGContextFillPath

Это позволит вам заполнить круг без необходимости использования OpenGL

Ответ 4

Я также удивляюсь этому, но на самом деле этого не сделал. Я попытался использовать материал CGContext, который Grouchal опрокинул выше, но я не могу заставить его ничего нарисовать на экране. Это то, что я пробовал:

-(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 node, а метод makestuff, который я заимствовал из примера кода...

Примечание: Я пытаюсь нарисовать любую форму или путь и заполнить ее. Я знаю, что вышеприведенный код рисует линии, но я не хотел продолжать, пока не получил работу.

EDIT: Это, вероятно, дрянное решение, но я думаю, что это по крайней мере сработало.

Каждый CocosNode имеет текстуру (Texture2D *). Класс Texture2D может быть инициализирован из UIImage. UIImage можно инициализировать из CGImageRef. Можно создать контекст CGImageRef для кварцевой библиотеки.

Итак, что вы будете делать:

  • Создайте контекст CGImageRef для кварца
  • Нарисуйте это изображение с помощью кварца
  • Инициализировать UIImage с помощью этого CGImageRef
  • Сделайте Texture2D, инициализированный этим изображением
  • Задайте текстуру CocosNode этому экземпляру Texture2D

Вопрос в том, достаточно ли это сделать. Я бы предпочел, если бы вы могли получить CGImageRef напрямую из CocosNode и нарисовать его, а не пройти все эти шаги, но я еще не нашел способ сделать это (и я вроде как noob на этом так что вообще сложно попасть куда-нибудь вообще).

Ответ 5

В cocos2d CCDrawingPrimitives есть новая функция, называемая ccDrawSolidCircle(CGPoint center, float r, NSUInteger segs). Для тех, кто смотрит на это сейчас, используйте этот метод вместо этого, тогда вам не нужно возиться с кодом cocos2d, просто импортируйте CCDrawingPrimitives.h

Ответ 6

Я использовал этот способ ниже.

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

Я сделал несколько кругов с циклом for и выглядел как заполненный круг.