Sprite Kit,使多个精灵遵循相同的方法

Posted

技术标签:

【中文标题】Sprite Kit,使多个精灵遵循相同的方法【英文标题】:Sprite Kit, make multiple sprites obey same method 【发布时间】:2014-02-23 19:17:36 【问题描述】:

如果有一个玩家和 12 个“敌人”,我正在为 iPhone 开发一款精灵套件游戏。这些敌人中的每一个都是以相同的方式创建的。我在 initWithSize 方法中使用 for 循环来做到这一点。

for (int i = 1; i <= 12; i++)
    
        [self spawnChargesWithNumber:i];
    

实际生成敌人的方法(spawnChargesWithNumber)如下。

- (void)spawnChargesWithNumber:(NSInteger)number


self.chargedBall = [[ChargedBall alloc] initWithImageNamed:[NSString stringWithFormat:@"ChargedBall%li", (long)number]];
int minX = self.chargedBall.size.width / 2;
int maxX = self.frame.size.width - self.chargedBall.size.width/2;
int rangeX = maxX - minX;
int actualX = (arc4random() % rangeX) + minX;

self.chargedBall.position = CGPointMake(actualX, 568);
self.chargedBall.name = [NSString stringWithFormat:@"chargeNumber%li", (long)number];
self.chargedBall.zPosition = 15;
self.chargedBall.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:13.0f];
self.chargedBall.physicsBody.dynamic = YES;
self.chargedBall.physicsBody.affectedByGravity = NO;
self.chargedBall.physicsBody.mass = 0.1;
[self.map addChild:self.chargedBall];

这确实创建了 12 个不同的敌人,但只有最后一个实际上是chargedBall 对象。我有一个名为 ChargedBall 的对象,其中有一个 .h 和 .m 文件。在 .m 文件中,我有一个方法可以更新对象的位置。

在 update:currentTime 方法中,我调用此方法来更新球的位置,并在此方法中检查与 tileMap 的碰撞。

-(void)update:(CFTimeInterval)currentTime


NSTimeInterval delta = currentTime - self.previousUpdateTime;

if (delta > 0.02)

    delta = 0.02;


self.previousUpdateTime = currentTime;
[self.player update:delta];
[self.chargedBall update:delta];
[self checkForAndResolveCollisionsForPlayer:self.player forLayer:self.walls];
[self checkForAndResolveCollisionsForCharge:self.chargedBall forLayer:self.walls];
[self processUserMotionForUpdate:currentTime];
[self setViewPointCenter:self.player.position];

如果我只有一个敌人/chargedBall,这会非常有效。如果我有多个chargedBalls,那么只有最后一个会按应有的方式运行。其他人只是停留在屏幕上。我认为这与我制作chargedBall 的方式有关。我每次都重新创建chargedBall 对象,因此只有最后一个实际上是chargedBall,而不是其他对象,因为我覆盖了它们。所以我的最终问题是,我怎样才能让所有敌人/chargedBall 对象的行为方式相同并遵循相同的方法来更新自己?非常感谢您的任何帮助

【问题讨论】:

【参考方案1】:

将所有ChargedBall 对象存储在一个数组中。声明一个属性:

@property (nonatomic, strong) NSMutableArray *enemies.

每次创建敌人时,将其添加到 enemies 数组中。

- (void)spawnChargesWithNumber:(NSInteger)number

    ChargedBall *enemy = [[ChargedBall alloc] ...];

    // Your code ...

    if (!_enemies)
    
        _enemies = [[NSMutableArray alloc] init];
    

    [_enemies addObject:enemy];

然后对数组中的每个ChargedBallupdate 方法更新它:

for(ChargedBall *enemy in self.enemies)

    [self checkForAndResolveCollisionsForCharge:enemy forLayer:self.walls];

旁注:

这不适用于这个问题,但很高兴知道。 如果你想调用每个敌人的方法,你可以使用NSArraymakeObjectsPerformSelector: 方法在一行中完成。示例:

[_enemies makeObjectsPerformSelector:@selector(selfDestruct)];

【讨论】:

非常感谢。这就像一个魅力!而且,我真的很喜欢使用 makeObjectsPerformSelector 的 selfDestruct 方法:NSArray 的方法!再次感谢您的时间和帮助。【参考方案2】:

您已经为您的chargedBall 定义了一个属性,但是您需要一个可变数组。定义一个属性来容纳所有的球。像这样的:

@property (nonatomic, strong) NSMutableArray *chargedBalls.

然后将你的 for 循环更改为这个(确保你已经在某处初始化了数组):

- (void)spawnChargesWithNumber:(NSInteger)number


   ChargedBall *chargedBall = [[ChargedBall alloc] initWithImageNamed:[NSString stringWithFormat:@"ChargedBall%li", (long)number]];
   int minX = chargedBall.size.width / 2;
   int maxX = self.frame.size.width - chargedBall.size.width/2;
   int rangeX = maxX - minX;
   int actualX = (arc4random() % rangeX) + minX;

   chargedBall.position = CGPointMake(actualX, 568);
   chargedBall.name = [NSString stringWithFormat:@"chargeNumber%li", (long)number];
   chargedBall.zPosition = 15;
   chargedBall.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:13.0f];
   chargedBall.physicsBody.dynamic = YES;
   chargedBall.physicsBody.affectedByGravity = NO;
   chargedBall.physicsBody.mass = 0.1;
   [self.map addChild:chargedBall];

   [self.chargedBalls addObject:chargedBall];

然后您可以迭代数组并确定是否与任何球发生碰撞。但是,如果您使用 SpriteKit 的物理引擎,您可以让引擎本身通知您发生碰撞。

【讨论】:

感谢您的帮助。我使用了两个答案的组合,所以我只能接受一个,但我为你的时间投了你的票!

以上是关于Sprite Kit,使多个精灵遵循相同的方法的主要内容,如果未能解决你的问题,请参考以下文章

在 Sprite-Kit 中更改精灵图像

使用 Swift 在 sprite kit 中的多个场景中重用相同的 sprite 节点

Sprite Kit:很多精灵 (1000+),带有位 Blitting

Sprite Kit 碰撞发生在精灵之外的几个点

在 Sprite Kit iOS 中使用一个图像精灵表

Swift iOS Sprite Kit - 将精灵从一种颜色淡化为另一种颜色[关闭]