2011-12-13 7 views
5

कोकोस 2 डी में, आप सीसीएसप्रेट्स में आसानी से और सभी प्रकार के तरीकों से उन्हें स्थानांतरित कर सकते हैं। सबसे महत्वपूर्ण बात यह है कि वे आसानी से बाहर/बाहर हो सकते हैं। अधिकांश खेलों में इस निर्बाध आवाजाही आदिसीसीएसप्रेट ऑब्जेक्ट्स की तरह बॉक्स 2 डी निकायों को स्थानांतरित करना

id action = [CCMoveTo actionWithDuration:dur position:pos]; 
move = [CCEaseInOut actionWithAction:action rate:2]; 
[self runAction: move]; 

के लिए वांछनीय है जब एक box2d शरीर चलती, स्प्राइट इसे से जुड़े box2d कदम के बाद अद्यतन किया जाता है()। स्प्राइट को स्थानांतरित करना और फिर शरीर को अद्यतन करना एक विकल्प नहीं है, क्योंकि यह पूरी तरह से भौतिकी ढांचे के उद्देश्य को हरा देता है।

तो दूसरा विकल्प, जिसे मैंने सफलतापूर्वक कार्यान्वित किया है, एक विषाणु के विस्थापन, वेग और त्वरण की गणना करना है ताकि इसे अपने स्वयं के अधिकार में मैकेनिक्स इकाई के रूप में पेश किया जा सके। प्रत्येक बार जब मैं अपने अपडेट() को स्प्राइट पर कॉल करता हूं तो चरित्र तय कर सकता है कि कहां स्थानांतरित करना है, मेरा सुपरक्लास भी पिछली स्थिति और वेग को स्टोर करता है। इन्हें PTM_RATIO द्वारा विभाजित करके box2d अनुरूप मानों के रूप में संग्रहीत किया जाता है।

CCSprite के उपवर्ग में, FMSprite कहा जाता है:

-(CGPoint) displacement { 
    return ccpSub(self.position, lastPos); 
} 

-(b2Vec2) getSpriteVelocity:(ccTime)dt { 
    return b2Vec2(self.displacement.x/dt/PTM_RATIO, 
        self.displacement.y/dt/PTM_RATIO); 
} 

-(b2Vec2) getSpriteAccel:(ccTime)dt { 
    b2Vec2 currVel = [self getSpriteVelocity:dt]; 
    if (dt == 0) { 
     return b2Vec2(0,0); 
    } else {  
     float accelX = (currVel.x - lastVel.x)/dt; 
     float accelY = (currVel.y - lastVel.y)/dt; 
     return b2Vec2(accelX, accelY); 
    } 
} 

// This is called each update() 
-(void) updateLast:(ccTime)dt { 
    // MUST store lastVel before lastPos is updated since it uses displacement 
    lastVel = [self getSpriteVelocity:dt]; 
    lastPos = ccp(self.X, self.Y); 
} 

// Leave this method untouched in subclasses 
-(void) update:(ccTime)dt { 
    [self updateObject:dt]; 

    // Store previous update values 
    [self updateLast:dt]; 
} 

// Override this method in subclasses for custom functionality 
-(void) updateObject:(ccTime)dt { 

} 

मैं तो "FMObject" है, जो एक b2Body आदि दुकानों में "FMSprite" subclassed है

आदेश शरीर को स्थानांतरित करने में , मुझे पहले एक स्प्राइट ले जाना चाहिए और इसके त्वरण को ट्रैक करना होगा, जिसके माध्यम से मैं स्प्राइट की गति का पालन करने के लिए आवश्यक बल (द्रव्यमान का उपयोग कर) प्राप्त कर सकता हूं। चूंकि मैं ऑब्जेक्ट के स्प्राइट (जो शरीर को सिंक्रनाइज़ किया गया है) को स्थानांतरित नहीं कर सकता है, इसलिए मैं एक "बीकन" नामक एक और स्प्राइट बना देता हूं, इसे ऑब्जेक्ट में बच्चे के रूप में जोड़ता हूं, और इसे चारों ओर ले जाता हूं। हमें बस इतना करना है कि मैंने पहले बताए गए बलों का उपयोग करके इस बीकन स्प्राइट के साथ बॉक्स 2 डी बॉडी की स्थिति को सिंक्रनाइज़ करने के लिए एक फ़ंक्शन रखना है।

