2015-01-02 12 views
7

Ciao Sto cercando di risolvere questo bug con la forma fisica di spritekit che appare sottosopra.SpriteKit SKPhysicsBody bodyWithTexture è a testa in giù

[SKPhysicsBody bodyWithTexture:monsterTexture size:monsterTexture.size] 

La prima volta che appare il mostro l'orientamento del corpo fisico è corretto. Ma la seconda volta e ogni volta dopo che il mostro appare, il suo corpo fisico è invertito lungo l'asse Y. Guarda l'immagine dove skView.showsPhysics = true; così vengono visualizzate le forme fisiche. Il fatto che funzioni correttamente la prima volta mi fa pensare che forse qualche proprietà di cui non sono a conoscenza è in fase di modifica o qualcosa del genere.

Ho pensato di mettere insieme 2 blocchi fisici nella forma approssimativa dello stivale ma non è l'ideale in quanto ci sono altre forme più complesse che voglio usare bodyWithTexture su cui si verifica lo stesso bug.

Ho anche provato bodyWithTexture:monsterTexture, l'oggetto SKTexture originale invece di bodyWithTexture:monster.texture, la trama dell'oggetto Mostro.

physics body upside down

Ecco il mio codice aggiuntivo mostro. Fammi sapere se hai bisogno di più.

- (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; 
} 

sto caching la consistenza quando i carichi di classe

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

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

Il NSLog recita come segue:

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) 

ho aggiunto i seguenti registri per il commento di LearnCocos2D:

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 

Inoltre, sto riscontrando alcuni problemi imprevisti con le collisioni quando si utilizzano corpi fisici complessi. SKPhysicsBody bodyWithCircleOfRadius sembra funzionare molto meglio e sto considerando di fare in modo che tutti i mostri cerchino le forme della fisica.

+0

controllare se lo sprite o il relativo genitore è ridimensionato a -1 o ruotato – LearnCocos2D

+0

@ LearnCocos2D Sembra corretto. Ho aggiunto 3 NSLogs al metodo sopra e ho aggiunto l'output del registro dei primi 3 mostri sottostanti. –

+2

Ho lo stesso problema, solo quando la scena viene ricaricata. –

risposta

0

La soluzione era di mantenere un forte riferimento all'atlante invece delle trame stesse. Questo ha anche semplificato il mio codice sinusoidamente sto già precaricando tutti i miei atlanti con [SKTextureAtlas preloadTextureAtlases:textureAtlases withCompletionHandler:^{ ... }]; all'inizio della mia scena. Questo sembra usare la stessa quantità di memoria (se non di meno), e non produce più il bug del corpo fisico capovolto. I commenti su questa domanda (should I cache textures in properties in sprite kit?) mi hanno aiutato a scoprirlo mentre stavo rifacendo il mio codice.

// 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

Ciò lo ha risolto fino a xcode 6.2, e ora è stato interrotto di nuovo. – Siriss

1

Penso che sia un bug in Spritekit su iOS8. Il mio sospetto è che il bug si verifichi quando la trama per il corpo fisico viene recuperata dalla cache interna. Potrebbe capitare di sbagliare l'immagine per provare a correggere i sistemi di coordinate da CoreGraphics.

Utilizzare invece BodyWithBodies. Peccato, mi piace molto questa funzione.

+1

sembra che la maggior parte delle nuove funzionalità che sono state rese disponibili con iOS8 siano ancora piuttosto stupefacenti =/ – hamobi

+0

Sì. Ero preoccupato per quello. Non ho trovato alcuna prova su SO o sul web però. Grazie per la risposta. Ho anche riscontrato alcuni problemi con removeFromParent durante la transizione a iOS8. Forse uscirà una patch. –

0

sono stato in grado di risolvere questo problema nel mio codice con la creazione di una matrice SKPhysicsBody nel mio allineamento didMoveToView dalle texture disponibili di cui avevo bisogno. Invece di ricreare SKPhysicsBody quando era necessario cambiare per il mio SKSpriteNode, ero in grado di fare riferimento alla SKPhysicsBody già creata nell'array. Ciò ha impedito che la trama venisse capovolta. Spero che questo approccio possa aiutare gli altri a rimanere fermi su questo.

// 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: Questo è stato lavorare tutto bene fino a quando iOS 9 SDK. Ho scoperto che il mio corpo di sesta e sesta fisica avrebbe funzionato, ma gli altri non sarebbero apparsi. Sono stato in grado di estrarre il file texture.plist dal dispositivo e ho scoperto che le trame da 1 a 5 sono state ruotate (cioè, textureRotated = YES nel plist). Presumo che la rotazione venga utilizzata per ridurre la dimensione complessiva dell'immagine per l'atlante. Sembra che dal momento che le immagini nell'atlante di texture vengono ruotate, questo in qualche modo influisce sulla capacità di generare un corpo fisico dalla trama.

Problemi correlati