cocos2dx3.3开发FlappyBird总结十三:数字特效类
2015-03-20 14:44
447 查看
由于显示得分其实是数字精灵的组合,因此需要先设计一个存储数字精灵数列的类:
这个类只有一个成员变量,_numberVector,存储的是一组数字精灵帧,这样就可以通过数字作为下标,直接获取对应的精灵帧。
在初始化时:
因此数字就是0~9这几个,所以是固定的,写成一个宏常量
下面这个方法是获取得分组合精灵,如得分为42,则把对应的精灵帧4和2加入到组合中,
base表示从什么数字开始,这样写是因为有的精灵的名称不是从0开始的,如bird_045~bird_088,那么base就是45了
获取数字精灵帧的时候,传数字过来,就是获取对应的数字精灵帧了,
考虑代码的健壮性,增加了范围的判断
下面是数字特效类了,设计为全局共享类,
首先,显示的方式为居中,居左,居右,因此先设计一个枚举来表示。
看看加载得分精灵方法:
这里_numberContainer是一个Map类型的容器,用于存储得分,因为游戏不断重复的话,同样的得分,就可以直接获取,而不用重复了。
下面这个方法是把数字得分转换成精灵数字,并调整方向:
下一步,先说明一下用到的宏
#ifndef __EngryBird__NumberSeries__ #define __EngryBird__NumberSeries__ #include "cocos2d.h" /** * This class is for ScoreNumber, and it will store a list of sprite frames. * With it, you can load number sprite with name format and get sprite frame * with index. */ class NumberSeries : public cocos2d::Ref { public: /** * The default constructor */ NumberSeries(); /** * The default destructor */ ~NumberSeries(); /** * The init method, will init the super init method first * * @return true if succeeded, otherwise false */ virtual bool init(); CREATE_FUNC(NumberSeries); /** * Load sprite frame with a format name * * @param format The name format, eg. "number1_%d" * @param base The begin index */ void loadNumber(const char *foramt, int base = 0); /** * Get sprite frame with an index * * @param index The index in the _numberVector * * @return a sprite frame object */ cocos2d::SpriteFrame* at(int index); private: /** * Store number sprite frames */ cocos2d::Vector<cocos2d::SpriteFrame *> _numberVector; }; #endif /* defined(__EngryBird__NumberSeries__) */
这个类只有一个成员变量,_numberVector,存储的是一组数字精灵帧,这样就可以通过数字作为下标,直接获取对应的精灵帧。
在初始化时:
bool NumberSeries::init() { _numberVector = cocos2d::Vector<SpriteFrame *>(kMaxNumberCount); return true; }
因此数字就是0~9这几个,所以是固定的,写成一个宏常量
下面这个方法是获取得分组合精灵,如得分为42,则把对应的精灵帧4和2加入到组合中,
void NumberSeries::loadNumber(const char *foramt, int base) { for (int i = base; i < kMaxNumberCount + base; ++i) { char name[20]; sprintf(name, foramt, i); auto frame = AtlasLoader::getInstance()->getSpriteFrame(name); _numberVector.pushBack(frame); } }
base表示从什么数字开始,这样写是因为有的精灵的名称不是从0开始的,如bird_045~bird_088,那么base就是45了
获取数字精灵帧的时候,传数字过来,就是获取对应的数字精灵帧了,
SpriteFrame* NumberSeries::at(int index) { if (index >= 0 && index < _numberVector.size()) { return _numberVector.at(index); } return NULL; }
考虑代码的健壮性,增加了范围的判断
下面是数字特效类了,设计为全局共享类,
首先,显示的方式为居中,居左,居右,因此先设计一个枚举来表示。
/** * The alignment */ typedef enum { kGravityDirectionCenter = 1, kGravityDirectionLeft, kGravityDirectionRight } GravityDirection;
看看加载得分精灵方法:
bool ScoreNumber::loadNumber(const char *name, const char *format, int base) { auto series = NumberSeries::create(); series->loadNumber(format, base); _numberContainer.insert(name, series); return true; }
这里_numberContainer是一个Map类型的容器,用于存储得分,因为游戏不断重复的话,同样的得分,就可以直接获取,而不用重复了。
下面这个方法是把数字得分转换成精灵数字,并调整方向:
Node* ScoreNumber::convert(const char *name, int number, GravityDirection direction) { // 首先根据key,取得数字组合 auto series = _numberContainer.at(name); auto zero = Sprite::createWithSpriteFrame(series->at(0)); // 如果得分为0,直接显示 if (number == 0) { zero->setAnchorPoint(Vec2(0.5, 0)); return zero; } // seperate the number and load number sprite into the node // 使用node节点来容纳数字精灵 auto node = Node::create(); float totalWidth = 0.0f; while (number) { // 循环获取每一位数字,然后获取对应的精灵,添加到node中并计算 // node的总宽 int tmp = number % 10; auto sprite = Sprite::createWithSpriteFrame(series->at(tmp)); totalWidth += sprite->getContentSize().width; node->addChild(sprite); number /= 10; } // set the content size of node node->setContentSize(Size(totalWidth, zero->getContentSize().height)); // caculate the width of each number float perWidth = totalWidth / node->getChildrenCount(); ssize_t index = 0; float anchorX = 0; bool isMinus = true; if (direction == kGravityDirectionCenter) { anchorX = 0.5f; index = node->getChildrenCount() / 2; } else if (direction == kGravityDirectionRight) { anchorX = 1.0f; index = node->getChildrenCount(); } else if (direction == kGravityDirectionLeft) { anchorX = 0.0f; isMinus = false; index = 0; } // 获取显示的方式来调整精灵的位置 for (auto child : node->getChildren()) { child->setAnchorPoint(Vec2(anchorX, 0)); float posX = perWidth * (isMinus ? index-- : index++); child->setPositionX(posX); } return node; }
下一步,先说明一下用到的宏
相关文章推荐
- cocos2dx3.3开发FlappyBird总结四:资源管理类
- cocos2dx3.3开发FlappyBird总结九:欢迎场景(WelcomeScene)
- cocos2dx3.3开发FlappyBird总结五:说说屏幕适配
- cocos2dx3.3开发FlappyBird总结七:说说游戏流程
- cocos2dx3.3开发FlappyBird总结十六:游戏层实现
- cocos2dx3.3开发FlappyBird总结十一:控制层功能设计
- cocos2dx3.3开发FlappyBird总结八:载入场景LoadingScene
- cocos2dx3.3开发FlappyBird总结十四:常量定义
- cocos2dx3.3开发FlappyBird总结十五:记录玩家得分
- cocos2dx3.3开发FlappyBird总结十二:状态层设计
- cocos2dx3.3开发FlappyBird总结十:背景层设计
- cocos2dx3.3开发FlappyBird总结六:设计共享小鸟类(主角)
- cocos2dx3.3开发FlappyBird总结三:项目剖析
- cocos2dx3.3开发FlappyBird总结一:背景介绍
- cocos2dx3.3开发FlappyBird总结十七:结束语
- cocos2dxFlappyBird开发总结二:开发环境介绍
- cocos2dx3.2开发 RPG《Flighting》(十三)让英雄炫酷点—技能以及技能效果
- 【COCOS2DX-LUA 脚本开发之十三】解决Cocos2dx-Lua编译到Android找不到CCLuaEngine、HelloWorld或出现get data from file(xxx.lua
- cocos2dx游戏开发总结
- cocos2dx3.2开发 RPG《Flighting》(十五)最后的总结说明,以及源码分享