2011-03-07 14 views
19

मैं अपने कोकोस 2 डी प्रोजेक्ट में स्पर्श को संभालने का तरीका जानने में कुछ दिनों के लिए व्यस्त रहा हूं। स्थिति सामान्य के रूप में थोड़ा अलग है।एकाधिक परतों के साथ Cocos2d हैंडलिंग स्पर्श

  • ControlLayer:: मैं कुछ अलग खेल परतों कि मैं स्पर्श के साथ नियंत्रित करने के लिए की जरूरत है उस पर आइटम नहीं हैं कि खेल को नियंत्रित करता है (आंदोलन, कार्रवाई बटन) रखती है। यह परत शीर्ष पर है।
  • गेमप्लेयर: गेम ऑब्जेक्ट्स (CCSprites) रखता है। यह परत सीधे नियंत्रण लेयर के नीचे है।

अब मेरी छूता ControlLayer में अच्छा काम है, मैं अपने खेलने वाले चरित्र के चारों ओर ले जाने और उसे कूद और अन्य मूर्खतापूर्ण चीजें करते बना सकते हैं। फिर भी मैं समझ नहीं पा रहा हूं कि मेरे कुछ CCSprites को स्पर्श कैसे कार्यान्वित किया जाए।

जो जानकारी मैंने अभी तक एकत्र की है, मुझे लगता है कि मुझे नियंत्रण परत से अपने सभी स्पर्श इनपुट की आवश्यकता है। फिर मुझे गेमप्लेयर को स्पर्श जानकारी को 'कैस्केड' करने की ज़रूरत है ताकि मैं वहां इनपुट को संभाल सकूं। एक और विकल्प मेरे लिए मेरे sprites से सीजीआरईटी जानकारी प्राप्त करने के लिए होगा, किसी भी तरह से उन वस्तुओं को पॉइंटर्स के साथ एक सरणी बनाकर जो स्पर्श करने योग्य होना चाहिए। यदि आइटम स्पर्श किया गया था तो मुझे उस सूची में प्रत्येक आइटम की जांच करने के लिए ControlLayer में उस जानकारी का उपयोग करने में सक्षम होना चाहिए।

ऐसा करने का सबसे अच्छा विकल्प क्या है, और मैं इसे कैसे कार्यान्वित कर सकता हूं? मैं कोको और ऑब्जेक्टिव सी के साथ प्रोग्रामिंग के लिए नया हूं, इसलिए मुझे सच में यकीन नहीं है कि इस भाषा के लिए सबसे अच्छा विकल्प क्या है और स्प्रेइट्स सीजीआरईटीई जानकारी ([mySpriteName बाउंडिंगबॉक्स]) को किसी अन्य वर्ग में कैसे पहुंचाया जाए, फिर परत

इस समय मैं इसे काम करने के लिए सुनिश्चित करने का एकमात्र तरीका प्रत्येक सीसीएसप्रेट स्थिति के लिए डुप्लिकेट सीजीआरईटी बना देता हूं और इसलिए मैं उन्हें जांच सकता हूं, लेकिन मुझे पता है कि यह करने का यह सही तरीका नहीं है।

क्या मैं अब तक (परीक्षण के लिए) है यह है: ControlLayer.m

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
UITouch *touch = [touches anyObject]; 
CGPoint location = [touch locationInView: [touch view]]; 

CGRect rect = CGRectMake(0.0f, 0.0f, 100.0f, 100.0f); 

//Tried some stuff here to get see if I could get a sprite by tagname so I could use it's bounding box but that didn't work 

// Check for touch with specific location 
if (CGRectContainsPoint([tree boundingBox], location)) { 
    CCLOG(@"CGRect contains the location, touched!"); 
} 

CCLOG(@"Layer touched at %@", NSStringFromCGPoint(location)); 

} मेरी मदद के लिए अग्रिम में

धन्यवाद!

उत्तर

27

