cocos2d-x for android:士兵听我的命令移动

cocos2d-x for android:士兵听我的命令移动

上一篇文章讲述了利用cocos2d-x构建精灵的动画效果,今天打算以此为引子,创建一个在移动时同时指挥角色到我手指触摸的移动地点,那么就开始吧。

开始

本篇要点

  1. 角色(Sprite)缓存
  2. 动画(Animation)缓存
  3. 触摸(Touch)精灵到我指定的移动地点
  4. 动作(Action)移动和切换

角色缓存

角色缓存使用CCSpriteFrameCache ,配合CCSpriteBatchNode将图片*.plist和*.png 加载进内存,方便以后调用。

cocos2d-x for android:士兵听我的命令移动 

以上为动作序列图,图片名称为:sg.png.图片来源于博客园:nowpaper.

角色缓存代码如下:

CCSpriteFrameCache* cache=CCSpriteFrameCache::sharedSpriteFrameCache();

cache->addSpriteFramesWithFile(

sg.plist
);

    sprite=CCSprite::createWithSpriteFrameName(

A1_6.png
);

    sprite->setPosition(ccp(size.width-sprite->getContentSize().width,size.height/
2));

    spriteBatchNode=CCSpriteBatchNode::create(

sg.png
);

    spriteBatchNode->addChild(sprite);

     addChild(spriteBatchNode);

 以上代码,CCSpriteFrameCache负责加载sg.plist,CCSpriteBatchNode负责加载sg.png,然后创建一个精灵指定初始化位置和精灵纹理,并添加进CCSpriteBatchNode。通过上面的代码即可以将一个plist序列图加载进缓存了,你要做的就是将这些缓存的数据拿出来操作它。

 

动画缓存

上面己经将数据加载进缓存了,可以使用其中的那些节点来制作动画缓存了。

缓存动画使用 CCAnimationCache,该动画同样需要使用到plist文件,代码如下

 

 

CCAnimationCache *animCache = CCAnimationCache::sharedAnimationCache();

    animCache->addAnimationsWithFile(

sg.plist
);

 在将plist文件添加完后,即可以通过动画Animation将每一个动画的Animation添加进CCAnimationCache了,这里我写了一个函数,代码见下方

 

CCAction* HelloWorld::createAction(
int begin,
int end,
char* cacheActionName,CCPoint point){

    CCAnimationCache *animCache = CCAnimationCache::sharedAnimationCache();//得到一个缓存对象

    CCArray *array = CCArray::createWithCapacity(end-begin);

    
char name[
20];

    
for(
int i = begin ;i<end;i++){

        sprintf(name,

A1_%d.png
,i);

        CCSpriteFrame* frame =cache->spriteFrameByName(name);

        array->addObject(frame);

    }//以上创建一个动作序列集合

    CCAnimation *plistAnimation = CCAnimation::createWithSpriteFrames(array,
0.2f);//通过动作序列集合创建animation

     animCache->addAnimation(plistAnimation, cacheActionName);//添加进缓存并指定缓存名称

    array->removeAllObjects();

    CCAnimation *animation = animCache->animationByName(cacheActionName);//通过缓存名称得到一个动画

    animation->setRestoreOriginalFrame(
true);

    CCAnimate *ani=CCAnimate::create(animation);

    CCActionInterval* plistSeq=(CCActionInterval*)(CCSequence::create(ani,

        CCFlipX::create(point.x>
0
true:
false),

        ani->copy()->autorelease(),

        NULL

    ));

    
return CCRepeatForever::create(plistSeq);//创建动画并返回Action

}

 

触摸精灵到我指定的移动地点

设定好让程序允许Touch之后,在回调函数ccTouchesEnded 里面通过捕获触摸位置指定精灵移动,代码见下方

 

CCTouch* touch=(CCTouch*)(touches->anyObject());  

     CCPoint location = touch ->getLocation();

     
float offX=location.x-sprite->getPosition().x; 

     
float offY=location.y-sprite->getPosition().y; 

     

     walkAction=createAction(
4,
6,

move
,ccp(offX,offY));

     

     sprite->setFlipX(offX>
0?
true:
false);

    

     
float realX=offY/offX;

      CCPoint realDeast =ccp(location.x,location.y);

      CCActionInterval *actionTo=CCMoveTo::create(
2.2f,realDeast);

    CCAction *moveToAction=CCSequence::create(

        actionTo,

        CCCallFunc::create(
this,callfunc_selector(HelloWorld::moveDone)),

        NULL

    );

  sprite->runAction(moveToAction);

