2012-02-20 13 views
14

मेरे पास एक छवि है जिसमें 100 छवियां हैं। मैं फ्रेम के अनुक्रम के माध्यम से एनीमेशन प्रदर्शित करने में सक्षम होना चाहता हूँ। उदाहरण के लिए, एनीमेशन को 0:00 सेकेंड से 0:32 सेकेंड तक प्रदर्शित करने के बजाय, मैं फ़्रेम 32 का फ़्रेम 32 का उपयोग करूंगा। मुझे ऐसा करने की ज़रूरत है क्योंकि मुझे एनीमेशन पर बहुत अधिक नियंत्रण की आवश्यकता है (यहां तक ​​कि एक के अंतर फ्रेम गलत परिणाम देगा)। मैंने व्यक्तिगत रूप से प्रत्येक फ्रेम खींचा है, इसलिए मुझे प्रत्येक फ्रेम की छवि पता है।फ्रेम द्वारा एनीमेशन प्रदर्शित करना?

क्या वैसे भी मैं कोको में ऑब्जेक्टिव-सी का उपयोग करके ऐसा कर सकता हूं? यह मैं कैसे करूंगा? मेरे पास 100 छवियां हैं और मुझे नहीं पता कि यहां से कैसे आगे बढ़ना है। और, क्या यह समय के अनुसार निर्दिष्ट करने की तुलना में "लगी" होगी?

मैं एक विस्तृत उत्तर पसंद करूंगा क्योंकि मुझे ऑनलाइन कोई संसाधन नहीं मिला और मैं इसके लिए बिल्कुल नया हूं।

ध्यान दें कि मैं ओएस एक्स का उपयोग कर रहा हूं, आईओएस नहीं, इसलिए कृपया आईओएस से संबंधित उत्तर प्रदान न करें। मैं हिम तेंदुए पर एक्सकोड 3.2.6 के साथ काम कर रहा हूं।

उत्तर

7

सबसे अधिक नियंत्रण रखने का तरीका आपकी सभी छवियों को एक सरणी में स्टोर करना होगा। आप अपने चित्रों की तरह "frame.png" (यानी "frame1.png") कुछ नाम दिया है, तो आप जल्दी से अपने सभी चित्रों को इस तरह लोड कर सकते हैं:

frames = [[NSMutableArray alloc] init]; // In header: NSMutableArray *frames; 
for (int i = 1; i < 100; i++) // 100 can be replaced for any number of frames. 
{ 
    NSString *filename = [NSString stringWithFormat:@"frame%i.png", i]; 
    [frames addObject:[NSImage imageNamed:filename]]; 
} 

क्या करता है एक सरणी बनाता है और साथ यह भरता है NSImage एस आपकी फाइलों के नाम पर रखा गया है। %i को i के वर्तमान मान के लिए स्ट्रिंग में प्रतिस्थापित किया गया है।

अब, आपको वर्तमान फ्रेम का ट्रैक रखने के लिए एक और चर की आवश्यकता होगी। कुछ की तरह। यह या तो प्रत्येक अपडेट लूप को बढ़ाया जा सकता है, या एक विशिष्ट मान पर सेट किया जा सकता है, जिससे आप प्रदर्शित फ्रेम पर पूर्ण नियंत्रण दे सकते हैं।

फिर, अपने पाश प्रस्तुत करना, आप प्रदान कर सकते हैं, जो भी फ्रेम वर्तमान में इस तरह संग्रहीत किया जाता है:

[(NSImage *)[frames objectAtIndex:currentFrame - 1] drawAtPoint:animPos fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f]; 

जहां animPos एक NSPoint स्थिति में आप पर आकर्षित करने के लिए इच्छा से युक्त है। - 1 इंडेक्स में है ताकि आप अपने फ्रेम को 0 से 1 पर शुरू कर सकें। यह कोड छवि को currentFrame पर खींचता है और इसे स्क्रीन पर प्रस्तुत करता है।

चूंकि आप एक सरणी का उपयोग कर रहे हैं, तो यह सुनिश्चित करना भी सुनिश्चित करें कि currentFrame फ्रेम की अधिकतम संख्या से अधिक मूल्य के बराबर कभी नहीं है, जैसे: if (currentFrame > 100) currentFrame = 1;। यह एनीमेशन को लूप का कारण बनता है, क्योंकि जब यह अंतिम फ्रेम तक जाता है, तो वर्तमान फ्रेम को सरणी की शुरुआत सूचकांक में वापस सेट किया जाएगा।

ड्राइंग के बारे में अधिक जानकारी के लिए, आपको यह देखना चाहिए: Cocoa Drawing Guide और NSImage Class Reference। इसके अलावा, यदि आपको समय की हर वृद्धि के फ्रेम को अपडेट करने के तरीके के बारे में अधिक जानकारी चाहिए, तो NSTimer Class Reference देखें।

+0

रेंडर लूप कोड कहां जाएगा? मेरा मतलब क्या वर्ग है? क्या यह एक एनएसआईमेज व्यू होगा? – fdh

+0

