在 Sprite Kit 中永远随机移动精灵的最佳方法

Posted

技术标签:

【中文标题】在 Sprite Kit 中永远随机移动精灵的最佳方法【英文标题】:Best way to randomly move sprite forever in Sprite Kit 【发布时间】:2015-08-25 19:47:28 【问题描述】:

我有一个精灵,我想永远将它移动到随机点。我已经编写了这段代码,但我认为它效率不高。

-(void)addBoss 
    SKSpriteNode *boss = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
    boss.position = CGPointMake(self.size.width + boss.size.width / 2.0, self.size.height / 2.0);
    boss.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:boss.size];
    boss.physicsBody.dynamic = YES;
    boss.physicsBody.categoryBitMask = bossCategory;
    boss.physicsBody.contactTestBitMask = bossContact;
    boss.physicsBody.collisionBitMask = 0;
    boss.zPosition = 1;
    self.boss = boss;
    self.bossHealth = bossHP;
    CGPoint destination = CGPointMake(self.size.width - boss.size.width / 2.0, boss.position.y);
    float time = length(boss.position, destination) / bossSpeed;
    SKAction *move = [SKAction moveTo:destination duration:time];
    [self addChild:boss];
    [self.boss runAction:[SKAction sequence:@[move, [SKAction runBlock:^
        [self artificialIntelligence];
    ]]]];


- (void)moveBoss 
    float minimumX = self.size.width / 2.0 + self.boss.size.width / 2.0;
    float maximumX = self.size.width - self.boss.size.width / 2.0;
    float minimumY = self.boss.size.height / 2.0;
    float maximumY = self.size.height - self.boss.size.height / 2.0;

    int rangeX = maximumX - minimumX;
    int rangeY = maximumY - minimumY;

    float x = arc4random() % rangeX + minimumX;
    float y = arc4random() % rangeY + minimumY;
    CGPoint dest = CGPointMake(x, y);
    float duration = length(self.boss.position, dest) / putinSpeed;
    [self.boss runAction:[SKAction moveTo:dest duration:duration] completion:^
        [self moveBoss];
    ];


-(void)artificialIntelligence 
    [self moveBoss];

这段代码运行良好,但我认为在移动完成后递归调用 move 方法并不是最好的解决方案。

解决此类问题的最佳方法是什么?

【问题讨论】:

您需要指定某种围棋运动模式。以纯粹随机的方式移动并不是一件好事。例如,从当前位置移动至少 x 和 y 距离。 提示:使用arc4random_uniform(rangeX),它更容易并且对mod操作员没有任何偏见。 该点不在运动模式中。我只是想知道如何让这个动作永远重复而不递归。只是某种方法可以让moveBoss 方法等到移动完成并再次重复。 【参考方案1】:

这是一种快速而肮脏的方式来满足您的要求:

-(void)moveCharacter 

    SKNode *playerNode;

    // get random position
    CGPoint destination = [self randomPosition];

    if(!CGPointEqualToPoint(playerNode.position, destination)) 

        // check xPos
        if(playerNode.position.x > destination.x) 
            playerNode.position = CGPointMake(playerNode.position.x-1, playerNode.position.y);
        
        if(playerNode.position.x < destination.x) 
            playerNode.position = CGPointMake(playerNode.position.x+1, playerNode.position.y);
        

        // check yPos
        if(playerNode.position.y > destination.y) 
            playerNode.position = CGPointMake(playerNode.position.x, playerNode.position.y-1);
        
        if(playerNode.position.y < destination.y) 
            playerNode.position = CGPointMake(playerNode.position.x, playerNode.position.y+1);
        

     else 

        destinationReached = YES;
    


-(CGPoint)randomPosition 

    CGRect screenRect = [[UIScreen mainScreen] bounds];

    int xPos = arc4random() % (int)screenRect.size.width;
    int yPos = arc4random() % (int)screenRect.size.height;

    return CGPointMake(xPos, yPos);

关于如何移动你的角色有许多不同的变化。例如,您可以将 x,y 的差异划分为固定数量的移动,以使玩家在从 A 点到 B 点的平滑线上移动。如果您是物理移动玩家,则必须使用 CGVector 而不是直接改变他的 x,y 位置。

【讨论】:

以上是关于在 Sprite Kit 中永远随机移动精灵的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

在 Sprite-Kit 中更改精灵图像

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

sprite kit:如何根据距离改变 skaction 持续时间?

如何确定节点出现在 sprite kit 中的顺序

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

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