从父级(Sprite Kit)目标 C 中移除节点
Posted
技术标签:
【中文标题】从父级(Sprite Kit)目标 C 中移除节点【英文标题】:Removing Node From Parent (Sprite Kit) Objective C 【发布时间】:2016-04-07 21:45:00 【问题描述】:我正在创建一个节点从右向左移动的横向滚动游戏。问题是当它离开屏幕时它不会自行移除。我可以让它工作的唯一方法是不多次调用我的 bat 节点方法。但我需要多个蝙蝠出现在屏幕上。问题似乎是当我使用 SKAction waitforDuration 或 performSelector afterDelay 多次调用我的 bat 方法时。
蝙蝠法
-(void) addBats
int random = arc4random_uniform(self.size.height/2);
bats = [SKSpriteNode spriteNodeWithImageNamed:@"Bat1.png"];
bats.physicsBody = [SKPhysicsBody bodyWithTexture:bats.texture size:bats.frame.size];
bats.position = CGPointMake(self.size.width * 9, random);
bats.zPosition = 4;
[bats setScale:0.3];
bats.physicsBody.categoryBitMask = enemyCategoryL4;
bats.physicsBody.dynamic = NO;
bats.physicsBody.contactTestBitMask = playerCategoryLevel4;
bats.physicsBody.usesPreciseCollisionDetection = YES;
[L4foregroundNode addChild:bats];
SKAction *up = [SKAction moveByX:-1 y: -40 duration:1];
SKAction *down = [SKAction moveByX:-1 y:40 duration:1];
SKAction *action1 = [SKAction repeatActionForever:[SKAction sequence:@[up, down]]];
SKAction *action2 = [SKAction moveByX:-self.size.width * 10 y:0 duration:40.0];
SKAction *group = [SKAction group:@[action1, action2]];
[bats runAction:group];
-(void) update:(NSTimeInterval) currentTime
if(bats.position.x < -50)
[bats removeFromParent];
[self addBats];
上述方法仅在我每次调用蝙蝠一次时才有效。有没有一种方法可以让我多次调用并在每次离开屏幕时移除球棒?
【问题讨论】:
bats
是否定义为场景的 iVar(SKSpriteNode
类型)(只是检查以获得完整图片)?
是的,它是 SKSpriteNode 的 iVar。你认为这可能是问题吗?
好的,所以你这里的代码很乱:) 你想要的是创建动作序列,或者按照建议使用完成处理程序。当动作完成时,也就是蝙蝠离开屏幕时,您将它们从其父级中移除......
另外,如果老节点不在屏幕上(你看不到它),你怎么知道它实际上没有从场景中移除?
哦,我明白了...如果您使用[SKAction waitForDuration];
在一定延迟后调用addBats
,那么您将失去用户5556671 指出的引用。 (这仍然意味着节点实际上并没有像你说的那样离开屏幕;)因为你可以看到它们)。
【参考方案1】:
这是一个关于如何创建精灵的示例,将其移动直到最终离开屏幕,然后立即将其移除:
#import "GameScene.h"
@interface GameScene()
@property (nonatomic, strong)SKSpriteNode *sprite;
@end
@implementation GameScene
-(void)didMoveToView:(SKView *)view
self.sprite = [SKSpriteNode spriteNodeWithColor:[SKColor purpleColor] size:CGSizeMake(50.0f,50.0f)];
//Place a sprite on right edge of the screen (I assume that your view and a scene have same size)
self.sprite.position = CGPointMake(self.frame.size.width, self.frame.size.height / 2.0f);
SKAction *moveSprite = [SKAction moveTo:CGPointMake(-self.sprite.size.width, self.frame.size.height / 2.0f) duration:5.0f];
SKAction *removeSprite = [SKAction removeFromParent];
SKAction *sequence = [SKAction sequence:@[moveSprite, removeSprite]];
[self addChild:self.sprite];
[self.sprite runAction:sequence withKey:@"moving"];
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
if (self.sprite.parent)
NSLog(@"Sprite has a parent");
else
NSLog(@"Sprite doesn't have a parent");
@end
尝试使用或不使用[SKAction removeFromParent]
的这段代码(查看两种情况下精灵离开屏幕后打印的内容)。
【讨论】:
【参考方案2】:对于您在 addBats 中创建的每个 bat,您可以使用 runAction:completion: 来运行滚动操作,然后在完成块中从父节点中删除节点。问题可能是当您添加多个节点时,您会丢失对要删除的节点的引用。
这段代码应该做你想做的事(未经测试):
SKAction *up = [SKAction moveByX:-1 y:-40 duration:1];
SKAction *down = [SKAction moveByX:-1 y:40 duration:1];
SKAction *action1 = [SKAction repeatActionForever:[SKAction sequence:@[up, down]]];
[bats runAction:action1];
SKAction *scroll = [SKAction moveByX:-self.size.width * 10 y:0 duration:40.0];
[bats runAction:scroll completion:^
[bats removeFromParent];
];
【讨论】:
以上是关于从父级(Sprite Kit)目标 C 中移除节点的主要内容,如果未能解决你的问题,请参考以下文章
如何在Swift中正确地从父节点中删除SKSpriteNode的子类(要从数组中移除,屏幕上的空格......)?
Xcode 如何自动从其父节点中删除 skspritenode