Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xcode 精灵套件+A*寻路=颠簸和冻结_Xcode_Sprite Kit_Freeze_Path Finding - Fatal编程技术网

Xcode 精灵套件+A*寻路=颠簸和冻结

Xcode 精灵套件+A*寻路=颠簸和冻结,xcode,sprite-kit,freeze,path-finding,Xcode,Sprite Kit,Freeze,Path Finding,我试图通过使用精灵工具包制作一个游戏来学习xcode,并且已经取得了相对的进步。我以前做过一些编程,我学得很快,但在调试了几个小时的游戏后,我几乎放弃了 我已经构建了一个包含大量块32x32px和1-4个字符的地图,它使用*寻路来查找路径 它可以工作,但我有两个问题: 路径计算正确,角色移动,但当角色设置动画到下一个块时,会有一点停顿,他会移动到下一个块。这个小停顿使动画看起来像是起伏的,就像char正在行走->微停顿->行走。 路径存储在nsmutablearray中,该方法在完成SKActi

我试图通过使用精灵工具包制作一个游戏来学习xcode,并且已经取得了相对的进步。我以前做过一些编程,我学得很快,但在调试了几个小时的游戏后,我几乎放弃了

我已经构建了一个包含大量块32x32px和1-4个字符的地图,它使用*寻路来查找路径

它可以工作,但我有两个问题:

路径计算正确,角色移动,但当角色设置动画到下一个块时,会有一点停顿,他会移动到下一个块。这个小停顿使动画看起来像是起伏的,就像char正在行走->微停顿->行走。 路径存储在nsmutablearray中,该方法在完成SKAction完成后调用自身以设置下一步的动画。在新动作的完成和动画制作之间,角色会出现这种微停顿

当char计算出一条路径时,游戏会冻结一段时间。当我有4个角色时,每次计算新路径时,游戏都会冻结。为什么呢

当我单击字符应该移动到的块时,我调用:

-(void)moveToward:(tileMap*)selBlock {
    BOOL pathFound = NO;

    if (currentStepAction) {
        self.pendingMove = selBlock;
        return;
    }

    self.StepListOpen = [NSMutableArray array];
    self.StepListClosed = [NSMutableArray array];
    self.shortestPath = nil;

    tileMap *fromTile = self.parentBlock;
    tileMap *toTile = selBlock;

    [self addToOpenSteps:[[ShortestPathStep alloc] initWithBlock:fromTile]];

    do {

        ShortestPathStep *currentStep = [self.StepListOpen objectAtIndex:0];
        [self.StepListClosed addObject:currentStep.theBlock];
        [self.StepListOpen removeObjectAtIndex:0];

        if (CGPointEqualToPoint(currentStep.theBlock.position, toTile.position)) {
            pathFound = YES;
            [self constructPathAndMove:currentStep];
            self.StepListOpen = nil;
            self.StepListClosed = nil;
            break;
        }

        NSArray *adjSteps = [_scene nearbyBlocks:currentStep.theBlock];

        for (tileMap *v in adjSteps) {
            ShortestPathStep *step = [[ShortestPathStep alloc] initWithBlock:v];
            if ([self.StepListClosed containsObject:step.theBlock]) {
                continue;
            }

            int moveCost = [self costToMove:currentStep toAdjacentStep:step];
            NSUInteger index = [self.StepListOpen indexOfObject:step.theBlock];

            if (index == NSNotFound) {
                step.parent = currentStep;
                step.gScore = currentStep.gScore + moveCost;
                CGPoint fromBlock = CGPointMake([[step.theBlock.name substringWithRange:NSMakeRange(6,1)] floatValue], [[step.theBlock.name substringWithRange:NSMakeRange(8,1)] floatValue]);
                CGPoint toBlock = CGPointMake([[toTile.name substringWithRange:NSMakeRange(6,1)] floatValue], [[toTile.name substringWithRange:NSMakeRange(8,1)] floatValue]);
                step.hScore = [self computeHscore:fromBlock toCoord:toBlock];
                [self addToOpenSteps:step];
            } else {
                step = [self.StepListOpen objectAtIndex:index];
                if ((currentStep.gScore + moveCost) < step.gScore) {
                    step.gScore = currentStep.gScore + moveCost;
                    [self.StepListOpen removeObjectAtIndex:index];
                    [self addToOpenSteps:step];
                }
            }
        }
    } while ([self.StepListOpen count] > 0);

    if (!pathFound) {
       NSLog(@"No path found.");
    }
}
现在我们转到popStepAndAnimate,这个方法会被反复调用,直到char到达目的地

