2015-01-02 7 views
7

Hallo Ich versuche, diesen Fehler zu beheben, mit Spritekit Physik Form auf den Kopf gestellt erscheint.SpriteKit SKPhysicsBody bodyWithTexture ist auf den Kopf gestellt

[SKPhysicsBody bodyWithTexture:monsterTexture size:monsterTexture.size] 

Wenn das Monster das erste Mal erscheint, ist die Körperausrichtung des Phsyics korrekt. Aber das zweite Mal und jedes Mal danach erscheint das Monster, dessen Physikkörper entlang der Y-Achse invertiert ist. Siehe Bild wo skView.showsPhysics = true; so die Physik Formen angezeigt werden. Die Tatsache, dass es beim ersten Mal richtig funktioniert, lässt mich denken, dass eine Eigenschaft, die mir nicht bekannt ist, modifiziert wird oder so.

Ich dachte daran, 2 Physikblöcke zusammen in die grobe Form des Bootes zu setzen, aber das ist nicht ideal, da es andere komplexere Formen gibt, die ich mit bodyWithTexture verwenden möchte, die den gleichen Bug haben.

Ich habe auch versucht bodyWithTexture:monsterTexture, das Original SKTexture Objekt statt bodyWithTexture:monster.texture, die Monster-Objekt-Textur.

physics body upside down

Hier ist mein Add Monster-Code. Lass es mich wissen, wenn du mehr brauchst.

- (Monster *)monster:(NSDictionary *)settings 
{ 
    NSDictionary * monsterDefaults = [self monsterDefaults]; 
    NSDictionary * monsterConfig = [self monsterConfig:settings[TYPE]]; 
    SKTexture * monsterTexture  = monsterConfig[TEXTURE] ? monsterConfig[TEXTURE] : monsterDefaults[TEXTURE]; 
    Monster * monster    = [Monster spriteNodeWithTexture:monsterTexture]; 

    // Animation 
    if (monsterConfig[ANIMATION]) { 
     [monster runAction:monsterConfig[ANIMATION]]; 
    } 

    // Moster Stats 
    monster.name = MONSTER_SPRITE; 
    monster.type = settings[TYPE]; 
    monster.points = monsterConfig[POINTS] ? [monsterConfig[POINTS] intValue] : [monsterDefaults[POINTS] intValue]; 
    monster.damage = monsterConfig[DAMAGE] ? [monsterConfig[DAMAGE] intValue] : [monsterDefaults[DAMAGE] intValue]; 
    monster.hp  = monsterConfig[HP]  ? [monsterConfig[HP] intValue] : [monsterDefaults[HP] intValue]; 
    monster.lethal = monsterConfig[LETHAL] ? [monsterConfig[LETHAL] boolValue] : [monsterDefaults[LETHAL] boolValue]; 

    // Monster Physics 
    float physicsResize = monsterConfig[RESIZE] ? [monsterConfig[RESIZE] floatValue] : [monsterDefaults[RESIZE] floatValue]; 
    switch ([monsterConfig[SHAPE] intValue]) { 
     case COMPLEX: 
      NSLog(@"%@", monster.texture); 
      NSLog(@"rotation: %f", monster.zRotation); 
      NSLog(@"x scale: %f", monster.xScale); 
      NSLog(@"y scale: %f", monster.yScale); 
      monster.physicsBody = [SKPhysicsBody bodyWithTexture:monster.texture size:monster.texture.size]; 
      break; 
     case RECTANGLE: 
      monster.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(monster.size.width * physicsResize, monster.size.height * physicsResize)]; 
      break; 
     default: 
      monster.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:(monster.size.height * physicsResize)/2]; 
      break; 
    } 

    monster.physicsBody.dynamic    = false; 
    monster.physicsBody.affectedByGravity = false; 
    monster.physicsBody.categoryBitMask  = monsterCategory; 
    monster.physicsBody.contactTestBitMask = weaponCategory | heroCategory; 
    monster.physicsBody.collisionBitMask = defaultCategory; 

    // Monster Flight Pattern 
    SKAction * flightPattern = [self monsterFlightPattern:monster settings:settings]; 

    // Monster Rotation 
    // Rotation disabled for physics text 
    // [self monsterRotation:monster rotationConfig:monsterConfig[ROTATION]]; 

    // Move & Remove 
    SKAction * remove = [Config removeAction:monster]; 
    [monster runAction:[SKAction sequence:@[flightPattern, remove]]]; 

    return monster; 
} 

Ich Caching der Textur, wenn die Klasse Lasten

@property (nonatomic) SKTexture * monsterBootTexture; 
... 

- (id)initWithFrameSize:(CGSize)frameSize 
{ 
    ... 
    SKTextureAtlas * atlas = [SKTextureAtlas atlasNamed:monsterAtlas]; 
    self.monsterBootTexture = [atlas textureNamed:MONSTER_BOOT]; 
    ... 
} 

Die NSLog lautet wie folgt:

2015-01-02 12:03:20.619 Gadget Blaster[3301:665394] <SKTexture> 'boot.png' (97 x 100) 
2015-01-02 12:03:20.623 Gadget Blaster[3301:665394] <SKTexture> 'boot.png' (97 x 100) 

ich die folgenden Protokolle pro LearnCocos2D Kommentar hinzugefügt haben:

