How to draw a solid circle with cocos2d for iPhone

后端 未结 6 1781
遇见更好的自我
遇见更好的自我 2021-02-02 15:53

Is it possible to draw a filled circle with cocos2d ? An outlined circle can be done using the drawCircle() function, but is there a way to fill it in a certain color? Perhaps b

相关标签:
6条回答
  • 2021-02-02 16:15

    I used this way below.

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

    I made multiple circle with for loop and looks like a filled circle.

    0 讨论(0)
  • 2021-02-02 16:18

    In DrawingPrimitives.m, change this in drawCricle:

    glDrawArrays(GL_LINE_STRIP, 0, segs+additionalSegment);
    

    to:

    glDrawArrays(GL_TRIANGLE_FAN, 0, segs+additionalSegment);
    

    You can read more about opengl primitives here: http://www.informit.com/articles/article.aspx?p=461848

    alt text

    0 讨论(0)
  • 2021-02-02 16:20

    Here's a slight modification of ccDrawCircle() that lets you draw any slice of a circle. Stick this in CCDrawingPrimitives.m and also add the method header information to CCDrawingPrimitives.h:

    Parameters: a: starting angle in radians, d: delta or change in angle in radians (use 2*M_PI for a complete circle)

    Changes are commented

    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 );
    }
    
    0 讨论(0)
  • 2021-02-02 16:30

    I also wonder this, but haven't really accomplished doing it. I tried using CGContext stuff that Grouchal tipped above, but I can't get it to draw anything on the screen. This is what I've tried:

    -(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]));
    }
    

    These methods are defined in a cocos node class, and the makestuff method I borrowed from a code example...

    NOTE: I'm trying to draw any shape or path and fill it. I know that the code above only draws lines, but I didn't wanna continue until I got it working.

    EDIT: This is probably a crappy solution, but I think this would at least work.

    Each CocosNode has a texture (Texture2D *). Texture2D class can be initialized from an UIImage. UIImage can be initialized from a CGImageRef. It is possible to create a CGImageRef context for the quartz lib.

    So, what you would do is:

    1. Create the CGImageRef context for quartz
    2. Draw into this image with quartz
    3. Initialize an UIImage with this CGImageRef
    4. Make a Texture2D that is initialized with that image
    5. Set the texture of a CocosNode to that Texture2D instance

    Question is if this would be fast enough to do. I would prefer if you could sort of get a CGImageRef from the CocosNode directly and draw into it instead of going through all these steps, but I haven't found a way to do that yet (and I'm kind of a noob at this so it's hard to actually get somewhere at all).

    0 讨论(0)
  • 2021-02-02 16:33

    Look into:

    • CGContextAddArc
    • CGContextFillPath

    These will allow you to fill a circle without needing OpenGL

    0 讨论(0)
  • 2021-02-02 16:34

    There is a new function in cocos2d CCDrawingPrimitives called ccDrawSolidCircle(CGPoint center, float r, NSUInteger segs). For those looking at this now, use this method instead, then you don't have to mess with the cocos2d code, just import CCDrawingPrimitives.h

    0 讨论(0)
提交回复
热议问题