-(void)popStepAndAnimate {

    self.currentStepAction = nil;

    if (self.pendingMove != nil) {
        tileMap *moveTarget = pendingMove;
        self.pendingMove = nil;
        self.shortestPath = nil;
        [self moveToward:moveTarget];
        return;
    }

    if (self.shortestPath == nil) {
        return;
    }


    // WE HAVE REACHED OUR BLOCK! CHECK IF ITS CLICKED OR STROLLING
    if ([self.shortestPath count] == 0) {
        self.shortestPath = nil;
        return;
    }

    ShortestPathStep *s = [self.shortestPath objectAtIndex:0];

    CGPoint futurePosition = s.theBlock.position;
    CGPoint currentPosition = self.parentBlock.position;
    CGPoint diff = ccpSub(futurePosition, currentPosition);

    if (abs(diff.x) > abs(diff.y)) {
        if (diff.x > 0) { [self runAnimation:_faceRight speed:0.1]; } else { [self runAnimation:_faceLeft speed:0.1]; }
    } else {
        if (diff.y > 0) { [self runAnimation:_faceUp speed:0.2]; } else { [self runAnimation:_faceDown speed:0.2]; }
    }

    self.parentBlock = s.theBlock;

    SKAction *moveAction = [SKAction moveTo:s.theBlock.position duration:0.7];
    SKAction *callbackAction = [SKAction runBlock:^{ [self popStepAndAnimate]; }];
    self.currentStepAction = [SKAction sequence:@[moveAction, callbackAction]];
    [self.shortestPath removeObjectAtIndex:0];
    [self runAction:currentStepAction];
}

正如您在问题中提到的,您应该提供相关的代码,这样社区才能看到哪里出了问题。只要你有时间,请阅读帮助中心的部分。可能值得发布一些调用路径查找算法的代码。HMI在出错的地方添加了一些代码:感谢我能得到的每一点帮助。几天来一直试图让它更平滑,没有冻结的经验:D
-(void)popStepAndAnimate {

    self.currentStepAction = nil;

    if (self.pendingMove != nil) {
        tileMap *moveTarget = pendingMove;
        self.pendingMove = nil;
        self.shortestPath = nil;
        [self moveToward:moveTarget];
        return;
    }

    if (self.shortestPath == nil) {
        return;
    }


    // WE HAVE REACHED OUR BLOCK! CHECK IF ITS CLICKED OR STROLLING
    if ([self.shortestPath count] == 0) {
        self.shortestPath = nil;
        return;
    }

    ShortestPathStep *s = [self.shortestPath objectAtIndex:0];

    CGPoint futurePosition = s.theBlock.position;
    CGPoint currentPosition = self.parentBlock.position;
    CGPoint diff = ccpSub(futurePosition, currentPosition);

    if (abs(diff.x) > abs(diff.y)) {
        if (diff.x > 0) { [self runAnimation:_faceRight speed:0.1]; } else { [self runAnimation:_faceLeft speed:0.1]; }
    } else {
        if (diff.y > 0) { [self runAnimation:_faceUp speed:0.2]; } else { [self runAnimation:_faceDown speed:0.2]; }
    }

    self.parentBlock = s.theBlock;

    SKAction *moveAction = [SKAction moveTo:s.theBlock.position duration:0.7];
    SKAction *callbackAction = [SKAction runBlock:^{ [self popStepAndAnimate]; }];
    self.currentStepAction = [SKAction sequence:@[moveAction, callbackAction]];
    [self.shortestPath removeObjectAtIndex:0];
    [self runAction:currentStepAction];
}