Cocos2d-x3.x塔防游戏保卫萝卜从零开始(三)

转自:http://www.cnblogs.com/hll2008/p/4266776.html

一、前提:

完成前一篇的内容。

具体参考:Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(二)篇

二、本篇目标:

l 说说游戏中各种角色的动作、属性以及重构思路

l 进行代码重构让色狼大叔和女主角生动鲜活起来

三、内容:

l说说游戏中各种角色的动作、属性以及重构思路

通过前两篇我们建立的一个简陋的游戏原型,但是游戏中的人物比如色狼大叔、女主角都看去来很呆板不够鲜活,比如色狼会沿着道路移动,那这个只能说是移动根本不像是在走路,没有走的动作感觉就是沿着道路在漂移,女主角也是一动不动的站那里。这样的游戏很没有乐趣,所以需要给这些游戏角色加入动作和表情,让人看去来他们是鲜活的,对这些角色进行一下简单的动画以及属性分析如下:

色狼大叔的动画:

1、 静止动画:游戏刚开始处于静止状态

2、 走路动画:沿着道路走

3、 死亡动画:当子弹击中血量消耗完时死亡消失

色狼大叔的属性:

1、 是否运动:色狼是否处于激活沿着道路行走

2、 是否死亡:是否被炮塔打死

3、 行走速度:不同色狼的行走速度不同

4、 色狼血量:不同色狼血量不同

5、 行走:沿着道路行走

女主角的动画:

2、 卖萌动画:不能像木头似的,就加点表情动作

3、 死亡动画:当纯洁值被色狼玷污光了就死亡了

女主角的属性:

1、 女主角贞洁值:相当于生命值

根据上面的分析我们把每个角色拆分成动画显示和业务属性逻辑两个部分,对色狼和女主角进行代码重构。

重构后大概结构如上图:

ActionSprite:属于CCSprite类,负责游戏角色精灵的动画显示,Luoli(萝莉)、DaShu(大叔)、JiaoShou(叫兽)等角色精灵均继承自ActionSprite,都属于动画显示类。

Luoli(萝莉):属ActionSprite的子类,负责女主角的动画效果展示。

DaShu(大叔):属ActionSprite的子类,负责大叔色狼的动画效果展示。

JiaoShou (叫兽):属ActionSprite的子类,负责叫兽色狼的动画效果展示。

Selang(色狼):属于CCNode类,负责色狼的行走、血量、速度、攻击等具体的业务,每个Selang都包含一个DaShu(大叔)或JiaoShou(叫兽)类的游戏精灵。并且具备最重要的行为实现沿着道路行走。

Girl(女孩):属于CCNode类,负责女主角的血量等具体的业务,每个Girl都包含一个Luoli类的游戏精灵。

l进行代码重构让色狼大叔和女主角生动鲜活起来

打开项目工程按照上面的思路重点对色狼和女主角的代码实现进行重构。

色狼大叔代码重构

第一步:

新建ActionSprite.h、ActionSprite.cpp类(角色动画类),这个类继承自CCSprite负责游戏角色的动画效果显示,色狼和女孩都会是这个类的子类。

ActionSprite.h代码:

//声明一个动作状态的枚举类型
typedef enum _ActionState{
    kActionStateNone = 0,无状态
    kActionStateIdle,0); line-height:1.5!important">静止状态
    kActionStateWalk,0); line-height:1.5!important">行走状态
    kActionStateDeath 死亡状态
}ActionState;