'drawAtPoint:' कोड किसी भी कक्षा में जा सकता है जिसे आप चाहें। इसे एनएसआईमेज व्यू के अंदर निष्पादित करने की आवश्यकता नहीं है, और यह बिना किसी विचार के खिड़की में कहीं भी प्रस्तुत कर सकता है। यदि आपके पास कई कक्षाएं नहीं हैं, तो इसे एप्लिकेशन प्रतिनिधि में छोड़ना सबसे आसान हो सकता है। हालांकि, अगर आप एक एनएसआईमेज व्यू का उपयोग करना चाहते हैं, तो आप 'ड्रॉएटपॉइंट * के बजाय' [एनएसआईमेज व्यू सेट इमेज: (एनएसआईमेज *) [फ्रेम ऑब्जेक्ट एट इंडेक्स: वर्तमानफ्रेम - 1]] 'का उपयोग कर सकते हैं और दृश्य को प्रतिपादन, पोजीशनिंग इत्यादि को संभालने दें। – wquist

+0

धन्यवाद आप, यह काम करता है! – fdh

0

आप NSAnimation उपवर्गीकरण, और यह छवि हर टिकटिक दिखाया बदल होने की कोशिश की है?

संपादित करें:

सबसे पहले, आप NSAnimation का एक उपवर्ग पैदा करते हैं। फिर, setCurrentProgress: को अपने सुपरक्लास कार्यान्वयन को कॉल करके ओवरराइड करें, और इसे currentValue के आधार पर दृश्य को बदल दें। अधिक गहराई से निर्देशों के लिए निम्न मार्गदर्शिका देखें: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/AnimationGuide/Articles/TimingAnimations.html#//apple_ref/doc/uid/TP40003581-SW1

+0

क्या आप विस्तार कर सकते हैं? यह मैं कैसे करूंगा? मैंने पहले कभी एनएसएनीमेशन के साथ काम नहीं किया है। – fdh

+0

यह एक काफी सरल प्रक्रिया है, जो एनएसएनीमेशन के लिए दस्तावेज़ीकरण में स्पष्ट रूप से समझाया गया है। अधिक जानकारी के लिए मेरा संपादन देखें। – Daniel

+0

कोई भी जानता है कि इन सभी उत्तरों को क्यों हटा दिया गया था? – Daniel

0

मैं एक साधारण परियोजना है कि आप parhaps उपयोग कर सकते हैं बनाया: you can find the project here

मैं इस आशा है कि आप क्या जरूरत है

2

आप के लिए इस कोड का उपयोग कर सकते हैं अपने फ्रेम एनीमेशन द्वारा फ्रेम। आशा है कि यह आपकी मदद करेगा।

// create the view that will execute our animation 
UIImageView* imageListView = [[UIImageView alloc] initWithFrame:self.view.frame]; 

// load all the frames of our animation 
imageListView.animationImages = [NSArray arrayWithObjects:  
          [UIImage imageNamed:@"campFire01.gif"], 
          [UIImage imageNamed:@"campFire02.gif"], 
          [UIImage imageNamed:@"campFire03.gif"], 
          [UIImage imageNamed:@"campFire04.gif"], 
          [UIImage imageNamed:@"campFire05.gif"], 
          [UIImage imageNamed:@"campFire06.gif"], 
          [UIImage imageNamed:@"campFire07.gif"], 
          [UIImage imageNamed:@"campFire08.gif"], 
          [UIImage imageNamed:@"campFire09.gif"], 
          [UIImage imageNamed:@"campFire10.gif"], 
          [UIImage imageNamed:@"campFire11.gif"], 
          [UIImage imageNamed:@"campFire12.gif"], 
          [UIImage imageNamed:@"campFire13.gif"], 
          [UIImage imageNamed:@"campFire14.gif"], 
          [UIImage imageNamed:@"campFire15.gif"], 
          [UIImage imageNamed:@"campFire16.gif"], 
          [UIImage imageNamed:@"campFire17.gif"], 
           //all your 100 images// , nil]; 

// all frames will execute in 1.75 seconds 
imageListView.animationDuration = 1.75; 
// repeat the annimation forever 
imageListView.animationRepeatCount = 0; 
// start animating 
[imageListView startAnimating]; 
// add the animation view to the main window 
[self.view addSubview:imageListView]; 
+1

यह केवल आईओएस पर काम करता है, सवाल ओएस एक्स के बारे में है। –

1

आप CADisplayLink का उपयोग करने पर विचार कर सकते हैं।

अपने प्रारंभ विधि में, सेटअप प्रदर्शन लिंक:,

- (void)playAnimation:(CADisplayLink*)displayLink 
{ 
    // Set the right image to display 
    self.imageToDisplay = TheRightImageBasedOnYourAnimationSequence 

    [self setNeedsDisplay]; 
} 

और अंत में drawRect में:

CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(playAnimation:)]; 
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];  

तो विधि जोड़ने इसका इस्तेमाल करने के बारे में एक उदाहरण है विधि , छवि प्रदर्शित करें। CADisplayLink वर्ग फ्रेम अवधि, आदि को नियंत्रित करने के ...

1

@ wquist की प्रतिक्रिया दोहराना करने के लिए जिम्मेदार बताते है: -

frames = [[NSMutableArray alloc] init]; // In header: NSMutableArray *frames; 
for (int i = 1; i < 100; i++) // 100 can be replaced for any number of frames. 
{ 
    NSString *filename = [NSString stringWithFormat:@"frame%i.png", i]; 
    [frames addObject:[NSImage imageNamed:filename]]; 
} 

अतीत में मैं इस तरह के image_00000.png के रूप में फ़ाइल नाम के साथ एनिमेशन के एक नंबर मिला है , image_00001.png और उनकी देखभाल करने के लिए मैंने इस तरह कुछ उपयोग किया: -

NSString *filename = [NSString stringWithFormat:@"frame%05d.png", i]; 
संबंधित मुद्दे