-(void) followBeaconWithDelta:(ccTime)dt { 
    float forceX = [beacon getSpriteAccel:dt].x * self.mass; 
    float forceY = [beacon getSpriteAccel:dt].y * self.mass; 
    [self addForce:b2Vec2(forceX, forceY)]; 
} 

परिणाम शानदार है, b2body की एक चिकनी सहजता गति से आगे बढ़ जहां कभी आप इसे, करना चाहते हैं अपने स्वयं के बलों में से किसी के साथ प्रयोग करना है, बल्कि एक CCSprite की प्रतिलिपि बनाई जा रही है कि और उसकी गति नकल के बिना। चूंकि यह सभी ताकतों से है, इसलिए यह अन्य बी 2 बॉडी ऑब्जेक्ट्स के साथ टकराने के दौरान झटके और विकृति का कारण नहीं बनता है। अगर किसी के पास ऐसा करने के लिए कोई अन्य तरीका है, तो कृपया एक उत्तर पोस्ट करें। धन्यवाद!

+0

हाय, इस पोस्ट के लिए धन्यवाद। हालांकि मुझे एक बात समझ में नहीं आया है। आपको बीकन स्प्राइट की आवश्यकता क्यों है? यदि एफएमओब्जेक्ट (जो एक सीसीएसप्रेट है) का एक ऑब्जेक्ट कुछ कस्टम एक्शन का उपयोग करके स्थानांतरित किया जा रहा है, तो एफएमओब्जेक्ट में बी 2 बॉडी को पैरेंट स्प्राइट का पालन क्यों न करें। मुझे यकीन नहीं है कि 'शरीर के लिए synchroinized' मतलब क्या है। आपको अलग-अलग बीकन स्प्राइट की आवश्यकता क्यों होती है और इसे चारों ओर ले जाती है? – Aks

+0

मैंने इसे पोस्ट करने के लगभग 3 साल बाद किया है, लेकिन मुझे लगता है कि आप सही हो सकते हैं। मैं एक बीकन स्प्राइट होने का कारण नहीं देख सकता। मुझे लगता है कि सिर्फ एक कार्यान्वयन विस्तार था। आप 'एफएमओब्जेक्ट' को ही प्रतिस्थापित करने में सक्षम होना चाहिए। –

उत्तर

4

मैं जो करता हूं वह आपके से अलग है, लेकिन CCSprite ऑब्जेक्ट्स की तरह Box2d निकायों को भी स्थानांतरित कर सकता है और सीसीएक्शन का भी उपयोग कर सकता है। सबसे महत्वपूर्ण बात यह है कि एक ऑब्जेक्ट बनाना जिसमें सीसीएसप्रेट और बी 2 एबी शामिल है।

@interface RigidBody : CCNode { 
    b2Body *m_Body; 
    CCSprite *m_Sprite; 
} 

और फिर, सेटपॉजिशन विधि को फिर से लिखें।

-(void)setPosition:(CGPoint)position 
{ 
    CGPoint currentPosition = position_; 
    b2Transform transform = self.body->GetTransform(); 
    b2Vec2 p = transform.p; 
    float32 angle = self.body->GetAngle(); 
    p += [CCMethod toMeter:ccpSub(position, currentPosition)]; 
    self.body->SetTransform(p, angle); 
    position_ = position; 
} 

सेटपॉजिशन विधि गणना करता है कि स्थिति कितनी बदलती है, और इसे b2body पर सेट करें।

मुझे उम्मीद है कि मैं आपके प्रश्न को समझ रहा हूं और उत्तर आपके लिए उपयोगी है ...

+0

यह स्थिति के लिए काम करता है लेकिन SetTransform सेनाओं का उपयोग करने के बजाय हर बार शरीर की स्थिति निर्धारित करेगा।इसका मतलब है कि जब दो कठोर बॉडी ऑब्जेक्ट करते हैं तो वे एक-दूसरे को आसानी से उछालने के बजाय एक झटकेदार प्रभाव पैदा करेंगे। एडफोर्स विधि अधिक काम है, लेकिन यह सुनिश्चित करेगा कि भौतिकी चिकनी है। –

+0

हां, लेकिन शरीर का उपयोग स्थिर गति और दृढ़ स्थिति में रखना मुश्किल है। जब मैं अपनी विधि का उपयोग करता हूं तो मुझे कभी भी कोई गलती नहीं होती है, लेकिन मुझे नहीं पता कि दोनों शरीर बी 2_डैनेमिक बॉडी हैं या नहीं। –

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