SpriteKit SKPhysicsBody bodyWithTexture颠倒了 [英] SpriteKit SKPhysicsBody bodyWithTexture is Upside Down

查看:120
本文介绍了SpriteKit SKPhysicsBody bodyWithTexture颠倒了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好我正在尝试修复这个错误,spritekit的物理形状上下颠倒。

Hi I'm trying to fix this bug with spritekit's physics shape appearing upside down.

[SKPhysicsBody bodyWithTexture:monsterTexture size:monsterTexture.size]

怪物第一次出现时,身体方向是正确的。但是第二次和每次之后怪物出现它的物理体沿着Y轴反转。请参见图片 skView.showsPhysics = true; ,以便显示物理形状。它第一次正常工作的事实让我觉得可能有一些我不知道的属性正在修改或者其他什么。

The first time the monster appears the phsyics body orientation is correct. But the second time and every time after that the monster appears it's physics body is inverted along the Y axis. See picture where skView.showsPhysics = true; so the physics shapes are displayed. The fact that it works correctly the first time makes me think maybe some property I'm not aware of is being modified or something.

我想把2个物理块放在靴子的粗糙形状中,但这并不理想,因为还有一些其他更复杂的形状,我想使用bodyWithTexture正在经历同样的错误。

I thought of putting 2 physics blocks together in the rough shape of the boot but that is not ideal as there are some other more complex shapes I want to use bodyWithTexture on that are experiencing the same bug.

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

I have also tried bodyWithTexture:monsterTexture, the original SKTexture object instead of bodyWithTexture:monster.texture, the Monster object's texture.

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

Here is my add monster code. Let me know if you need more.

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

我在课程加载时缓存纹理

I am caching the texture when the class loads

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

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

NSLog的内容如下:

The NSLog reads as follows:

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的评论添加了以下日志:

I have added the following logs per LearnCocos2D's comment:

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 似乎表现得更好,我正在考虑让所有怪物圈出物理形状。

Additionally I'm experiencing some unexpected issues with collisions when using complex physics bodies. SKPhysicsBody bodyWithCircleOfRadius seems to perform much better and I'm considering just making all monsters circle physics shapes.

推荐答案

解决方案是强烈引用地图集而不是纹理本身。这也简化了我的代码正弦我已经在我的场景开头用 [SKTextureAtlas preloadTextureAtlases:textureAtlases withCompletionHandler:^ {...}]; 预加载我的所有地图集。这似乎使用相同数量的内存(如果不是更少),并且它不再产生颠倒的物理主体错误。关于这个问题的评论(我应该在精灵中的属性中缓存纹理套件?)帮助我发现这一点,因为我正在重构我的代码。

The solution was to hold a strong reference to the atlas instead of the textures themselves. This also simplified my code sine I'm already preloading all my atlases with [SKTextureAtlas preloadTextureAtlases:textureAtlases withCompletionHandler:^{ ... }]; at the beginning of my scene. This seems to use the same amount of memory (if not less), and it does not produce the upside-down physics body bug anymore. The comments on this question (should I cache textures in properties in sprite kit?) helped me discover this as I was refactoring my code.

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

      ...
 }

这篇关于SpriteKit SKPhysicsBody bodyWithTexture颠倒了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