class ActionSprite: public cocos2d::CCSprite
{
public:
    ActionSprite(void);
    ~ActionSprite(void);
    静止
    void idle();
    死亡
    void death();
    行走
    void walk();
    价格
    CC_SYNTHESIZE(int,_price,Price);
    生命值
    CC_SYNTHESIZE(float,_hp,HP);
    静止状态动作
    CC_SYNTHESIZE_RETAIN(cocos2d::Action*,_idleAction,IdleAction);
    死亡状态动作
    CC_SYNTHESIZE_RETAIN(cocos2d::Action*,_deathAction,DeathAction);
    行走状态动作
    CC_SYNTHESIZE_RETAIN(cocos2d::Action*,_walkAction,WalkAction);
    当前动作状态
    CC_SYNTHESIZE(ActionState,_actionState,ActionState);
    行走速度
    CC_SYNTHESIZE(伤害值
    CC_SYNTHESIZE(金钱
    CC_SYNTHESIZE(是否有光环
    CC_SYNTHESIZE(bool,_halo,Halo);
    
};

ActionSprite.cpp代码:

ActionSprite::ActionSprite(void)
{
    _price=0;
    _idleAction=NULL;
    _walkAction=NULL;
    _deathAction=NULL;
}

ActionSprite::~ActionSprite(void)
{
    释放内存
    CC_SAFE_RELEASE_NULL(_idleAction);
    CC_SAFE_RELEASE_NULL(_deathAction);
    CC_SAFE_RELEASE_NULL(_walkAction);
}

设置精灵为静止状态
void ActionSprite::idle()
{
    if (_actionState != kActionStateIdle)
    {
        先停止所有动作
        this->stopAllActions();
        运行静止动作
        this->runAction(_idleAction);
        _actionState=kActionStateIdle;
    }
}

设置精灵为行走状态
void ActionSprite::walk()
{
    if (_actionState != kActionStateWalk)
    {
        运行行走动作
        this->runAction(_walkAction);
        _actionState=kActionStateWalk;
    }

}

设置精灵为死亡状态
void ActionSprite::death()
{
    先停止所有动作
    this->stopAllActions();
    this->runAction(_deathAction);
    _actionState=kActionStateDeath;
}

第二步:

素材准备,设计2张大叔不同动作的图片,交替显示模拟色狼行走动画,完成后把图片拷贝到Resources的iphonehd文件夹中,为了适应小分辨率的手机把这个2张图片按比例缩小一半并且拷贝到Resources的iphone文件夹中。

第三步:

新建DaShu.h、DaShu.cpp类(色狼大叔动画类),这个类继承自上面的ActionSprite负责游戏色狼大叔的动画效果显示。

DaShu.h:

class DaShu : public ActionSprite { public: DaShu(void); ~DaShu(void); CREATE_FUNC(DaShu); 初始化方法 bool init(); 设置光环,拥有光环的色狼生命值加倍 void setHalo(bool halo); };

DaShu.cpp:

bool DaShu::init() { bool bRet=false; do { CC_BREAK_IF(!ActionSprite::initWithFile("dashu_2.png")); 设置静止状态动作 Vector<SpriteFrame *> idleFrames(1); SpriteFrame *frame1=SpriteFrame::create(",Rect(60,128); line-height:1.5!important">83)); idleFrames.pushBack(frame1); Animation *idleAnimation=Animation::createWithSpriteFrames(idleFrames,255); line-height:1.5!important">float(6.0 / 12.0)); this->setIdleAction(CCRepeatForever::create(CCAnimate::create(idleAnimation))); int i=0; 设置行走状态动作 Vector<SpriteFrame *> walkFrames(2); for (i=0;i<2;i++) { SpriteFrame *frame2=SpriteFrame::create(CCString::createWithFormat(dashu_%d.png1)->getCString(),128); line-height:1.5!important">83)); walkFrames.pushBack(frame2); } Animation *walkAnimation=Animation::createWithSpriteFrames(walkFrames,255); line-height:1.5!important">this->setWalkAction(CCRepeatForever::create(CCAnimate::create(walkAnimation))); 设置死亡状态动作 Vector<SpriteFrame *> deathFrames(1); SpriteFrame *frame3=SpriteFrame::create(83)); deathFrames.pushBack(frame3); Animation *deathAnimation=Animation::createWithSpriteFrames(deathFrames,255); line-height:1.5!important">this->setDeathAction(Animate::create(deathAnimation)); 设置攻击值 this->setDamage(1); 设置行走速度 this->setWalkSpeed(0.4f); 设置生命值 this->setHP(18); 设置金钱数 this->setMoney(1.0f/10.0f); bRet=true; } while (0); return bRet; } 设置光环 void DaShu::setHalo(bool halo) { if (halo) { 拥有光环后生命值加4倍 float h=this->getHP()*4.0f; this->setHP(h); } }

