(NO.00005)iOS实现炸弹人游戏(九):游戏主角(二)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处.
如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;)



上篇介绍了游戏主角的初始化方法,下面我们一次来实现主角的其他方法,首先来看看runAnimation方法,我们使用这个方法来播放主角的动画:

-(void)runAnimation:(CCAnimation*)animation{
    if (_curAnimation == animation) {
        return;
    }

    _curAnimation = animation;
    if (_curAnimate) {
        [self stopAction:_curAnimate];
    }

    _curAnimate = [CCActionRepeatForever actionWithAction:
                   [CCActionAnimate actionWithAnimation:animation]];
    [self runAction:_curAnimate];
}

代码首先检查将要播放的动画是否和当前正在播放的动画相同,如果相同则直接退出.然后如果当前正在播放动画动作,则将其停止.

接下来为需要播放的动画创建一个永久循环的动作,然后运行该动作.

上图是玩家控制游戏主角在场景中自由行走所播放的各种动画,最后主角碰上怪物挂掉的动画也是如此.

主角类中还有一个重要的方法,应该还包括该游戏中所有怪物都需要这么一个方法,就是A*的移动算法.不熟悉A*算法的小伙伴可以到我翻译和原创的A*系列博文中观赏:

原创:如何在Cocos2D游戏中实现A*寻路算法(一)
翻译:A*寻路算法入门(一)

该方法就是moveTowardByAStar方法:

//使用A*寻路算法移动至目标坐标
-(void)moveTowardByAStar:(CGPoint)targetLocation{
    if (_currentStepAction) {
        _pendingMove = [NSValue valueWithCGPoint:targetLocation];
        return;
    }

    CGPoint fromTileCoord = [_mainScene tileCoordForPosition:self.position];
    CGPoint toTileCoord = [_mainScene tileCoordForPosition:targetLocation];

    if (CGPointEqualToPoint(fromTileCoord, toTileCoord)) {      return;
    }

    if (![_mainScene isWalkableTile:toTileCoord forRole:self]) {
        return;
    }

    _spOpenSteps = [NSMutableArray array];
    _spClosedSteps = [NSMutableArray array];
    _shortestPath = nil;

    [StarA insertStep:[[ShortestPathStep alloc] initWithPosition:fromTileCoord]
                                                                    toOpenList:_spOpenSteps];
    do{
        ShortestPathStep *currentStep = _spOpenSteps[0];
        [_spClosedSteps addObject:currentStep];
        [_spOpenSteps removeObjectAtIndex:0];
        if (CGPointEqualToPoint(currentStep.position, toTileCoord)) {
            //如果已经找到最短路径则完成该最短路径的移动动作
            [self constructPathAndStartAnimationFromStep:currentStep];
            _spOpenSteps = nil;
            _spClosedSteps = nil;
            break;
        }

        NSArray *adjSteps = [_mainScene walkableAdjacentTilesCoordDiagonallyForTileCoord:
                                                                currentStep.position forRole:self];

        for (NSValue *v in adjSteps) {
            ShortestPathStep *step = [[ShortestPathStep alloc]initWithPosition:[v CGPointValue]];
            if ([_spClosedSteps containsObject:step]) {
                continue;
            }

            int moveCost = [StarA costToMoveDiagonallyFromStep:currentStep toAdjacentStep:step];
            NSUInteger index = [_spOpenSteps indexOfObject:step];
            if (index == NSNotFound) {
                step.parent = currentStep;
                step.gScore = currentStep.gScore + moveCost;
                step.hScore = [StarA computeHScoreFromCoord:step.position toCoord:toTileCoord];
                [StarA insertStep:step toOpenList:_spOpenSteps];
            }else{//已经存在于开放列表
                step = _spOpenSteps[index];
                if ((currentStep.gScore + moveCost) < step.gScore) {
                    step.gScore = currentStep.gScore + moveCost;
                    step.parent = currentStep;
                    [_spOpenSteps removeObjectAtIndex:index];
                    [StarA insertStep:step toOpenList:_spOpenSteps];
                }
            }
        }
    }while (_spOpenSteps.count > 0);
}

其中比较长,这里就不详细说明了,大家需要的信息上面2个系列的博文完全涵盖了.有一点要指出的是,因为我也才开始写这类代码,所以一开始对类元素的把握也不是太强,按理说这个方法是所有游戏角色都需要的,所以应该放在它们的父类中.的确是这样,我在另一个RPG游戏<<熊猫之魂>>中正是这样做的,我们有机会再叙.

时间: 2024-11-02 20:10:19

(NO.00005)iOS实现炸弹人游戏(九):游戏主角(二)的相关文章