ok了,精灵移动了,但你会发现,你想让精灵移动的时候不是一整张图片移动,而是边移动边两只脚在走路的移动,就像是我们人类一样,是走着过去的,而不是幽灵飘过去的,那么,我们要做些什么呢?

动作移动

其实,很简单 ,只要记住要精灵移动的时候即:MoveTo时,同时再让精灵执行一个动作即walk的动作,代码如下:

sprite->stopAllActions();  //因为Touch是无时无刻的,所以每当touch一次即停止当前的action

walkAction=createAction(
4,
6,

move
,ccp(offX,offY));//构建一个walk的action

sprite->runAction(walkAction);//播放走的action

sprite->runAction(moveToAction);//播放moveTo的action

 当到达指定地点时,希望让角色以站立的姿势站在屏幕上,这时我们需要在moveTo的callback函数里面调用,让其停止当前action,并重新执行站立的action,代码如下:



void HelloWorld::moveDone(){

    sprite->stopAllActions();

    CCAnimationCache *animCache = CCAnimationCache::sharedAnimationCache();

    CCAnimation *standAnimation = animCache->animationByName(

stand
);

        standAnimation->setRestoreOriginalFrame(
true);

        CCAnimate *standAni=CCAnimate::create(standAnimation);

        CCActionInterval* s=(CCActionInterval*)(CCSequence::create(standAni,

            standAni->copy()->autorelease(),

            NULL

        ));

        CCAction *frameAction=CCRepeatForever::create(s);

    

    sprite->runAction(frameAction);

}

 

全部代码如下:

cocos2d-x for android:士兵听我的命令移动
ExpandedBlockStart.gif
View Code 

  1 
using 
namespace cocos2d;


  2 
using 
namespace CocosDenshion;


  3 


  4 
#define  LOG_TAG    “main”                                                                                                              ||-   function


  5 
#define  LOGD(…)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)  


  6 


  7 CCScene* HelloWorld::scene()


  8 {


  9     
//
 ‘scene’ is an autorelease object


 10 
    CCScene *scene = CCScene::create();


 11     


 12     
//
 ‘layer’ is an autorelease object


 13 
    HelloWorld *layer = HelloWorld::create();


 14 


 15     
//
 add layer as a child to scene


 16 
    scene->addChild(layer);


 17 


 18     
//
 return the scene


 19 
    
return scene;


 20 }


 21 


 22 
//
 on “init” you need to initialize your instance


 23 