2015-01-03 12:00:06.131 Gadget Blaster[3987:772046] rotation: 0.000000 
2015-01-03 12:00:06.133 Gadget Blaster[3987:772046] x scale: 1.000000 
2015-01-03 12:00:06.134 Gadget Blaster[3987:772046] y scale: 1.000000 
2015-01-03 12:00:08.131 Gadget Blaster[3987:772046] rotation: 0.000000 
2015-01-03 12:00:08.131 Gadget Blaster[3987:772046] x scale: 1.000000 
2015-01-03 12:00:08.132 Gadget Blaster[3987:772046] y scale: 1.000000 
2015-01-03 12:00:10.156 Gadget Blaster[3987:772046] rotation: 0.000000 
2015-01-03 12:00:10.156 Gadget Blaster[3987:772046] x scale: 1.000000 
2015-01-03 12:00:10.159 Gadget Blaster[3987:772046] y scale: 1.000000 

Außerdem treten bei der Verwendung komplexer physikalischer Körper unerwartete Probleme mit Kollisionen auf. SKPhysicsBody bodyWithCircleOfRadius scheint viel besser zu sein und ich denke darüber nach, alle Monster dazu zu bringen, physikalische Formen zu kreisen.

+0

Überprüfen Sie, ob das Sprite oder sein Elternteil entweder auf -1 oder – LearnCocos2D

+0

skaliert ist. @ LearnCocos2D Sieht korrekt aus. Ich habe der obigen Methode 3 NSLogs hinzugefügt und die logarithmische Ausgabe der ersten 3 Monster hinzugefügt. –

+2

Ich habe das gleiche Problem, nur wenn die Szene neu geladen wird. –

Antwort

0

Die Lösung bestand darin, eine starke Bezugnahme auf den Atlas anstelle der Texturen selbst zu halten. Dies vereinfacht auch meinen Code sine Ich habe bereits alle meine Atlanten mit [SKTextureAtlas preloadTextureAtlases:textureAtlases withCompletionHandler:^{ ... }]; am Anfang meiner Szene geladen. Dies scheint die gleiche Menge an Speicher zu verwenden (wenn nicht weniger), und es erzeugt nicht mehr den auf den Kopf gestellten Physikkörper-Bug. Die Kommentare zu dieser Frage (should I cache textures in properties in sprite kit?) haben mir geholfen, dies zu entdecken, als ich meinen Code überarbeitet habe.

// In Game Scene 

@property (nonatomic, strong) SKTextureAtlas * monsterAtlas; 

... 

- (id)initWithSize:(CGSize)size 
{ 
     self.monsterAtlas = [SKTextureAtlas atlasNamed:monsterAtlasName]; 
     NSArray * textureAtlases = @[self.monsterAtlas]; 
     [SKTextureAtlas preloadTextureAtlases:textureAtlases withCompletionHandler:^{ ... }]; 
} 

// In Monster Class 

- (Monster *)monster:(NSDictionary *)settings 
{ 
     ... 

     SKTextureAtlas * atlas = [SKTextureAtlas atlasNamed:monsterAtlasName]; 
     NSString * textureName = monsterConfig[TEXTURE] ? monsterConfig[TEXTURE] : monsterDefaults[TEXTURE]; 
     Monster * monster  = [Monster spriteNodeWithTexture:[atlas textureNamed:textureName]]; 

     ... 
} 
+1

Dies hat es bis xcode 6.2 behoben, und jetzt ist es wieder gebrochen. – Siriss

1

Ich denke, es ist ein Fehler in Spritekit auf iOS8. Mein Verdacht ist, dass der Fehler auftritt, wenn die Textur für den Physikkörper aus dem internen Cache abgerufen wird. Es könnte sein, dass das Bild falsch umgedreht wird, um zu versuchen, Koordinatensysteme von CoreGraphics zu korrigieren.

Verwenden Sie stattdessen bodyWithBodies. Bummer, ich mag diese Funktion wirklich.

+1

scheint wie die meisten der neuen Funktionen, die mit iOS8 kam, sind ziemlich wackelig immer noch =/ – hamobi

+0

Ja. Ich war besorgt darüber. Konnte jedoch keine Beweise über SO oder das Internet finden. Danke für die Antwort. Ich stieß auch auf einige Probleme mit RemoveFromParent beim Übergang zu iOS8. Vielleicht wird ein Patch herauskommen. –

0

Ich war in der Lage, dieses Problem in meinem Code zu lösen, indem ein SKPhysicsBody Array in meinem didMoveToView Array aus den verfügbaren Texturen zu schaffen ich brauchte. Anstatt den SKPhysicsBody neu zu erstellen, als er für meinen gegebenen SKSpriteNode geändert werden musste, konnte ich den bereits erstellten SKPhysicsBody im Array referenzieren. Dadurch konnte die Textur nicht umgedreht werden. Ich hoffe, dieser Ansatz kann anderen helfen, auf diesem einen Punkt festzuhalten.

// variable declared in SKScene 
var myPhysicsBodies: [SKPhysicsBody]() 

// put in didMoveToView 
for var i = 0; i <= 6; i++ {   
    self.myPhysicsBodies.append(SKPhysicsBody(texture: self.myTextureFrames[i], size: self.myObject.size)) 
} 

// used when changing physicsBody 
self.myObject.physicsBody = self.myPhysicsBodies[self.frameIndex] 

UPDATE: Das war alles gut funktioniert und gut, bis iOS 9 SDK. Ich fand heraus, dass meine Physikstellen der 0. und 6. Physik funktionieren würden, aber die anderen würden nicht erscheinen. Ich konnte die texture.plist vom Gerät extrahieren und fand heraus, dass die Texturen 1 bis 5 rotiert wurden (dh textureRotated = YES im plist). Ich nehme an, die Rotation wird verwendet, um die Gesamtbildgröße für den Atlas zu verringern. Es scheint, dass, da die Bilder in dem Texturatlas gedreht werden, dies irgendwie die Fähigkeit beeinflusst, einen Physikkörper aus der Textur zu erzeugen.

Verwandte Themen