第四步:

新建Selang.h、Selang.cpp类(色狼类),这个类继承自CCNode游戏场景中的每一个色狼都有这个类产生,它肯定包含一个ActionSprite的色狼动画类,并且之前在MainScene.cpp的update方法中实现的色狼沿路行走代码也将转移到这个类的update方法中。

Selang.h:

#include cocos2d.h"
#include Waypoint.hGameMediator.hActionSprite.h"
class Selang : public cocos2d::CCNode
{
public:
    Selang(void);
    ~Selang(根据提供的spriteIndex实例化成不同的色狼
    static Selang* nodeWithType(int spriteIndex);
    bool initWithType(int spriteIndex,255); line-height:1.5!important">bool halo);
    激活色狼
    void doActivate(float dt);
    获取精灵Rect
    virtual cocos2d::Rect getRect();
    设置精灵是否激活
    void setActive(bool active);
    是否死亡
    bool isDie;
    void update(float delta);
    色狼精灵
    CC_SYNTHESIZE_RETAIN(ActionSprite*,_mySprite,MySprite);

private:
    精灵序号,为每种精灵编一个序号
    int _spriteIndex;
    GameMediator* m;
    当前精灵的位置
    cocos2d::Point myPosition;
    走路速度
    float walkingSpeed;
    开始路点
    Waypoint *beginningWaypoint;
    结束路点
    Waypoint *destinationWaypoint;
    是否激活
    bool active; 
    色狼高度
    float myHeight;
    两个点的碰撞检测
    bool collisionWithCircle(cocos2d::Point circlePoint,255); line-height:1.5!important">float radius,cocos2d::Point circlePointTwo,255); line-height:1.5!important">float radiusTwo);
};

Selang.cpp:

