2013-10-10 9 views
8

स्प्राइटकिट का उपयोग कर मेरे वर्तमान प्रोजेक्ट में, मेरे पास स्प्राइट्स का एक गुच्छा है जिसे विभिन्न समय पर स्वतंत्र रूप से ऊपर और नीचे स्केल किया जाना चाहिए। समस्या यह है कि जब मैं नोड को स्केल करता हूं, भौतिकी शरीर इसके साथ स्केल नहीं करता है, इसलिए यह भौतिकी को खराब करता है।SKPhysicsBody और [SKNode setScale:]

CGSize objectSize = CGSizeMake(100, 100); 
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:CGRectMake(0, 0, self.size.width, self.size.height)]; 

SKSpriteNode *n1 = [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:objectSize]; 
n1.position = CGPointMake(self.size.width/2, 2*self.size.height/3); 
n1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:objectSize]; 
n1.physicsBody.affectedByGravity = YES; 
[self addChild:n1]; 

SKSpriteNode *n2 = [SKSpriteNode spriteNodeWithColor:[UIColor redColor] size:objectSize]; 
n2.position = CGPointMake(self.size.width/2, self.size.height/3); 
n2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:objectSize]; 
n2.physicsBody.affectedByGravity = YES; 
[self addChild:n2]; 

[n1 setScale:0.5]; 

enter image description here

सूचना कैसे नीले स्प्राइट (छोटा) लाल एक के शीर्ष पर बैठता है, लेकिन आप अपने भौतिक विज्ञान शरीर अभी भी बता सकते हैं: यहाँ एक छोटा सा उदाहरण मैं इस सवाल के उद्देश्य के लिए एक साथ रखा है आयाम मैंने इसे बताया है, और यह पैमाने पर नहीं था।

तो जाहिर है, नोड को स्केलिंग भौतिकी को स्केल नहीं करता है। तो मेरा सवाल यह है कि अगर मुझे इसे मैन्युअल रूप से करना है, तो मैं इसके बारे में कैसे जा सकता हूं?

मैंने स्केलिंग के दौरान शरीर को सही आकार में से एक के साथ स्वैप करने का प्रयास किया, लेकिन फिर पुराने शरीर के जोड़ों के साथ चीजें वास्तव में गड़बड़ हो गईं ... यह बहुत आसान होगा अगर मैं मौजूदा निकाय को स्केल कर सकूं किसी न किसी तरह।

+1

बॉक्स 2 डी (एसके द्वारा उपयोग किए गए) में शरीर के आकार की कोई स्केलिंग नहीं है – LearnCocos2D

उत्तर

3

मुझे एक ही समस्या थी, मुझे लगता है कि यह स्प्राइट किट में एक बग है।

स्केल करने के लिए एक क्रिया का उपयोग करने का प्रयास करें, यह पूरे दृश्य पर काम करता है।

[self runAction:[SKAction scaleTo:0.5 duration:0]]; 

मेरी मूल question

यह आप क्या होने

- (void) anthoertest 
{ 
    CGSize objectSize = CGSizeMake(100, 100); 
    self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:CGRectMake(0, 0, self.size.width, self.size.height)]; 

    SKSpriteNode *n1 = [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:objectSize]; 
    n1.position = CGPointMake(self.size.width/2, 2*self.size.height/3); 
    n1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:n1.size]; 
    n1.physicsBody.affectedByGravity = YES; 
    [self addChild:n1]; 

    SKSpriteNode *n2 = [SKSpriteNode spriteNodeWithColor:[UIColor redColor] size:objectSize]; 
    n2.position = CGPointMake(self.size.width/2, self.size.height/3); 
    n2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:n2.size]; 
    n2.physicsBody.affectedByGravity = YES; 
    [self addChild:n2]; 

    [self shrinkMe:n1]; 
} 

- (void) shrinkMe:(SKSpriteNode *) s 
{ 
    [s setScale:0.5]; 
    s.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:s.size]; 
} 

enter image description here

+0

मैं वास्तव में भी आपके धागे को पढ़ता हूं। यह काम करता है अगर मैं पूरे दृश्य को इस तरह से स्केल करता हूं, लेकिन यदि आप स्प्राइट पर एक ही कार्रवाई चलाते हैं, तो यह वही छोटी गाड़ी परिणाम उत्पन्न करता है। मैं स्वतंत्र रूप से उन नोड्स को स्केल करने की कोशिश कर रहा हूं, यह मुझे पागल कर रहा है। – mprivat

+0

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

+0

मैं आपकी टिप्पणी से सहमत हूं, एक एसके फिक्स – DogCoffee

5

भौतिकी शरीर आकार छोटा नहीं किया जा सकता चाहते हैं। निश्चित रूप से Box2D में नहीं जो स्प्राइट किट आंतरिक रूप से उपयोग करता है।

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

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

हालांकि आपको इसके आकार के अनुसार शरीर की घनत्व और शायद अन्य गुणों की गणना करना होगा।

+0

अच्छा विचार, लेकिन दुर्भाग्यवश मेरे उपयोग के मामले के लिए लागू नहीं है: मेरे पास एक गेंद है (एक शरीर के साथ SKShapeNode) कि, जब किसी अन्य वस्तु को मारते हैं, तो दूसरी दिशा में बंद हो जाता है और छोटा हो जाता है। अगर मैं बस शरीर को निष्क्रिय करता हूं और दूसरा बनाता हूं, तो गेंद इसकी वेग और अन्य गुणों को खो देगी। आप लिखते हैं: > दिए गए आकारों के निकायों के साथ अतिरिक्त SKNode जोड़ें AFAIK एक एकल SKNode में एकाधिक निकायों को जोड़ना संभव नहीं है, है ना? – cocoapriest

