Cocos2dx 3.2 横版过关游戏Brave学习笔记(二)

作者: douxt



动画

这次我们要让人物动起来。
首先要将精灵帧缓存中的帧组合成动画,然后将这些动画放到动画缓存中。
需要播放的时候直接从缓存中拿出来用即可。


目前这个项目里用到的帧的格式为:  player1-1-1.png, 即:角色-动作编号-动画帧编号.png
对于player1,有walk,attack,dead,hit,skill动作,每个动作的帧数可以不同,这里分别为,4,4,4,2,4
对于enemy1,有walk,attack,dead,hit,帧数分别为3,3,3,2
相关信息可以在Resources下的image/role.plist里看到。

对于不同的角色类型,加载动画时略参数略有不同,现在我们给Player类增加一些参数,记录这些不同之处,并在初始化函数中,根据角色类型的不同来给这些参数赋值。
首先建立一个字符串,记录动画的前缀,如PLAYER类型的角色_name值为"player1"。
还需要一个整数记录动作的数目,一个字符串数组记录动作的名称,以及一个整数数组记录每个动作的帧数。

在类Player的末端加入:

private:
    PlayerType _type;  
    std::string _name;
    int _animationNum; 
    std::vector _animationFrameNum;
    std::vector _animationNames;

然后修改InitWithPlayerType函数,使之如下:

bool Player::initWithPlayerType(PlayerType type)
{
    std::string sfName = "";
    _type = type;
    int animationFrameNum[5] ={4, 4, 4, 2, 4};
    int animationFrameNum2[5] ={3, 3, 3, 2, 0};
 
    //setup according to PlayerType
    switch(type)
    {
    case PlayerType::PLAYER:
        sfName = "player1-1-1.png";
        _name = "player1";
        _animationNum = 5;
        _animationFrameNum.assign(animationFrameNum, animationFrameNum + 5);
        break;
    case PlayerType::ENEMY1:
        sfName = "enemy1-1-1.png";
        _name = "enemy1";
        _animationNum = 4;
        _animationFrameNum.assign(animationFrameNum2, animationFrameNum2 + 5);
        break;
    case PlayerType::ENEMY2:
        sfName = "enemy2-1-1.png";
        _name = "enemy2";
        _animationNum = 4;
        _animationFrameNum.assign(animationFrameNum2, animationFrameNum2 + 5);
        break;
    }
    this->initWithSpriteFrameName(sfName);
    std::string animationNames[] = {"walk", "attack", "dead", "hit", "skill"};
    _animationNames.assign(animationNames, animationNames + 5);
    //load animation
    this->addAnimation();
    return true;
}

现在给Player类增加载入动画函数Player::addAnimation(),相同动画的载入只需要进行一次,所以载入前先确定所需动画还没有被载入。

void Player::addAnimation()
{
    // check if already loaded
    auto animation = AnimationCache::getInstance()->getAnimation(String::createWithFormat("%s-%s",_name.c_str(),
                        _animationNames[0])->getCString());
    if(animation)
        return;
     
    for(int i1=0; i1<_animationNum; i1++)     {         auto animation = Animation::create();         animation->setDelayPerUnit(0.2f);
        //put frames into animation
        for(int j = 0; j< _animationFrameNum[i1] ; j++)         {             auto sfName =String::createWithFormat("%s-%d-%d.png",_name.c_str(), i1+1, j+1)->getCString();
            animation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(sfName));
        }
        // put the animation into cache
        AnimationCache::getInstance()->addAnimation(animation, String::createWithFormat("%s-%s",_name.c_str(), 
                    _animationNames[i1].c_str())->getCString());
    }
}

现在加入一个根据动作编号进行指定动作的函数,查看动画是否载入成功。

void Player::playAnimationForever(int index)
{
    if(index = _animationNum)
    {
        log("illegal animation index!");
        return;
    }
    auto str = String::createWithFormat("%s-%s",_name.c_str(), _animationNames[index].c_str())->getCString();
    auto animation = AnimationCache::getInstance()->getAnimation(str);
    auto animate = Animate::create(animation);
    this->runAction(RepeatForever::create(animate));
}

在HelloWorld::init()的末端加入如下语句,然后运行。

//add player
    Player* player = Player::create(Player::PlayerType::PLAYER);
    player->setPosition(origin.x + player->getContentSize().width/2, origin.y + visibleSize.height/2);
    this->addChild(player);
 
 
    //add enemy1
    Player* enemy1 = Player::create(Player::PlayerType::ENEMY1);
    enemy1->setPosition(origin.x + visibleSize.width - player->getContentSize().width/2, origin.y + visibleSize.height/2);
    this->addChild(enemy1);
 
    //test animation
    player->playAnimationForever(1);
    enemy1->playAnimationForever(1);

结果如下:



用GitHub来管理源代码是个不错的选择。
项目的代码经常会进行删减,随着笔记的进行,最后的代码可能和前期相比面目全非了,但是使用GitHub可以让你访问任意历史版本。
我刚刚进行了一个名为“Note2”的commit,如果有人想下载代码,可以点下面链接,点下载Zip即可。
https://github.com/douxt/Brave_cpp/tree/8752cc055601800eb10ed73d9ea757993dfa352a
即使以后更新了,这个历史版本还是可以访问。

注意:代码中没有包含cocos2d目录,可以将其他项目的cocos2d目录拷贝到项目目录下。

标签: none

?>