根据提供的spriteIndex实例化成不同的色狼 Selang* Selang::nodeWithType(int spriteIndex) { Selang* pRet=new Selang(); bool b=if (pRet && pRet->initWithType(spriteIndex,b)) { pRet->autorelease(); return pRet; } else { delete pRet; pRet=NULL; return NULL; } } 初始化方法 bool Selang::initWithType(do { 色狼类型index _spriteIndex=spriteIndex; // m = GameMediator::sharedMediator(); 不激活 active=false; 行走速度 walkingSpeed=0.2f; ActionSprite* sprite=NULL; if (spriteIndex==1)如果类型是1初始化成大叔色狼 { sprite=DaShu::create(); sprite->setHalo(halo); 设置速度 walkingSpeed=sprite->getWalkSpeed(); } this->setMySprite(sprite); 添加精灵到当前Selang中 this->addChild(_mySprite); 计算当前色狼精灵1/2高 myHeight=sprite->getTextureRect().size.height/2.0f; 获得路点集合中的最后一个点 Waypoint *waypoint=(Waypoint*)m->getWayPoints().back(); 设置为色狼出发点 beginningWaypoint=waypoint; 获取出发点的下个点为色狼目标点 destinationWaypoint=waypoint->getNextWaypoint(); 获得出发点坐标 Point pos=waypoint->getMyPosition(); 对坐标进行校正提供半个身位高度 pos.add(Vec2(0,myHeight)); 记录位置坐标 myPosition=pos; 设置精灵的初始坐标 _mySprite->setPosition(pos); 设置初始不可见 this->setVisible(false); 把当前色狼添加到游戏的MainScene场景中显示 m->getNowScene()->addChild(this); 启动定时器 this->scheduleUpdate(); bRet=0); void Selang::doActivate(float dt) { 激活色狼 active=true; 设置色狼可见 true); } 获取精灵Rect Rect Selang::getRect() { Rect rect =Rect(_mySprite->getPosition().x - _mySprite->getContentSize().width * 0.5f,_mySprite->getPosition().y - _mySprite->getContentSize().height* getContentSize().width,_mySprite->getContentSize().height); return rect; } 设置精灵是否激活 void Selang::setActive(bool aactive) { active=aactive; void Selang::update(float delta) { if (!active) { return; } Point destinationPos=destinationWaypoint->getMyPosition(); 提升色狼半个身位 destinationPos.add(Vec2(是否拐弯 if (this->collisionWithCircle(myPosition,128); line-height:1.5!important">1,destinationPos,128); line-height:1.5!important">1)) { if (destinationWaypoint->getNextWaypoint()) { 设置新的出发点和目标点 beginningWaypoint=destinationWaypoint; destinationWaypoint=destinationWaypoint->getNextWaypoint(); } } Point targetPoint=destinationWaypoint->getMyPosition(); 提升色狼半个身位 targetPoint.add(Vec2(float movementSpeed=walkingSpeed; 计算目标点的向量 Point normalized=Point(targetPoint.x-myPosition.x,targetPoint.y-myPosition.y).getNormalized(); 根据速度和向量分别计算x,y方式上的偏移值 float ox=normalized.x * walkingSpeed; float oy=normalized.y *walkingSpeed; 更新色狼移动后的位置 myPosition = Point(myPosition.x + ox,myPosition.y +oy); _mySprite->setPosition(myPosition); } 两个点的碰撞检测 bool Selang::collisionWithCircle(cocos2d::Point circlePoint,255); line-height:1.5!important">float radiusTwo) { float xdif = circlePoint.x - circlePointTwo.x; float ydif = circlePoint.y - circlePointTwo.y; 计算两点间的距离 float distance = sqrt(xdif * xdif + ydif * ydif); if(distance <= radius + radiusTwo) { return true; } false; }

第五步:

如果运行一下那么上面的代码中Waypoint *waypoint=(Waypoint*)m->getWayPoints().back();这行应该会报错,因为GameMediator中没有提供getWayPoints()这个方法,所以我们要对GameMediator类进行修改加上这个方法,代码如下:

void GameMediator::setWayPoints(cocos2d::Vector<Waypoint*> wayPoints) { _wayPoints=wayPoints; } Vector<Waypoint*> GameMediator::getWayPoints() { return _wayPoints; }

第六步:

在MainScene的init方法中把路点集合通过setWayPoints方法赋值给GameMediator,这样在Selang.cpp中就可以取到路点集合了:

……
this->wayPositions.pushBack(waypoint12);
GameMediator::sharedMediator()->setWayPoints(wayPositions);
……

第七步:

测试这个Selang类具体效果,先给MainScene添加一个void startGame(float delta)的方法,用这个方法开始游戏。

开始游戏 void MainScene::startGame(实例化一个大叔类型的色狼 Selang* selang=Selang::nodeWithType(1); 激活这个色狼 selang->setActive(true); 设置色狼动画为行走动画 selang->getMySprite()->walk(); 取消定时器方法,保证startGame只执行一次 this->unschedule(schedule_selector(MainScene::startGame)); }

第八步:

我们在MainScene的init方法末尾处调用这个startGame的方法:

0.5秒后调用startGame方法
this->schedule(schedule_selector(MainScene::startGame),128); line-height:1.5!important">0.5f);

到这里,把第一篇中临时添加色狼的代码删除,就可以运行测试游戏了,会看到色狼大叔一扭一扭的沿着道路靠近女主角。效果非常好,我们成功的对色狼的代码进行了重构。

女主角代码重构

素材准备,设计4张萝莉不同动作的图片,交替显示模拟萝莉卖萌动画,完成后把图片拷贝到Resources的iphonehd文件夹中,为了适应小分辨率的手机把这个4张图片按比例缩小一半并且拷贝到Resources的iphone文件夹中。

新建Luoli.h、Luoli.cpp类(女主角动画类),这个类继承自上面的ActionSprite负责游戏女主角的动画效果显示。

Luoli.h:

class Luoli : public: Luoli(void); ~Luoli(void); CREATE_FUNC(Luoli); bool init(); };

Luoli.cpp:

bool Luoli::init() { girl1_1.png")); 100,128); line-height:1.5!important">126)); idleFrames.pushBack(frame1); Animation *idleAnimation=Animation::createWithSpriteFrames(idleFrames,0); line-height:1.5!important">设置行走状态动作 int i; Vector<SpriteFrame *> walkFrames(4); 4;i++) { SpriteFrame *frame1=SpriteFrame::create(CCString::createWithFormat(girl1_%d.png126)); walkFrames.pushBack(frame1); } Animation *walkAnimation=Animation::createWithSpriteFrames(walkFrames,255); line-height:1.5!important">this->setWalkAction(CCRepeatForever::create(CCAnimate::create(walkAnimation))); bRet=true; } return bRet; }

