SpriteKit SKPhysicsBody bodyWithTexture是颠倒的

您好我正试图解决这个问题与spritekit的物理形状出现颠倒。

[SKPhysicsBody bodyWithTexture:monsterTexture size:monsterTexture.size] 

怪物第一次出现时,身体的取向是正确的。 但是第二次和每一次之后,怪物出现了,它的物理体是沿着Y轴倒置的。 看图片在哪里skView.showsPhysics = true; 所以显示物理形状。 事实上,第一次正确的工作使我想,也许一些财产,我不知道正在修改或什么的。

我想把两个物理块放在引导的粗糙形状中,但这并不理想,因为还有一些其他更复杂的形状,我想使用bodyWithTexture就是遇到同样的错误。

我也尝试了bodyWithTexture:monsterTexture ,原来的SKTexture对象,而不是bodyWithTexture:monster.texture ,怪物对象的纹理。

物理机构颠倒了

这是我的添加怪物代码。 让我知道你是否需要更多。

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

我在caching类加载时的纹理

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

NSLog的内容如下:

 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) 

我为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 

另外,在使用复杂的物理体时,我遇到了碰撞时的一些意想不到的问题。 SKPhysicsBody bodyWithCircleOfRadius似乎performance好得多,我正在考虑让所有的怪物圈出物理形状。

我认为这是iOS8上的Spritekit中的一个bug。 我怀疑是从内部caching中检索到物理体的纹理时发生的错误。 这可能是不正确的翻转图像,以尝试纠正从CoreGraphics坐标系统。

改用bodyWithBodies。 无赖,我真的很喜欢这个function。

解决的办法是强调地图集而不是地图本身。 这也简化了我的代码正弦我已经预载所有我的地图集[SKTextureAtlas preloadTextureAtlases:textureAtlases withCompletionHandler:^{ ... }]; 在我的场景开始。 这似乎使用相同数量的内存(如果不是更less),并且不会产生颠倒的物理机体错误。 关于这个问题的评论( 我应该在sprite工具包中的属性caching纹理? )帮助我发现这一点,因为我重构我的代码。

  // 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]]; ... } 

我能在我的代码中解决这个问题,通过在我需要的可用纹理的didMoveToView数组中创build一个SKPhysicsBody数组。 当我需要改变给定的SKSpriteNode时,我没有重新创buildSKPhysicsBody,而是能够引用已经创build的SKPhysicsBody。 这保持了翻转的质地。 希望这种方法可以帮助别人卡在这一个。

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

更新:这是工作得很好,直到iOS 9 SDK。 我发现我的第0和第6个物理机构会工作,但其他的不会出现。 我能够从设备中提取texture.plist,并发现纹理1到纹理5被旋转(即,纹理旋转=是在plist中)。 我假设旋转用于减less图集的整体图像大小。 看起来,由于纹理图集中的图像正在被旋转,这不知何故地影响了从纹理生成物理体的能力。