سؤال

أقوم بإنشاء ملف CGPath لتحديد منطقة في لعبتي مثل هذا:

CGPathMoveToPoint   ( myPath, NULL, center.x, center.y );
CGPathAddLineToPoint( myPath, NULL,center.x + 100, center.y);
CGPathAddLineToPoint( myPath, NULL, center.x + 100, center.y + 100);
CGPathAddLineToPoint( myPath, NULL, center.x,  center.y + 100);
CGPathCloseSubpath  ( myPath );

أعلم أن هذا مجرد مربع ويمكنني فقط استخدام آخر CGRect لكن المسار الذي أرغب في إنشائه في الواقع ليس مستطيلًا (أنا فقط أختبر في الوقت الحالي). ثم اكتشاف منطقة اللمس ببساطة مع:

if (CGPathContainsPoint(myPath, nil, location, YES))

كل هذا يعمل بشكل جيد ، المشكلة هي أن CGPath قد تتحرك حتى 40 مرة في الثانية. كيف يمكنني تحريكه دون الحاجة إلى إنشاء واحدة جديدة؟ أعلم أنه يمكنني فعل شيء كهذا "لنقله":

center.y += x;
CGPathRelease(myPath);
myPath = CGPathCreateMutable();
CGPathMoveToPoint   ( myPath, NULL, center.x, center.y );
CGPathAddLineToPoint( myPath, NULL,center.x + 100, center.y);
CGPathAddLineToPoint( myPath, NULL, center.x + 100, center.y + 100);
CGPathAddLineToPoint( myPath, NULL, center.x,  center.y + 100);
CGPathCloseSubpath  ( myPath );

لكن يجب أن أصدر وإنشاء مسار جديد يصل إلى 40 مرة في الثانية ، وأعتقد أنه قد يكون لديه عقوبة أداء ؛ هل هذا صحيح؟

أود أن أكون قادرًا على تحريكها تمامًا كما أنا أتحرك حاليًا CGRects بمجرد تعيين الأصل على قيمة مختلفة ، هل هذا ممكن مع CGPath?

شكرًا لك.

تحرير: لقد نسيت أن أذكر أنه ليس لدي رسومات كونيتوت لأنني لا أرتقي على أ UIView.

هل كانت مفيدة؟

المحلول

إن تطبيق تحول على CGPath واختباره مقابل نقطة ، يعادل تطبيق معكوس التحول إلى هذه النقطة.

لذلك ، يمكنك استخدام

CGPoint adjusted_point = CGPointMake(location.x - center.x, location.y - center.y);
if (CGPathContainsPoint(myPath, NULL, adjusted_point, YES)) 

ولكن CGPathContainsPoint يأخذ بالفعل CGAffineTransform المعلمة (التي لديك NULL-

CGAffineTransform transf = CGAffineTransformMakeTranslation(-center.x, -center.y);
if (CGPathContainsPoint(myPath, &transf, location, YES)) 

إذا كنت ترسم ، بدلاً من تغيير المسار ، يمكنك تغيير CTM في رمز الرسم مباشرة.

CGContextSaveGState(c);
CGContextTranslateCTM(c, center.x, center.y);
// draw your path
CGContextRestoreGState(c);

إستخدم CAShapeLayer إذا كنت بحاجة إلى أداء.

نصائح أخرى

عملت إجابة @Kennytm بشكل مثالي لغرض البروتوكول الاختياري ، ولكن يبقى السؤال:

كيف يمكنني تحريك CGPath دون إنشاء واحدة جديدة؟

حسنًا ، قام سطران من الكود بالخدعة بالنسبة لي:

UIBezierPath* path = [UIBezierPath bezierPathWithCGPath:cgPath];
[path applyTransform:CGAffineTransformMakeTranslation(2.f, 0.f)];
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top