+0

मुझे लगता है कि उनका मतलब है कि आप अपने एसपीएनओड्स को अपने स्प्राइट नोड में बच्चों के रूप में जोड़ सकते हैं, और प्रत्येक बच्चे के नोड्स का अपना भौतिकी शरीर होगा। शरीर को सक्षम/अक्षम करने का एक तरीका यह है कि वे अपने टकराव बिटमैस्क को बदल दें। – peacetype

1

भौतिकी शरीर SKNode के CGPath पर निर्भर करता है; आपको किसी भी तरह इसे बदलने की आवश्यकता होगी। आप निम्न की तरह कुछ के साथ CGPath स्केलिंग की कोशिश कर सकते:

//scale up 

CGFloat scaleFactor = 1.1; 
CGAffineTransform scaleTransform = CGAffineTransformIdentity; 
scaleTransform = CGAffineTransformScale(scaleTransform, scaleFactor, scaleFactor); 
CGPathRef scaledPathRef = CGPathCreateCopyByTransformingPath(exampleNode.path, &scaleTransform); 
exampleNode.path = scaledPathRef; 

लेकिन ध्यान रखें कि यह एक SKScene में पहले से ही नोड्स की उपस्थिति अपडेट नहीं होगा। आपको सीजीपैथ को एसकेएक्शन के साथ आकार देने की आवश्यकता हो सकती है जो नोड को स्केल करता है।

+0

लेकिन आप भौतिकी बॉडी वर्तमान पथ तक नहीं पहुंच सकते हैं। – Martin

+0

शरीर पर निर्भर करता है कि इस पर निर्भर करता है कि आपने इसे कैसे बनाया है, जरूरी नहीं है (सीधे)/एक CGPath - और यह उस समय (या अन्य ज्यामिति) पर निर्भर करता है जब यह बनाया गया हो। – bshirley

7

या तो SKAction या अद्यतन पाश का उपयोग करके, आप उचित पैमाने के साथ एक नया SKPhysicsBody बना सकते हैं और इसे ऑब्जेक्ट पर लागू कर सकते हैं। हालांकि, ऐसा करके, आप वेग खो देंगे।इसे ठीक करने के लिए, आप निम्न कर सकते हैं:

SKPhysicsBody *newBody = [SKPhysicsBody bodyWithRectangleOfSize:boxObject.size]; 
newBody.velocity = boxObject.physicsBody.velocity; 

boxObject.physicsBody = newBody; 
+0

यह पर्याप्त नहीं है, अन्य पैरामीटर जैसे कोणीय वेग और अन्य सीधे उपलब्ध नहीं हैं, इसलिए आप एक ही भौतिक विज्ञान के लिए समान गुणों का प्रचार नहीं कर सकते हैं। –

2

किसी और को इस जवाब को पढ़ने के लिए, मुझे विश्वास है कि अब भौतिकी निकायों SKNode साथ पैमाने पर। मैं एक्सकोड 8.2.1 और स्विफ्ट 3.0.2 का उपयोग कर रहा हूँ। मैं एक नई परियोजना शुरू करता हूं, गेम का चयन करता हूं, विवरण भरता हूं। 2 फ़ाइलें परिवर्तित करें:

GameViewController.swift (एक पंक्ति जोड़ें)

खेल Scene.swift इस के साथ समारोह (sceneDidLoad() डालें):

override func sceneDidLoad() { 

    var found = false 
    self.enumerateChildNodes(withName: "testSprite") { 
     node, stop in 
      found = true 
    } 
    if !found { 
     let testSprite = SKSpriteNode(color: UIColor.white, size: CGSize(width: 200.0, height: 200.0)) 
     testSprite.physicsBody = SKPhysicsBody(polygonFrom: CGPath(rect: CGRect(x: -100.0, y: -100.0, width: 200.0, height: 200.0), transform: nil)) 
     testSprite.physicsBody?.affectedByGravity = false 
     testSprite.name = "testSprite" 
     let scaleAction = SKAction.repeatForever(SKAction.sequence([ 
      SKAction.scale(to: 2.0, duration: 2.0), 
      SKAction.scale(to: 0.5, duration: 2.0) 
      ])) 
     testSprite.run(scaleAction) 
     self.addChild(testSprite) 
    } 

} 

भौतिकी सीमा स्केलिंग है स्प्राइट नोड के साथ।

+2

मैंने यह भी देखा है: http://stackoverflow.com/a/33572073/3402095 – Whirlwind

+0

@Wirlwind की इच्छा है कि मैंने इस से पहले अपनी पोस्ट देखी थी –

0

मुझे यह वही समस्या थी, मैंने जो कुछ किया वह मेरे भौतिकी निकाय को मेरे अपडेट वर्तमान समय समारोह में परिभाषित किया गया था और यह इसके साथ स्केल करेगा।

कुछ इस तरह आप के लिए यह होगा:

override func sceneDidLoad() { 

SKSpriteNode *n1 = [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:objectSize]; 
n1.position = CGPointMake(self.size.width/2, 2*self.size.height/3); 

} 
override func update(_ currentTime: TimeInterval) { 

n1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:objectSize]; 
n1.physicsBody.affectedByGravity = YES; 

} 

समस्या सिर्फ आप अपने भौतिक विज्ञान गुण updateCurrentTime में हर बार फिर से परिभाषित करने के लिए है कि है। आप इनमें से कुछ गुणों को बना सकते हैं जैसे कि इसके पुनर्वितरण एक चर के बराबर है ताकि आप कहीं और परिवर्तनीय रूप से बदलकर अपनी गुणों को बदल सकें। इसे कहीं भी फिर से परिभाषित करना केवल तभी काम करता है जब तक कि अगले फ्रेम को बुलाया न जाए।

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