前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >cocos2d-x for android:士兵听我的命令移动

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

作者头像
全栈程序员站长
发布2022-07-05 09:19:40
5100
发布2022-07-05 09:19:40
举报
文章被收录于专栏:全栈程序员必看

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

开始

本篇要点

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

涉及到的要学的学习点:

  1. 角色移动点击由此进入–>cocos2d-x for android:SimpleGame分析
  2. 播放动画点击由此进入–>cocos2d-x for android:CCSprite 精灵动画­

角色缓存

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

cocos2d-x for android:士兵听我的命令移动
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); }

全部代码如下:

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:士兵听我的命令移动
cocos2d-x for android:士兵听我的命令移动

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

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

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021年8月2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 开始
    • 角色缓存
      • 动画缓存
        • 触摸精灵到我指定的移动地点
          • 动作移动
            • 注意点
            相关产品与服务
            批量计算
            批量计算(BatchCompute,Batch)是为有大数据计算业务的企业、科研单位等提供高性价比且易用的计算服务。批量计算 Batch 可以根据用户提供的批处理规模,智能地管理作业和调动其所需的最佳资源。有了 Batch 的帮助,您可以将精力集中在如何分析和处理数据结果上。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档