bool HelloWorld::init()


 24 {


 25     
//

 26 
    
//
 1. super init first


 27 
    
if ( !CCLayer::init() )


 28     {


 29         
return 
false;


 30     }


 31 


 32     
this->setTouchEnabled(
true);


 33 


 34     CCSize size = CCDirector::sharedDirector()->getWinSize();


 35     CCAnimationCache::purgeSharedAnimationCache();


 36     CCAnimationCache *animCache = CCAnimationCache::sharedAnimationCache();


 37 


 38     animCache->addAnimationsWithFile(

sg.plist
);


 39     


 40 


 41 


 42     cache=CCSpriteFrameCache::sharedSpriteFrameCache();


 43     cache->addSpriteFramesWithFile(

sg.plist
);


 44 


 45     sprite=CCSprite::createWithSpriteFrameName(

A1_6.png
);


 46     sprite->setPosition(ccp(size.width-sprite->getContentSize().width,size.height/
2));


 47     spriteBatchNode=CCSpriteBatchNode::create(

sg.png
);


 48     spriteBatchNode->addChild(sprite);


 49      addChild(spriteBatchNode);


 50 


 51     cache->addSpriteFramesWithFile(

hero.plist
);


 52     hero=CCSprite::createWithSpriteFrameName(

Hero02_0.png
);


 53     hero->setPosition(ccp(hero->getContentSize().width,size.height/
2));


 54     heroBatchNode=CCSpriteBatchNode::create(

hero.png
);


 55     heroBatchNode ->addChild(hero);


 56     hero->setFlipX(
true);


 57     


 58     addChild(heroBatchNode);


 59     


 60 


 61 


 62     attackArray =CCArray::createWithCapacity(
4);


 63     
char attackName[
20];


 64     
for(
int i=
0;i<
4;i++){


 65         sprintf(attackName,


 66 

A1_%d.png
,i);


 67         CCSpriteFrame* frame =cache->spriteFrameByName(attackName);


 68         attackArray->addObject(frame);


 69     }


 70     CCAnimation *attackAnimation =CCAnimation::createWithSpriteFrames(attackArray,
0.2f);


 71     CCAnimationCache::sharedAnimationCache()->addAnimation(attackAnimation, 

attack
);


 72     


 73     attackArray->removeAllObjects();


 74 


 75     


 76 


 77     standArray= CCArray::createWithCapacity(
1);


 78     
char standName[
20];


 79         
for(
int i=
6;i<
7;i++){


 80             sprintf(standName,


 81 

A1_%d.png
,i);


 82             CCSpriteFrame* frame =cache->spriteFrameByName(standName);


 83             standArray->addObject(frame);


 84         }


 85         CCAnimation *standAnimation =CCAnimation::createWithSpriteFrames(standArray,
0.2f);


 86         CCAnimationCache::sharedAnimationCache()->addAnimation(standAnimation, 

stand
);


 87         standArray->removeAllObjects();


 88     


 89     


 90     
return 
true;


 91 }


 92 


 93 
void HelloWorld::moveDone(){


 94     
//

 95 
    sprite->stopAllActions();


 96     CCAnimationCache *animCache = CCAnimationCache::sharedAnimationCache();


 97 


 98 


 99     CCAnimation *standAnimation = animCache->animationByName(

stand
);


100         standAnimation->setRestoreOriginalFrame(
true);


101         CCAnimate *standAni=CCAnimate::create(standAnimation);


102         CCActionInterval* s=(CCActionInterval*)(CCSequence::create(standAni,


103             standAni->copy()->autorelease(),


104             NULL


105         ));


106         CCAction *frameAction=CCRepeatForever::create(s);


107 


108     


109     sprite->runAction(frameAction);


110 }


111 


112 CCAction* HelloWorld::createAction(
int begin,
int end,
char* cacheActionName,CCPoint point){


113     CCAnimationCache *animCache = CCAnimationCache::sharedAnimationCache();


114     CCArray *array = CCArray::createWithCapacity(end-begin);


115 


116     
char name[
20];


117     
for(
int i = begin ;i<end;i++){


118         sprintf(name,

A1_%d.png
,i);


119         CCSpriteFrame* frame =cache->spriteFrameByName(name);


120         array->addObject(frame);


121     }


122 


123     CCAnimation *plistAnimation = CCAnimation::createWithSpriteFrames(array,
0.2f);


124     CCAnimationCache::sharedAnimationCache()->addAnimation(plistAnimation, cacheActionName);


125 


126     array->removeAllObjects();


127 


128     CCAnimation *animation = animCache->animationByName(cacheActionName);


129     animation->setRestoreOriginalFrame(
true);


130     CCAnimate *ani=CCAnimate::create(animation);


131     CCActionInterval* plistSeq=(CCActionInterval*)(CCSequence::create(ani,


132         CCFlipX::create(point.x>
0
true:
false),


133         ani->copy()->autorelease(),


134         NULL


135     ));


136     
return CCRepeatForever::create(plistSeq);


137 }


138 


139 


140 
void HelloWorld::registerWithTouchDispatcher(){                                                                                    


141     CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(
this,
0);


142 }