अपनी समस्या को हल करने के लिए सबसे आसान और सबसे आसान तरीका है, IMO, ccTouchBegan/Moved/Ended का उपयोग कर ccTouchesBegan/Moved/Ended के बजाय कर रहा है। मतलब, आप किसी विशेष पल पर एक स्पर्श को संभालने में कामयाब रहे हैं, इसलिए आप कई स्पर्शों पर भ्रमित होने से बचते हैं, साथ ही ccTouchBegan की सबसे महत्वपूर्ण विशेषता एक सीसीएलएयर स्पर्श को 'उपभोग' कर सकती है और इसे अगली परतों में प्रचार करने से रोक सकती है। नीचे कोड नमूने के बाद अधिक स्पष्टीकरण।

यहां ऐसा करने के लिए कदम हैं। सभी CCLayer उपवर्गों कि स्पर्श इवेंट संभाल चाहिए में तरीकों में से इन सेटों को लागू करें:

पहले, CCTouchDispatcher साथ रजिस्टर:

- (void)registerWithTouchDispatcher { 
    [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES]; 
} 

इसके बाद, ccTouchBegan लागू, नीचे दिए गए उदाहरण मेरे द्वारा बनाए गए एक खेल से है (कुछ हिस्सा निश्चित रूप से छोड़े गए):

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event { 
    if (scene.state != lvlPlaying) { 
     // don't accept touch if not playing 
     return NO; 
    } 
    CGPoint location = [self convertTouchToNodeSpace:touch]; 
    if (scene.mode == modePlaying && !firstTouch) { 
     if (CGRectContainsPoint(snb_putt.sprite.boundingBox, location)) { 
      touchOnPutt = touch.timestamp; 

      // do stuff 

      // return YES to consume the touch 
      return YES; 
     } 
    } 
    // default to not consume touch 
    return NO; 
} 

और अंत में ccTouchMoved और ccTouchEnded लागू ccTouches की तरह * समकक्षों, सिवाय इसके कि वे अंतिम रूप के बजाय एकल स्पर्श संभाल।इन तरीकों से पारित स्पर्श सीसी टचबेगन में खपत वाले किसी भी व्यक्ति तक सीमित है, इसलिए इन दो तरीकों में सत्यापन करने की आवश्यकता नहीं है।

मूल रूप से यह काम करता है। एक स्पर्श घटना सीसीएससीन द्वारा अपने प्रत्येक सीसीलेयर को जेड-ऑर्डरिंग (यानी शीर्ष परत से नीचे परत तक शुरू होती है) के आधार पर एक-एक करके पारित की जाती है, जब तक कि कोई भी परत स्पर्श का उपभोग न करे। तो यदि शीर्ष पर एक परत (उदा। नियंत्रण परत) स्पर्श का उपभोग करती है, तो स्पर्श अगले परत (उदा। ऑब्जेक्ट परत) पर प्रचारित नहीं किया जाएगा। इस तरह प्रत्येक परत को केवल यह तय करने के लिए चिंता करना पड़ता है कि स्पर्श का उपभोग करना है या नहीं। यदि यह निर्णय लेता है कि स्पर्श का उपयोग नहीं किया जा सकता है, तो इसे स्पर्श का उपभोग नहीं करना चाहिए (सीसी टचबेगन से वापस लौटें) और स्पर्श स्वचालित रूप से परतों को फैल जाएगा।

उम्मीद है कि इससे मदद मिलती है।

+0

बहुत बहुत धन्यवाद, आपने मुझे यह पता लगाने में मदद की कि मैंने क्या गलत किया है और अब मैं सकारात्मक रूप से अपनी वस्तुओं पर स्पर्श प्रतिक्रिया प्राप्त कर रहा हूं! –

+0

इस उत्कृष्ट स्पष्टीकरण के लिए धन्यवाद। मुझे बहुत मदद की। इस विषय का सबसे अच्छा जवाब जो मैंने अभी तक पाया है। –

+4

'[सीसीटीएचडी डिस्पैचर साझाडिस्परचर] 'को बहिष्कृत किया गया है। आप इसके बजाय '[[सीसीडी डायरेक्टर डायरेक्टर डायरेक्टर] टच डिस्पैचर] का उपयोग कर सकते हैं। – Hlung

संबंधित मुद्दे