CocoStudio sample讲解 DemoCowboyGame 牛仔演示

CocoStuido sample----DemoMap 源代码地址
https://github.com/chukong/CocoStudioSamples
大家可以预先下载这个源代码, 等下要用到里面的图片资源哦

一 目标


在本教程里, 我们将学习下如何联合使用UI编辑器, 动画编辑器和场景编辑器.
我们使用的cocos2d-x的版本是2.2.3, CocoStudio的版本是1.2.0.1. 不同的版本, 功能上会有差异, 大家学习时, 最好采用对应的版本.

我们要在场景编辑器中添加制作好的动画和UI, 然后点击UI层的左右走动按钮, 酷酷的牛仔会左右移动, 点击蓝色圆形按钮, 牛仔会开火.

二 创建项目并导入资源
今天我们要同时用到UI编辑器, 动画编辑器和场景编辑器.
大家可以在下载到的源代码的DemoCowboyGame\EditorProjects\DemoUI\Resources 目录下找到UI编辑器需要的资源.
在DemoCowboyGame\EditorProjects\DemoAnimation 目录中找到动画编辑器需要的资源.
而场景编辑器使用的资源则是UI项目, 动画项目导出的文件.

大家分别创建新的动画编辑器和UI编辑器项目, 并分别导入资源.

我们在前面已经学习了很多关于动画制作和UI制作的例子, 我们在这里就不在详细讲诉其制作.
大家可以参照目录中已经做好的例子, 做出动画和UI, 并导出资源

然后创建一个场景编辑器, 并导入上面导出的资源.
向渲染区添加骨骼组件和UI, 并分别为其指定文件属性分别为导出的动画文件和UI文件.

如果大家在制作的过程中遇到了问题, 不妨到CocoaChina论坛的CocoStudio专区提出来, 大家多加交流.

三 导出资源
我们在场景编辑器里面用快捷键Ctrl+E打开导出对话框, 选择导出的路径, 按默认配置导出. 我们稍后会用到这些文件.

四 在cocos2d-x工程中添加导出后的资源
想必各位看官都已经熟练掌握了cocos2d-x工程的创建, 我这里就不再啰嗦了.
创建完工程之后, 需要将我们上面用CocoStudio导出的几个文件拷贝到cocos2d-x工程的Resources文件夹下.

五 代码实现
我们先添加一个Player类, 用于管理我们的英雄. 我们来先看下Player.h类的声明部分.