143 
void HelloWorld::ccTouchesEnded(cocos2d::CCSet * touches,cocos2d::CCEvent * 
event){


144 


145     sprite->stopAllActions();


146     


147     


148     CCTouch* touch=(CCTouch*)(touches->anyObject());  


149      CCPoint location = touch ->getLocation();


150      
float offX=location.x-sprite->getPosition().x; 


151      
float offY=location.y-sprite->getPosition().y; 


152      


153      walkAction=createAction(
4,
6,

move
,ccp(offX,offY));


154      


155      sprite->setFlipX(offX>
0?
true:
false);


156 


157     


158      
float realX=offY/offX;


159       CCPoint realDeast =ccp(location.x,location.y);


160       CCActionInterval *actionTo=CCMoveTo::create(
2.2f,realDeast);


161     CCAction *moveToAction=CCSequence::create(


162         actionTo,


163         CCCallFunc::create(
this,callfunc_selector(HelloWorld::moveDone)),


164         NULL


165     );


166 


167   sprite->runAction(walkAction);


168   sprite->runAction(moveToAction);


169 }


170 


171 


172 
void HelloWorld::menuCloseCallback(CCObject* pSender)


173 {


174     CCDirector::sharedDirector()->end();


175 


176 
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)


177     exit(
0);


178 
#endif


179

 

 

 注意点

CCAnimation *attackAnimation =CCAnimation::createWithSpriteFrames(attackArray,0.2f); 与

CCAnimation *attackAnimation =CCAnimation::createWithSpriteFrames(attackArray);因为站立action才一帧,所以我不打算指定时间,但是如果不指定时间,它无法成功切换action,这个目前还不清楚是为什么。

 

 

 

 

 最后实现的效果如下:

cocos2d-x for android:士兵听我的命令移动 

由于是在ubuntu下开发,好像没有什么抓取屏幕gif 图片的软件可用,简单截一屏!!!

代码没有做任何的处理,很多多余的代码,做个DEMO可以看看就行!!!

代码下载:https://github.com/terryyhl/SpriteAnimation.git 
 

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

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/110285.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • ci 框架中defined(‘BASEPATH’) OR exit(‘No direct script access allowed’);

    ci 框架中defined(‘BASEPATH’) OR exit(‘No direct script access allowed’);

  • 安全帽识别算法

    安全帽识别算法应用背景:安全帽作为一种最常见和实用的个人防护用具,能够有效地防止和减轻外来危险源对头部的伤害。但在现场操作过程中,安全帽的佩戴很容易人为忽略,引发了不少人身伤害事故。为了保证工作人员都能在作业中佩戴安全帽,保障作业人员安全,安全帽识别算法系统应运而生。关键字:安全帽识别算法安全帽识别算法技术原理安全帽识别算法采用最新AI人工智能深度学习技术,基于计算机智能视频物体识别算法,且通过规模化的安全帽数据识别训练,赋予监控系统智能识别能力,从而准确判断识别场景内的作业人员是否佩戴安全帽,若检.

  • 软件版本号命名规范1.0.0.1什么意思_医疗器械软件版本号命名规范

    软件版本号命名规范1.0.0.1什么意思_医疗器械软件版本号命名规范软件版本号命名规范总原则标准的版本号必须采用XYZ的格式,并且X、Y和Z为非负的整数,禁止在数字前方补零版本是严格递增的,此处是:16.2.0->16.3.0->16.3.1在发布重要版本时,可以发布alpha,rc等先行版本alpha和rc等修饰版本的关键字后面可以带上次数和meta信息版本的优先层级指的是不同版本在排序时如何比较。判断优先层级时,必…

  • Mybatis源码:@MapperScan解析过程

    Mybatis源码:@MapperScan解析过程目录0.说明1.@MapperScan2.MapperScannerRegister3.ClassPathMapperScanner4.MapperFactoryBean0.说明mybatis构建过程主要包括:解析mybatis配置文件,构造Configuration配置类对象和SqlSessionFactory; 利用@MapperScan注册BeanDe…

  • navicat15 for mysql激活码【2021免费激活】「建议收藏」

    (navicat15 for mysql激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~https://javaforall.cn/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~14…

  • docker 搭建drone + gitee 的CI/CD

    docker 搭建drone + gitee 的CI/CD准备创建OAuth应用程序创建一个GiteeOAuth应用程序。ConsumerKey和ConsumerSecret用于授权访问Gitee资源。授权回调URL必须与以下格式和路径匹配,并且必须使用您的确切服务器方案和主机。创建共享密钥创建一个共享密钥来验证跑步者和您的中央无人机服务器之间的通信。您可以使用openssl生成共享密钥:$opensslrand-hex16bea26a2221fd8090ea38720fc445ec.

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号