(NO.00005)iOS实现炸弹人游戏(八):游戏主角(一)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 最近一直在做另一个RPG游戏,所以本系列迟迟没有更新,上一篇博文的地址在: (NO.00005)iOS实现炸弹人游戏(七):游戏数据的序列化表示 本篇接着上篇介绍炸弹人游戏中的游戏主角的基本构成,游戏主角自然是我们的炸弹人了. 因为主角会在游戏场景中各个方向行走,所以我们需要先准备其对应的图片资源: 如各位所见除了普通的移动动作,我还选择了主角被人道毁灭和无敌

(NO.00005)iOS实现炸弹人游戏(三):从主场景类谈起

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我又粗粗看了下整个项目的代码,比较多: 不少类都与其他类有着千丝万缕的联系,所以在后面交代某个类的时候可能会遇到一些其他类中的代码,这个大家先看名会意吧.如果实在不明白的,都是我叙述的原因,和大家的理解力没有任何关系 ;).大家可以随时在博文后面直接跟帖发消息给我,如果时间允许,每条我都会回复. 从MainScene类开始 MainScene类是整个工程里代码最

(NO.00005)iOS实现炸弹人游戏(十一):怪物之火精灵

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 从本篇开始我们一次介绍一下游戏中敌人的制作过程.看过第一篇的小伙伴都知道,在炸弹人游戏中一共准备实现4种敌人.不同的怪物要有不同的特点,否则如果只是外形发生变化其余行为都一样的话,也就没有什么意思了. 我们本篇先介绍第一种,也是最普通的火焰精灵FireSprite. 首先需要找到火焰精灵对应的素材: 用TexturePacker制作成Cocos2D可以使用的纹

(NO.00005)iOS实现炸弹人游戏(七):游戏数据的序列化表示

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 用plist列表文件来表示游戏数据 因为在这个炸弹人游戏中有很多不同的关卡,难度依次上升,所以对于每个关卡的数据我们必须存放在某个地方,有很多种保存方法,这里我们选择使用plist列表文件来保存每个关卡的数据. 选择Resources目录,在其中新建一个plist文件,命名为LevelsData.plist. 下面我们要想一想里面到底要存放神马数据. 大致有这些

(NO.00005)iOS实现炸弹人游戏(二):素材选择的取舍

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 前面一篇里我们基本明确了游戏的大致玩法和特点.下面就游戏中会用到的一些素材准备做些说明. 游戏主角与敌人 首先是游戏主角,这个从网上可以找到炸弹人的全部动画贴图,包括骑着各种坐骑的都有.但是遗憾的是炸弹人中怪物的素材很少,我只找到1种全套的贴图.所以对于怪物素材来说我们可以想点其他办法,以下是本猫猪制作炸弹人的效果动画: 对于游戏中其它敌人的动画,我也从网上随便

(NO.00005)iOS实现炸弹人游戏(四):游戏数据的初始化(一)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 上一篇我们初步看了一下MainScene类的初始化方法里都做了神马事,其中随机化地图是在initGameDataFromGD方法里做的,我们就来深入看看这个方法. 该方法是一个比较长的方法,里面又调用了若干其他方法,我把其中主要的代码在下面列出来: //用游戏数据初始化当前关卡的数据 -(void)initGameDataFromGD{ [_gd loadGam

(NO.00005)iOS实现炸弹人游戏(五):游戏数据的初始化(二)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们现在来依次看一下上篇中提到的各个方法,首先介绍的是updateStateLabel方法: #pragma mark MainScene游戏相关辅助方法 //更新主角状态标签,格式为:神速 无敌 爆裂 穿墙 穿弹 遥控 -(void)updateStateLabel{ NSString *state = [NSString stringWithFormat:@

(NO.00005)iOS实现炸弹人游戏(十):游戏主角(三)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 下面我们来看游戏主角类里面几个播放特殊动画的方法,首先从runWinAnimation开始: //运行精灵庆祝时的动画 -(void)runWinAnimation{ CCActionJumpBy *jump = [CCActionJumpBy actionWithDuration:5 position:ccp(0, 5) height:5 jumps:10]

(NO.00005)iOS实现炸弹人游戏(六):游戏数据的初始化(三)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 现在我们来看看实际初始化地图的randomCreateMap方法: //在空白地图上根据当前关卡数据随机创建一个关卡地图 //地图总共瓦块为30x10 = 300块,抛去不能移动的Wall(48块)还剩252块空格. //还要减去player和敌人占去的空格.玩家出现在每一关的(0,0)瓦格上. //为了保证player不至于卡死,(0,0),(0,1)和(1,