我正在尝试通过使用精灵套件制作游戏来学习xcode并且已经相对较远 . 我以前做过一些编程,但我学得很快,但经过几个小时的调试后,我几乎放弃了 .

我已经构建了一个包含许多块(32x32px)和1-4个字符的映射,它们使用A *寻路来查找路径 .

它有效,但我有两个问题:

  • 正确计算路径并且char移动但是当char动画到下一个块时,有一个小paus并且他移动到下一个块 . 这个小小的paus使得动画看起来不稳定,就像char走路 - > micropaus - > walk . 路径存储在nsmutablearray中,并且该方法在完成SKAction(完成)后调用自身以设置下一个动作的动画 . 在新动作的完成和动画之间,有这个角色的微观 .

  • 当char计算路径时,游戏会冻结一段时间 . 当我有4个字符时,每次计算新路径时游戏都会冻结 . 这是为什么?

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

-(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.");
    }
}

如果找到它调用的路径

- (void)constructPathAndMove:(ShortestPathStep *)step {
    self.shortestPath = [NSMutableArray array];
    do {
        if (step.parent != nil) {
            [self.shortestPath insertObject:step atIndex:0];
        }
        step = step.parent;
    } while (step != nil);

    [self popStepAndAnimate];
}

现在我们转到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];
}