Как нарисовать сплошной круг с 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 и выглядел как заполненный круг.