Czy można narysować wypełnione kółko za pomocą cocos2d? Zakreślone koło można wykonać za pomocą funkcji drawCircle(), ale czy istnieje sposób na wypełnienie go określonym kolorem? Być może używając czystej OpenGL?Jak narysować solidne kółko z cocos2d dla iPhone'a
Odpowiedz
Spójrz na:
- CGContextAddArc
- CGContextFillPath
To pozwoli Ci wypełnić kółko bez konieczności OpenGL
Zastanawiam się również to, ale naprawdę nie dokonał robić to. Próbowałem używać rzeczy CGContext, które Grouchal przechylił powyżej, ale nie mogę tego zrobić, aby narysować cokolwiek na ekranie. To co próbowałem:
-(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]));
}
Metody te są zdefiniowane w klasie cocos węzła, a metoda makestuff pożyczyłem od przykładzie kodu ...
UWAGA: Próbuję narysuj dowolny kształt lub ścieżkę i wypełnij go. Wiem, że powyższy kod tylko rysuje linie, ale nie chciałem kontynuować, dopóki nie zadziałało.
EDYTOWANIE: To jest prawdopodobnie brzydkie rozwiązanie, ale myślę, że to będzie co najmniej pracy.
Każdy kod CocosNode ma teksturę (Texture2D *). Klasa Texture2D może zostać zainicjowana z UIImage. UIImage można zainicjować z CGImageRef. Możliwe jest stworzenie kontekstu CGImageRef dla biblioteki kwarcowej.
Więc, co chcesz zrobić, to:
- Tworzenie kontekstu CGImageRef dla kwarcu
- Nabrać do tego zdjęcia z kwarcu
- zainicjować UIImage z tym CGImageRef
- Zrób Texture2D który jest zainicjalizowany tym obrazem
- Ustaw teksturę węzła CocosNode na tę instancję Texture2D
Pytanie brzmi, czy byłoby to wystarczająco szybkie. Wolałbym, gdybyś mógł pobrać CGImageRef z CocosNode bezpośrednio i narysować go zamiast przechodzić przez wszystkie te kroki, ale nie znalazłem jeszcze sposobu na zrobienie tego jeszcze (i jestem noobem w tym więc naprawdę trudno jest gdzieś dotrzeć).
W DrawingPrimitives.m, to zmienić w drawCricle:
glDrawArrays(GL_LINE_STRIP, 0, segs+additionalSegment);
do:
glDrawArrays(GL_TRIANGLE_FAN, 0, segs+additionalSegment);
Możesz przeczytać więcej o OpenGL prymitywów tutaj: http://www.informit.com/articles/article.aspx?p=461848
Oto niewielka modyfikacja ccDrawCircle (), która pozwala narysować dowolny kawałek koła. Trzymać to w CCDrawingPrimitives.m i dodawać informacje Sposób nagłówkowego CCDrawingPrimitives.h:
parametry: a
: kąt startu w radianach d
Delta lub zmiany kąta w radianach (Użyj 2*M_PI
do pełnego okręgu)
Zmiany są skomentował
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);
}
Kiedyś tędy poniżej.
glLineWidth(2);
for(int i=0;i<50;i++){
ccDrawCircle(ccp(s.width/2, s.height/2), i,0, 50, NO);
}
Wykonałem wiele kół z pętlą for i wygląda jak wypełnione koło.
Istnieje nowa funkcja w cocos2d CCDrawingPrimitives
o nazwie ccDrawSolidCircle(CGPoint center, float r, NSUInteger segs)
. Dla tych, którzy na to patrzą teraz, użyj tej metody, a następnie nie musisz zadzierać z kodem cocos2d, po prostu zaimportuj CCDrawingPrimitives.h