新建Girl.h、Girl.cpp类(女孩类),这个类继承自CCNode游戏场景中的女主角由这个类产生,它肯定包含一个ActionSprite的萝莉动画类。

Girl.h:

class Girl : public: Girl(void); ~Girl(void); 根据提供的type实例化成不同的女主角 static Girl* nodeWithType(int type); bool initWithLocation(cocos2d::Point location); 获取精灵Rect cocos2d::Rect getRect(); 萝莉精灵 CC_SYNTHESIZE_RETAIN(ActionSprite*,MySprite); };

Girl.cpp:

根据提供的type实例化成不同的女主角 Girl* Girl::nodeWithType(int type) { Girl* pRet=new Girl(); GameMediator* m = GameMediator::sharedMediator(); Waypoint *waypoint=(Waypoint*)m->getWayPoints().front(); Point pos=waypoint->getMyPosition(); if (pRet && pRet->initWithLocation(pos)) { pRet->autorelease(); false; } } bool Girl::initWithLocation(cocos2d::Point location) { 实例化一个萝莉 ActionSprite *sprite= Luoli::create(); 添加精灵到当前Gril中 this->addChild(sprite); 设置为静止 sprite->idle(); 计算当前萝莉精灵1/2高 int myHeight=sprite->getTextureRect().size.height/对坐标进行校正提供半个身位高度 location.add(Vec2(setPosition(location); 把当前女主角添加到游戏的MainScene场景中显示 GameMediator* m = GameMediator::sharedMediator(); m->getNowScene()->addChild(this,128); line-height:1.5!important">10000); bRet=return bRet; } Rect Girl::getRect() { Rect rect = Rect(_mySprite->getPosition().x - _mySprite->getContentSize().width * 0.5f+20,_mySprite->getContentSize().height-40); return rect; }

在MainScene的 startGame(float delta)的方法中加上初始化女主角的代码。

……
初始一个女主角
    Girl* girl=Girl::nodeWithType(设置女主角动画为卖萌动画
    girl->getMySprite()->walk();
    this->unschedule(schedule_selector(MainScene::startGame));

到这里,把第一篇中临时添加女主角的代码删除,就可以运行测试游戏了,本篇的任务到此为止,本篇完成后android真机的运行效果如下:

结束语:

这个塔防游戏系列已经写了3篇了,到现在为止还没有出现炮塔,说好的炮塔呢?请期待下一篇炮塔姑娘的保护神~

作者交流QQ:2303452599

邮箱:mymoney1001@126.com

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


    本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
 下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是