#include “cocos2d.h”#include “cocos-ext.h”
USING_NS_CC ;USING_NS_CC_EXT ;using namespace std;
#define WALK_SPEED 10 //行走速度#define WALK_LEFT 1 //方向向左#define WALK_RIGHT -1 //方向向右
enum PlayerState {//英雄状态 IDLE = 0, //闲置状态 WALK, //走路 SHOOT, //开火 };
class Player : public CCObject{ CCNode* playerNode; CCArmatureAnimation* animation; PlayerState currentState; //英雄当前状态 PlayerState newState; //英雄新状态 int direction; //方向
public : Player( CCNode* node); void update( float dt); void updateAnimation(); void updateMovement(); void play( string animName); //播放动画 inline void setState( PlayerState state) {newState = state;} //设置状态 void setDirection( int newDirection); //设置方向};

我们再来看下类的实现部分
#include “Player.h”
Player ::Player(CCNode * playerNode ): CCObject(){ this->playerNode = playerNode; CCComRender* comRender = static_cast <CCComRender *>(playerNode ->getComponent( “CCArmature”)); CCArmature *animationNode = static_cast <CCArmature *>(comRender->getNode()); this->animation = animationNode->getAnimation(); currentState = IDLE; //默认状态为闲置 newState = IDLE; //新状态为闲置}
//设置英雄方向void Player ::setDirection( int newDirection){ direction = newDirection; //设置用户方向 playerNode->setScaleX(direction * fabs(playerNode->getScaleX())); //根据英雄走动方向,}
//更新void Player ::update(float dt ){ if (currentState == newState) //当前状态与新状态相同 { updateMovement(); //更新英雄位置 } else { currentState = newState; //更新英雄状态 updateAnimation(); //更新状态 }}
//更新英雄位置void Player ::updateMovement(){ CCPoint oldPos = playerNode->getPosition(); //获取当前位置 if (currentState == WALK) //正在行走 { //根据速度方向更新英雄位置 playerNode->setPosition(oldPos.x + -direction * WALK_SPEED, oldPos.y); }}
//根据英雄状态来选择需要播放的动画void Player ::updateAnimation(){ switch (currentState) { case IDLE: //闲置状态 animation->play( “stand” );//播放站立的动画 break; case SHOOT: //开火状态 animation->play( “stand_fire” );//播放开火动画 break; case WALK: animation->play( “walk” );//播放走路动画 break; default: break; }}

我们在HelloWorld中, 做下简单的修改. 在声明中添加几个函数.
void onMoveLeft( CCObject* pSender, TouchEventType type);//点击了向左按钮 void onMoveRight( CCObject* pSender, TouchEventType type);//点击了向右按钮 void onFire( CCObject* pSender, TouchEventType type);//点击了开火按钮

我们再来看下其实现.
在HelloWorld.cpp中修改HelloWorld::init的实现, 在最后加入.
//加载场景 CCNode* gameScene = SceneReader ::sharedSceneReader()->createNodeWithSceneFile( “DemoCowboy.json”); addChild(gameScene); //添加到父节点 //获取英雄所在节点 CCNode* playerNode = gameScene->getChildByTag(10004); player = new Player(playerNode); //创建英雄对象 //获得UI层节点 CCNode* uiNode = gameScene->getChildByTag(10005); CCComRender render = static_cast <CCComRender >(uiNode->getComponent( “GUIComponent”)); UILayer ui = ( UILayer)render->getNode(); UIButton* btnLeft = ( UIButton*)ui->getWidgetByName( “LeftButton” );//向左点击按钮 btnLeft->addTouchEventListener( this, toucheventselector (HelloWorld ::onMoveLeft)); //点击事件绑定 UIButton* btnRight = ( UIButton*)ui->getWidgetByName( “RightButton” );//向右点击按钮 btnRight->addTouchEventListener( this, toucheventselector (HelloWorld ::onMoveRight)); //点击事件绑定 UIButton* btnFire = ( UIButton*)ui->getWidgetByName( “FireButton” );//开火点击按钮 btnFire->addTouchEventListener( this, toucheventselector (HelloWorld ::onFire));//点击事件绑定 this->scheduleUpdate(); return true;

然后其他函数的实现部分.
void HelloWorld ::onMoveLeft(cocos2d:: CCObject * pSender, TouchEventType type){ if( type == TOUCH_EVENT_BEGAN) //点击向左按钮开始设置为走路状态 { player->setDirection( WALK_LEFT); player->setState( WALK); } if ( type == TOUCH_EVENT_ENDED) //点击结束设置为闲置状态 { player->setState( IDLE); }}
void HelloWorld ::onMoveRight(cocos2d:: CCObject * pSender, TouchEventType type){ if ( type == TOUCH_EVENT_BEGAN) //点击向右按钮开始设置为走路状态 { player->setDirection( WALK_RIGHT); player->setState( WALK); } if ( type == TOUCH_EVENT_ENDED) //点击结束设置为闲置状态 { player->setState( IDLE); }}
//点击开火按钮void HelloWorld ::onFire(cocos2d:: CCObject * pSender, TouchEventType type){ if ( type == TOUCH_EVENT_BEGAN) //点击开始设置为开火状态 { player->setState( SHOOT); } if ( type == TOUCH_EVENT_ENDED) //点击结束设置为闲置状态 { player->setState( IDLE); }}

好了赶快运行下吧.

补了一篇…:3:

似乎应该对TOUCH_EVENT_CANCELED状态做处理= =

嗯, 你说的很对.

这个系列的教程希望起到一个抛砖引玉的作用

当然, 我们在后续的例子, 教程里面, 会更加注意和实际开发中的结合, 尽量做到符合开发习惯.

感谢你的建议, 给你加32个赞 :855:

赞,我赞,我赞赞赞
赞赞赞赞赞赞赞赞赞赞赞
赞赞赞赞赞赞赞赞赞赞赞
赞,我赞,我赞赞赞

排版好看多了,感谢分享实际结合的例子,感谢

         //获得UI层节点
CCNode* uiNode = gameScene->getChildByTag(10005);
         CCComRender *render = static_cast <CCComRender *>(uiNode->getComponent( "GUIComponent"));
UILayer* ui = ( UILayer*)render->getNode();

UIButton* btnLeft = ( UIButton*)ui->getWidgetByName( "LeftButton" );//向左点击按钮
btnLeft->addTouchEventListener( this, toucheventselector (HelloWorld ::onMoveLeft)); //点击事件绑定

这段在3.0里面到底改成什么样子了啊!!!!

UILayer—〉Layer
UIButton–〉Widget

然后我用addTouchEventListener的时候TouchEventType没有该标识符啊啊!!!
我加了namespace ui 编译时候有又说ui不是cocos2d的命名空间。。 有病啊!! gui的命名空间又根本没有。。。