SKSpriteNode 失去了它的物理体属性
Posted
技术标签:
【中文标题】SKSpriteNode 失去了它的物理体属性【英文标题】:SKSpriteNode loses its physicsBody properties 【发布时间】:2014-03-22 21:54:13 【问题描述】:我正在使用 SpriteKit 创建一个游戏,其中地图底部的对象会移动。 对象是鳄鱼和硬币。
场景使用一个 NSTimer 来调用这个选择器:
timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(generateBottomSprite) userInfo:nil repeats:YES];
-(void) generateBottomSprite
int random = (arc4random() % difficulty+3) + difficulty-3;
if (counter >random)
SKSpriteNode *bottomSprite;
if (random>difficulty)
bottomSprite = [SKSpriteNode spriteNodeWithImageNamed:@"crocodile"];
bottomSprite.size = CGSizeMake(70, 120);
bottomSprite.physicsBody.categoryBitMask = crocMask;
else
bottomSprite = [SKSpriteNode spriteNodeWithImageNamed:@"coin"];
bottomSprite.size = CGSizeMake(50, 50);
bottomSprite.physicsBody.categoryBitMask = coinMask;
//create a crocodile
bottomSprite.position = CGPointMake(self.frame.size.width,bottomSprite.frame.size.height/2);
bottomSprite.name = @"bottomSprite";
[self addChild: bottomSprite];
counter = 0;
[self enumerateChildNodesWithName:@"bottomSprite" usingBlock: ^(SKNode *node, BOOL *stop)
node.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:node.frame.size];
node.physicsBody.affectedByGravity = NO;
node.physicsBody.mass = 8000.0;
node.physicsBody.friction = 2.50;
node.physicsBody.usesPreciseCollisionDetection = YES;
];
问题:physicsWorld 的所有属性在每次调用选择器时都会重新初始化,我必须遍历场景的子节点才能重新分配它们。
为什么要重新初始化属性?
【问题讨论】:
我是否正确假设底部的子节点枚举是您想要避免做的事情? 是的,正是问题所在。 不确定是否相关,但我再说一遍:不要在 Sprite Kit 应用中使用 NSTimer。使用 SKScene 的 update:/didSimulatePhysics 方法来执行重复的任务,或者使用与 waitForDuration 配对的 SKAction runBlock。问题:在 Sprite Kit 更新循环期间,NSTimer 可能随时触发。 NSTimer 甚至会在节点/场景暂停或转换时触发。 感谢您的建议,但这也不能解决问题 【参考方案1】:您在创建 skphysicsbody 之前设置了 categorybitmask
bottomSprite = [SKSpriteNode spriteNodeWithImageNamed:@"crocodile"];
bottomSprite.size = CGSizeMake(70, 120);
//add the following
bottomSprite.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bottomSprite.frame.size];
///////////////
bottomSprite.physicsBody.categoryBitMask = crocMask;
像这样将所有物理设置移到枚举之外
if (counter >random)
SKSpriteNode *bottomSprite;
int currentBitMask;
if (random>difficulty)
bottomSprite = [SKSpriteNode spriteNodeWithImageNamed:@"crocodile"];
bottomSprite.size = CGSizeMake(70, 120);
currentBitMask = crocMask;
else
bottomSprite = [SKSpriteNode spriteNodeWithImageNamed:@"coin"];
bottomSprite.size = CGSizeMake(50, 50);
currentBitMask = coinMask;
**bottomSprite.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bottomSprite.frame.size];**
bottomSprite.physicsBody.categoryBitMask = currentBitMask ;
bottomSprite.physicsBody.affectedByGravity = NO;
bottomSprite.physicsBody.mass = 8000.0;//way too high
bottomSprite.physicsBody.friction = 2.50;//probably high
bottomSprite.physicsBody.usesPreciseCollisionDetection = YES;//overkill, set only if critical
//create a crocodile
bottomSprite.position = CGPointMake(self.frame.size.width,bottomSprite.frame.size.height/2);
bottomSprite.name = @"bottomSprite";
[self addChild: bottomSprite];
您可能还想使用 skscene 和 nstimeintervals 中的 update 方法来测量时间,直到您经过半秒然后调用 generateBottomSprite 方法,它应该比使用额外的 NSTimer 更有效。
如果有什么不清楚的地方欢迎提问,希望对你有帮助。
【讨论】:
以上是关于SKSpriteNode 失去了它的物理体属性的主要内容,如果未能解决你的问题,请参考以下文章