首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SpriteKit SKPhysicsBody bodyWithTexture倒挂

SpriteKit SKPhysicsBody bodyWithTexture倒挂
EN

Stack Overflow用户
提问于 2015-01-02 20:17:34
回答 3查看 1.4K关注 0票数 8

嗨,我试着用spritekit的物理形状来修复这个错误。

代码语言:javascript
复制
[SKPhysicsBody bodyWithTexture:monsterTexture size:monsterTexture.size]

当怪物第一次出现时,phsyics的身体定位是正确的。但是第二次和以后每一次怪物出现的时候,它的物理体是沿着Y轴倒转的。请参见skView.showsPhysics = true;显示物理形状的图片。它第一次正确工作的事实让我想,也许是一些我不知道的属性被修改了什么的。

我想把两个物理块放在一起,在引导的粗糙形状,但这并不理想,因为还有一些更复杂的形状,我想使用bodyWithTexture,正在经历同样的错误。

我也尝试过bodyWithTexture:monsterTexture,它是原始的SKTexture对象,而不是怪物对象的纹理bodyWithTexture:monster.texture

这是我添加的怪物代码。如果你需要更多的话请告诉我。

代码语言:javascript
复制
- (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;
}

当类加载时,我正在缓存纹理。

代码语言:javascript
复制
@property (nonatomic) SKTexture * monsterBootTexture;
...

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

NSLog的内容如下:

代码语言:javascript
复制
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的评论中添加了以下日志:

代码语言:javascript
复制
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的表现似乎要好得多,我正在考虑让所有的怪物都绕着物理形状转。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-01-23 03:58:18

解决办法是保持强烈的参考图集,而不是纹理本身。这也简化了我的代码,在我的场景开始时,我已经用[SKTextureAtlas preloadTextureAtlases:textureAtlases withCompletionHandler:^{ ... }];预装了我所有的地图集。这似乎使用了同样数量的内存(如果不是少的话),并且它不再产生颠倒的物理身体错误。关于这个问题的评论(should I cache textures in properties in sprite kit?)帮助我在重构代码时发现了这一点。

代码语言:javascript
复制
 // 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]];

      ...
 }
票数 0
EN

Stack Overflow用户

发布于 2015-01-09 17:43:55

我认为这是iOS8上Spritekit中的一个bug。我怀疑,当从内部缓存中检索到物理体的纹理时,就会发生错误。它可能是不正确的翻转图像,试图纠正协调系统从CoreGraphics。

使用bodyWithBodies代替。很遗憾,我真的很喜欢这个功能。

票数 1
EN

Stack Overflow用户

发布于 2015-05-30 22:28:20

我能够在代码中通过从我需要的可用纹理在我的SKPhysicsBody数组中创建一个didMoveToView数组来解决这个问题。没有在需要对给定的SKPhysicsBody进行更改时重新创建SKSpriteNode,而是能够在数组中引用已经创建的SKPhysicsBody。这防止了纹理被倒转。希望这种方法能帮助其他人坚持这一条。

代码语言:javascript
复制
// 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被旋转(即,textureRotated = YES )。我假设旋转是用来缩小地图集的整体图像大小。看来,由于纹理地图集中的图像正在旋转,这在某种程度上影响了从纹理生成物理体的能力。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27748034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档