一个简单的游戏开发框架(七.动作Motion)
2024-10-09 09:57:45
发现还没谈到最基本也是最重要的问题,怎么画图,画动画?
在原版cocos2d-x里画动画比较麻烦,见cocos2d-x学习笔记04:简单动画
cocostudio扩展出CCArmature类,就比较简单了
cocos2d::extension::CCArmature *armature = nullptr;
armature = cocos2d::extension::CCArmature::create("name");
armature->getAnimation()->playByIndex();
从游戏逻辑的角度来看的话,比如考察一个RPG游戏的主角,通常他有站立,行走,攻击,受伤,倒地,死亡等动作,有中毒,加攻,加防等状态。一个动画会对应一个动作或状态,但是反过来不一定,一个动作可能包含不止一个动画。比如行走,在横版游戏中有两个方向,两个方向可以用一个翻转的动画来实现,还是一个动画;在ARPG游戏中可能有4个甚至8个方向,这时候行走动作不能用一个动画实现了,可能包含4或8个动画。
因此这里可以把动作/状态抽象出来成为一个类,统称为动作Motion。一个Motion可能是一个静态图形,一个动画或几个动画。Motion和Action的区别在于,Action改变对象属性,客户端/服务器通用,Motion不改变对象属性,仅用于客户端表现。举例来讲,移动,就是一个Action(坐标改变)和一个Motion(行走动画)的组合。
在接口篇里,没有提到Motion的概念。在概念上对象+行为就足以描述游戏逻辑,应该没有必要再增加新的实体,因此希望对Action的操作能导致Motion自动改变。考虑到,如果把“当前动作”作为对象的一个属性的话,可以认为所有Motion(动作+状态)都是随对象属性的改变而改变的,因此对Motion的操作可以通过以下方式进行:Action改变对象属性,属性改变导致动作/状态改变。
一个对象,其所拥有的动作是有限的,可以在配置文件里配置,在对象加载的时候把所有动作一起加载进来。
typedef struct
{
enum E
{
NONE,
STAND, // 站立
MOVE, // 移动 COUNT
};
}Motions; class Motion
{
public:
virtual ~Motion() {} public:
virtual void InitMotion() = ;
virtual void RunWithObject(ObjectView* pObj) = ;
virtual void StopMotion() = ;
}; class ObjectView : public Object
{
public:
ObjectView();
virtual ~ObjectView(); public:
virtual bool LoadObject(const char* fileName);
virtual void OnPropertyChanged(uint32 propertyID, Property& oldValue); virtual Motion* CreateMotion(uint32 motionID); // 工厂方法 protected:
std::map<uint32, Motion*> _motions;
};
void ObjectView::OnPropertyChanged(uint32 propertyID, Property& oldValue)
{
if (Properties::MOTION == propertyID) // 动作改变
{
// 停止旧动作
uint32 oldMotion = oldValue;
if (_motions.find(oldMotion) != _motions.end())
_motions[oldMotion]->StopMotion(); // 播放新动作
uint32 motionID = GetProperty(Properties::MOTION);
if (_motions.find(motionID) != _motions.end())
_motions[motionID]->RunWithObject(this);
}
}
静态图Motion:
class MotionImage : public Motion
{
public:
virtual void InitMotion();
virtual void RunWithObject(ObjectView* pObj);
virtual void StopMotion(); private:
Image _image; // 等于CCSprite
};
void MotionImage::InitMotion()
{
CCTexture2D* pTex = CCTextureCache::sharedTextureCache()->textureForKey(_image._texKey.c_str());
if (pTex)
{
_image._sprite->setTexture(pTex);
_image._sprite->setTextureRect(_image._sprite->getTextureRect());
}
} void MotionImage::RunWithObject(ObjectView* pObj)
{
ObjectCocos2dx::Cast(pObj->GetEngineData())->m_pNode->addChild(_image._sprite);
} void MotionImage::StopMotion()
{
_image._sprite->removeFromParent();
}
有两个方向的动画Motion:
class MotionAnim2 : public Motion
{
public:
MotionAnim2() : _pAnimation(nullptr), _direction(Directions::NONE) {}
virtual ~MotionAnim2(); public:
virtual void InitMotion();
virtual void RunWithObject(ObjectView* pObj);
virtual void StopMotion(); private:
Animate* _pAnimation; // 等于CCArmature
int _direction;
};
void MotionAnim2::InitMotion()
{
cocos2d::extension::CCArmature *armature = nullptr;
armature = cocos2d::extension::CCArmature::create(_pAnimation->_animName.c_str());
_pAnimation->_armature = armature;
} void MotionAnim2::RunWithObject(ObjectView* pObj)
{
int direction = pObj->GetProperty(Properties::DIRECTION); if (_direction != direction)
{
// 镜像动画
float sx = -_pAnimation->_armature->getScaleX();
float sy = _pAnimation->_armature->getScaleY();
_pAnimation->_armature->runAction(CCScaleTo::create(0.0f, sx, sy)); _direction = direction;
} _pAnimation->_armature->getAnimation()->playByIndex();
// 加入对象的CCNode结点
ObjectCocos2dx::Cast(pObj->GetEngineData())->m_pNode->addChild(_pAnimation->_armature);
} void MotionAnim2::StopMotion()
{
_pAnimation->_armature->stopAllActions();
_pAnimation->_armature->removeFromParentAndCleanup(false);
}
最新文章
- 输出 n=6 的三角数字阵(JAVA基础回顾)
- iOS 系统分析(一) 阅读内核准备知识
- django-- Models
- 简单的例子 关于Java内存管理的讲解
- PHP对图片按照一定比例缩放并生成图片文件
- 2014 WAP校园招聘笔试题
- 用windows远程连接linux桌面(使用tightvnc或者tigervnc)
- Servlet课程0424(三) 通过继承HttpServlet来开发Servlet
- 使用ajax传递及接收数据
- 跨域文件crossdomain.xml在weblogic上的部署
- C语言学习(记录)【内存相关_1:内存基础】
- 深入理解 Python 异步编程(上)
- 原生 table css实现操作按钮固定右侧及底部滚动 IE不会卡死
- Codeforces Round #369 (Div. 2) C. Coloring Trees(简单dp)
- php unset对json_encode的影响
- 044、vloume声明周期管理(2019-03-07 周四)
- jenkins(8): 实战jenkins+gitlab持续集成发布php项目(代码不需要编译)
- VMware vSphere client 中英文语言界面设置
- hdu-3366 Passage 概率DP 读懂就能AC hhh
- iOS 10 的一个重要更新-新的通知推送 API