SpriteKit SKPhysicsBody bodyWithTexture 是颠倒的 [英] SpriteKit SKPhysicsBody bodyWithTexture is Upside Down

查看:18
本文介绍了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,Monster 对象的纹理.

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:^{ ... }]; 预加载了我的所有图集.这似乎使用了相同数量的内存(如果不是更少的话),并且不再产生倒置的物理体错误.关于这个问题的评论(我应该在精灵的属性中缓存纹理吗?kit?) 在我重构代码时帮助我发现了这一点.

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天全站免登陆