كيف يمكنني تحريك CGPath دون إنشاء واحدة جديدة
-
20-09-2019 - |
سؤال
أقوم بإنشاء ملف 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)];