哈,山寨又来了。这次用到是pop cap的宝石迷阵资源。写了个简单的玩法,呵呵,其实是因为算法比较简单。还是记录一下。

先下载pop cap的Bejeweled,找到资源。巧妇难为无米之炊,有了资源,就好动手鸟。

我选择了其中的一部分资源,练练手,完全仿出来就算了吧。pop cap的游戏就是好啊,资源不加密的,太方便了,这里我们用到Audio和Graphics里的部分资源。

既然是宝石消除类游戏,当然宝石就是猪脚了。宝石消失,宝石移动,宝石的颜色,这些都需要一堆数据。所以我们这里继承CCSprite创建宝石类CCBlock:

#pragma once
#include "Defines.h"
#include "cocos2d.h"USING_NS_CC;class CCBlock : public cocos2d::CCSprite
{
public:void removeSelf(){this->removeFromParentAndCleanup(true);}public:CC_SYNTHESIZE(bool, _willRemove, WillRemove);CC_SYNTHESIZE(int, _moveStep, MoveStep);CC_SYNTHESIZE(JewelType, _type, Type);CREATE_FUNC(CCBlock);bool init();
};

在cpp中其实就是初始化

#include "CCBlock.h"bool CCBlock::init()
{bool bRet = false;do {int type = rand()%7 + 1;CCString* s = CCString::createWithFormat("Jewel%d.png", type);CC_BREAK_IF(!CCSprite::initWithFile(s->getCString()));this->setWillRemove(false);this->setMoveStep(0);this->setType((JewelType)type);bRet = true;} while (0);return bRet;
}

宝石类CCBlock中其实就包含JewelType宝石的种类,宝石是否要消除_willRemove,宝石要移动的步数_moveStep几个属性,我这里初始化种类是随机的。

然后就是简单的开始游戏场景,用了pop cap的资源和自己在网上搜到的图片PS了一下拼装的,比较简陋。

就一个简单的动态图,和play按钮。

按下play,“go”直接到主场景游戏界面吧。

其实也很简陋,哈哈,凑合看吧。

#include "GameLayer.h"
#include "CCBlock.h"
#include "TitleLayer.h"
#include "SimpleAudioEngine.h"using namespace cocos2d;
using namespace CocosDenshion;CCScene* GameLayer::scene()
{CCScene* scene = NULL;do {scene = CCScene::create();CC_BREAK_IF(!scene);GameLayer *layer = GameLayer::create();CC_BREAK_IF(!layer);scene->addChild(layer);} while (0);return scene;
}bool GameLayer::init()
{bool bRet = false;do {CC_BREAK_IF(! CCLayer::init());this->setTouchEnabled(true);//载入音效SimpleAudioEngine::sharedEngine()->preloadBackgroundMusic("Audio/BGM/classic.mp3");SimpleAudioEngine::sharedEngine()->preloadEffect("Audio/SE/combo.mp3");SimpleAudioEngine::sharedEngine()->preloadEffect("Audio/SE/voice_good.mp3");SimpleAudioEngine::sharedEngine()->preloadEffect("Audio/SE/voice_excellent.mp3");SimpleAudioEngine::sharedEngine()->preloadEffect("Audio/SE/voice_awesome.mp3");SimpleAudioEngine::sharedEngine()->preloadEffect("Audio/SE/voice_spectacular.mp3");SimpleAudioEngine::sharedEngine()->preloadEffect("Audio/SE/voice_extraordinary.mp3");SimpleAudioEngine::sharedEngine()->preloadEffect("Audio/SE/voice_unbelievable.mp3");SimpleAudioEngine::sharedEngine()->preloadEffect("Audio/SE/levelcomplete.mp3");SimpleAudioEngine::sharedEngine()->preloadEffect("Audio/SE/gameover.mp3");SimpleAudioEngine::sharedEngine()->playBackgroundMusic("Audio/BGM/classic.mp3", true);blood = 0.0f;score = 60;level++;levelRatio = 1.8f - level * 0.2f;  loadTexture();initBlocks();bCanTouch = true;scheduleUpdate();schedule(SEL_SCHEDULE(&GameLayer::updateBlood), 1.0f);bRet = true;} while (0);return bRet;
}void GameLayer::update(float dt)
{if(blood >=1.0f){completeSprite->setVisible(true);CCMoveBy *moveBy = CCMoveBy::create(1.0f, ccp(0, 300));CCFadeOut *fadeOut = CCFadeOut::create(1.0f);score = 60;blood = 0.0f;SimpleAudioEngine::sharedEngine()->stopAllEffects();SimpleAudioEngine::sharedEngine()->playEffect("Audio/SE/levelcomplete.mp3");CCCallFunc* completeCallBack = CCCallFunc::create(this, callfunc_selector(GameLayer::restartLevel));completeSprite->runAction(CCSequence::create(CCSpawn::create(moveBy, fadeOut, NULL), completeCallBack, NULL));}
}void GameLayer::initBlocks()  //初始化宝石的tag和位置
{srand(time(NULL));for(int i=0; i<BLOCKHEIGHT; i++)for(int j=0; j<BLOCKWIDTH; j++){CCBlock* block = CCBlock::create();block->setPosition(ccp(313 + 60*j, 104 + 60*i));block->setTag(1000 + (i+1)*8 + j +1);block->retain();this->addChild(block, 10);BlockArr->addObject(block);}
}void GameLayer::loadTexture()  //ui方面的初始化和时间处理
{CCSize winSize = CCDirector::sharedDirector()->getWinSize();CCSprite *bg = CCSprite::create(CCString::createWithFormat("Backgrounds/back_%d.jpg", rand()%19 + 1)->getCString());bg->setPosition(ccp(winSize.width * 0.5f, winSize.height * 0.5f));this->addChild(bg, -11);CCSprite *box = CCSprite::create("UI/box.png");box->setPosition(ccp(winSize.width * 0.5f + 120, winSize.height * 0.5f));this->addChild(box, -9);hpSprite = CCSprite::create("UI/bottombar_blue.png");  hpSprite->setAnchorPoint(ccp(0, 0));hpSprite->setPosition(ccp(309, 49));hpSprite->setScaleX(blood);this->addChild(hpSprite, -10);BlockArr = CCArray::create();BlockArr->retain();completeSprite = CCSprite::create("UI/levelcomplete.png");completeSprite->setPosition(ccp(523, 200));this->addChild(completeSprite, 3);completeSprite->setVisible(false);CCSprite* menuUI = CCSprite::create("UI/window_score.png");menuUI->setPosition(ccp(120, 438));this->addChild(menuUI, -1);labelAtlas = CCLabelAtlas::create("60", "fps_images.png", 12, 32, '.');labelAtlas->setPosition(ccp(105, 500));this->addChild(labelAtlas, 1);labelLevel = CCLabelAtlas::create("1", "fps_images.png", 12, 32, '.');labelLevel->setPosition(ccp(113, 468));labelLevel->setString(CCString::createWithFormat("%d", level)->getCString());this->addChild(labelLevel, 1);CCSprite* menuBox = CCSprite::create("UI/menu_box_added.png");menuBox->setPosition(ccp(120, 130));this->addChild(menuBox, -2);CCMenuItemImage *menuItem = CCMenuItemImage::create("UI/menu_d.png","UI/menu_d.png",this,menu_selector(GameLayer::menuCallBack));CCMenu *menu = CCMenu::createWithItem(menuItem);menu->setPosition(ccp(120, 130));this->addChild(menu, -1);
}void GameLayer::ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent){}void GameLayer::ccTouchesEnded(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent){//每次点击都判断是那个宝石被击中,然后做updateState和updateMoveStep的操作if(bCanTouch){CCTouch* pTouch = (CCTouch*)pTouches->anyObject();CCPoint pos = CCDirector::sharedDirector()->convertToGL(pTouch->getLocationInView());int x = (pos.x - 283) / 60 + 1;int y = (pos.y - 74) / 60 + 1;if(x >= 1 && y >= 1 && x <= 8 && y <= 8){bCanTouch = false;CCBlock *block = getBlockByTag(1000 + y*8 + x);if(block){JewelType type = block->getType();removeTotal = 0;updateState(x, y, type);updateMoveStep();}}}
}void GameLayer::updateState(int x, int y, JewelType type)  //递归遍历周边相同颜色宝石,找到要消失的宝石
{if(x<=0 || x>=9 || y<=0 || y>=9)return;CCBlock *block = getBlockByTag(1000+8*y+x);if(block->getWillRemove())return;if(block && block->getType() == type){block->setWillRemove(true);removeTotal ++;updateState(x-1, y, type);updateState(x+1, y, type);updateState(x, y-1, type);updateState(x, y+1, type);}
}void GameLayer::updateMoveStep()  //根据要消失的宝石计算每个宝石要移动的步数step
{for(int i=1; i<9; i++){int step = 0;for(int j=1; j<9; j++){CCBlock *block = getBlockByTag(1000+j*8+i);CC_BREAK_IF(!block);if(block->getWillRemove()){step++;}block->setMoveStep(step);}}int newStep[8] = {0}; //需新建的个数for(int i=1065; i<1073; i++){CCBlock *block = getBlockByTag(i);CC_BREAK_IF(!block);newStep[i-1065] = block->getMoveStep();}for(int i=1009; i<1073; i++){CCBlock* block = getBlockByTag(i);if(block->getWillRemove()){CCScaleTo* scaleTo1 = CCScaleTo::create(0.04f, 1.1f);CCScaleTo* scaleTo2 = CCScaleTo::create(0.12f, 0.5f);block->runAction(CCSequence::create(scaleTo1, scaleTo2, CCCallFuncN::create(this, callfuncN_selector(GameLayer::deleteBlock)),NULL));}else if(block->getMoveStep())block->setTag(block->getTag()-block->getMoveStep()*8);}SimpleAudioEngine::sharedEngine()->playEffect("Audio/SE/combo.mp3");if(removeTotal >= 4 && removeTotal <5)SimpleAudioEngine::sharedEngine()->playEffect("Audio/SE/voice_good.mp3");else if(removeTotal >= 5 && removeTotal <6)SimpleAudioEngine::sharedEngine()->playEffect("Audio/SE/voice_excellent.mp3");else if(removeTotal >= 6 && removeTotal <7)SimpleAudioEngine::sharedEngine()->playEffect("Audio/SE/voice_awesome.mp3");else if(removeTotal >= 7 && removeTotal <8)SimpleAudioEngine::sharedEngine()->playEffect("Audio/SE/voice_spectacular.mp3");else if(removeTotal >= 8 && removeTotal <9)SimpleAudioEngine::sharedEngine()->playEffect("Audio/SE/voice_extraordinary.mp3");else if(removeTotal >= 9)SimpleAudioEngine::sharedEngine()->playEffect("Audio/SE/voice_unbelievable.mp3");//分数变化switch(removeTotal){case 1:blood -= 0.03f;break;case 2:blood += 0.01f * levelRatio;break;case 3:blood += 0.02f * levelRatio;break;case 4:createMsg(1);blood += 0.03f * levelRatio;break;case 5:createMsg(2);blood += 0.04f * levelRatio;break;case 6:createMsg(3);blood += 0.05f * levelRatio;break;case 7:createMsg(4);blood += 0.06f * levelRatio;break;case 8:createMsg(5);blood += 0.07f * levelRatio;break;case 9:createMsg(6);blood += 0.08f * levelRatio;break;default:createMsg(6);blood += 0.09f * levelRatio;break;}if(blood < 0)blood = 0;hpSprite->setScaleX(blood);for(int i=0; i<8; i++)  //生成新的宝石类,并移动到正确的位置{for(int j=newStep[i]; j>0; j--){CCBlock* block = CCBlock::create();block->setPosition(ccp(313 + 60*i, 104 + 420 + 60*j));block->setMoveStep(newStep[i]);block->setWillRemove(false);block->retain();this->addChild(block, 10);BlockArr->addObject(block);}}hpSprite->setScaleX(blood);CCString* scoreStr = CCString::createWithFormat("%d", score);labelAtlas->setString(scoreStr->getCString());CCObject* pObj;int maxStep = 0;CCARRAY_FOREACH(BlockArr, pObj){CCBlock* block = (CCBlock*)pObj;if(int step = block->getMoveStep()){if(step > maxStep)maxStep = step;CCDelayTime* delayTime = CCDelayTime::create(0.2f);CCMoveBy* moveBy = CCMoveBy::create(0.1f * step, ccp(0, -step * 60));block->runAction(CCSequence::create(delayTime, moveBy, NULL));}}this->runAction(CCSequence::create(CCDelayTime::create(maxStep * 0.1f + 0.21f),CCCallFunc::create(this, callfunc_selector(GameLayer::touchCallBack)), NULL));
}void GameLayer::touchCallBack()  //每次消除后,重新设定宝石的tag等状态
{CCObject* pObj;    CCARRAY_FOREACH(BlockArr, pObj){CCBlock* block = (CCBlock*)pObj;CCPoint pos = block->getPosition();    int x = (pos.x - 283) / 60 + 1;int y = (pos.y - 74) / 60 + 1;block->setMoveStep(0);block->setTag(1000 + y*8 + x);block->setWillRemove(false);}bCanTouch = true;
}void GameLayer::menuCallBack(CCObject *pObj)
{CCDirector::sharedDirector()->replaceScene(CCTransitionFade::create(1.0f, TitleLayer::scene()));level = 0;
}void GameLayer::updateBlood(float dt)
{score -= 1;if(score <=0){score = 0;if(blood < 1.0f){this->unschedule(schedule_selector(GameLayer::updateBlood));level = 0;SimpleAudioEngine::sharedEngine()->stopAllEffects();SimpleAudioEngine::sharedEngine()->playEffect("Audio/SE/gameover.mp3");CCSprite *gameOver = CCSprite::create("UI/gameover.png");gameOver->setPosition(ccp(523, 200));this->addChild(gameOver, 1);CCMoveBy *moveBy = CCMoveBy::create(1.0f, ccp(0, 300));CCFadeOut *fadeOut = CCFadeOut::create(1.0f);CCSpawn *spn = CCSpawn::create(moveBy, fadeOut, NULL);CCDelayTime* delayTime = CCDelayTime::create(0.2f);CCCallFunc* callBack = CCCallFunc::create(this, callfunc_selector(GameLayer::restartLevel));gameOver->runAction(CCSequence::create(spn, delayTime, callBack, NULL));         }}labelAtlas->setString(CCString::createWithFormat("%d", score)->getCString());
}void GameLayer::restartLevel()
{if(level == 0)CCDirector::sharedDirector()->replaceScene(CCTransitionFade::create(1.0f, TitleLayer::scene()));elseCCDirector::sharedDirector()->replaceScene(CCTransitionFade::create(1.0f, GameLayer::scene()));
}void GameLayer::createMsg(int msg)  //good,excellent等信息的处理。
{CCSprite* msgSprite = CCSprite::create();switch(msg){case 1:msgSprite = CCSprite::create("Complements/good.png");break;case 2:msgSprite = CCSprite::create("Complements/excellent.png");break;case 3:msgSprite = CCSprite::create("Complements/awesome.png");break;case 4:msgSprite = CCSprite::create("Complements/spectacular.png");break;case 5:msgSprite = CCSprite::create("Complements/extraordinary.png");break;case 6:msgSprite = CCSprite::create("Complements/unbelievable.png");break;default:break;}msgSprite->setPosition(ccp(120, 200));msgSprite->setScale(0.2f);this->addChild(msgSprite, 1);CCMoveBy *moveBy = CCMoveBy::create(1.0f, ccp(0, 200));CCFadeOut *fadeOut = CCFadeOut::create(1.0f);CCSpawn *spn = CCSpawn::create(moveBy, fadeOut, NULL);msgSprite->runAction(CCSequence::create(spn, CCCallFuncN::create(this, callfuncN_selector(GameLayer::deleteSelf)),NULL));}void GameLayer::deleteSelf(CCNode* node)
{CCSprite* s = (CCSprite*)node;s->removeFromParentAndCleanup(true);
}void GameLayer::deleteBlock(CCNode* node)
{CCSprite* s = (CCSprite*)node;s->removeFromParentAndCleanup(true);CCBlock* block = (CCBlock*)node;BlockArr->removeObject(block, true);
}CCBlock* GameLayer::getBlockByTag(int tag)
{if(BlockArr->count()==0)return NULL;CCObject *pObj;CCARRAY_FOREACH(BlockArr, pObj){CCBlock* block = (CCBlock*)pObj;if(block->getTag() == tag)return block;}return NULL;
}

注释写的不怎多。说说我写的大致思路:

1.首先初始化宝石的位置和tag,当然tag和位置有这密切的位置,是对应的,在知道位置的情况是可以计算出tag,反之亦然。

2.在点击屏幕后,根据位置判断是否有宝石被点击到。如果点击到,先得到宝石的种类,其实就颜色了,然后遍历他周边4个是否是一样的颜色,如果是一样的,那么改变他的_willRemove为true,即是准备删除掉,在遍历他周边4个宝石,这里我用的是递归函数,见updateState函数。

3.在知道哪些宝石是要删除后,我们计算出其他宝石要掉落的步数step,和上方要重新要生成新宝石的数量,在函数updateMoveStep中有详细的方法。

4.然后让要删除的宝石做消失的动作,并从主场景中remove,并且从CCArray中remove。接着宝石生成,让他们根据要移动的step做移动的action。

5.完成这些后,我们在根据宝石的位置在重新初始化下一下他们的属性,主要是重新设定tag。

至于时间和血量这个就比较简单了,这个根据自己的喜好设定了,哈哈,你可以搞的很变态虐待自己哦。

这是我的方法,主要根据tag来做运算,如果哪位大神有更好的方法,希望能指点一下,个人还是觉得自己这个方法有点笨。

demo下载地址。

『cocos2d-x』diamond hunter宝石猎手相关推荐

  1. 看雪『Android安全』板块 2018 年优秀和精华帖分类索引

    转载:https://bbs.pediy.com/thread-249602.htm [推荐]『Android安全』版2018年优秀和精华帖分类索引 文章筛选和评价仅代表个人观点,欢迎指正. 列表不定 ...

  2. 洛谷 2 月月赛 I 『MdOI R4』 (Div2) A ~ D 四题全,也许会有六题,超高质量题解 (Div.1E、F下辈子一定补)【每日亿题2 / 9】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A.P7337 『MdOI R4』Fun B.P7338 『MdOI R4』Color C.P7 ...

  3. 『中级篇』docker容器安装wordpress(37)

    原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『中级篇』docker容器安装wordpress(37) 第一节的时候我就部署过wordpress,可能很多老铁一头雾水不知道 ...

  4. linux网络命名空间详解,『中级篇』 Linux网络命名空间(25)

    原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『中级篇』 Linux网络命名空间(25) docker底层技术,非常重要的关于namespace,network的names ...

  5. [日推荐]『保养汽车』爱车的专职管家

    2019独角兽企业重金招聘Python工程师标准>>> 你的爱车需要做保养啦! 想要挑一个优惠力度大.口碑好的4S店,又嫌电话预约太麻烦? 这个小程序你一定会爱不释手-- 保养汽车 ...

  6. 『高级篇』docker之APIGateway(17)

    原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『高级篇』docker之APIGateway(17) 这次说最后一个模块APIGateway,他的功能就是将我们客户端的请求统 ...

  7. 『中级篇』k8s基础网络Cluster Network(66)

    原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『中级篇』k8s基础网络Cluster Network(66) 通过国人大神的一键安装k8s集群安装了3个master节点和3 ...

  8. 『中级篇』Minikube快速搭建K8S单节点环境(61)

    原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『中级篇』Minikube快速搭建K8S单节点环境(61) 去介绍k8s的集群安装,本地搭建一个k8s的集群. 不会科学上网的 ...

  9. 『高级篇』docker容器来说什么是微服务(三)

    原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『高级篇』docker容器来说什么是微服务(三) 上一节说了单体架构,单体架构也无法适应我们的服务,来说说微服务,看能否解决单 ...

最新文章

  1. 关于鼠标、键盘的几个例子
  2. 《思科UCS服务器统一计算》一导读
  3. 【深度学习的数学】2×3×1层带sigmoid激活函数的神经网络感知机对三角形平面的分类训练预测(绘制出模型结果三维图展示效果)(梯度下降法+最小二乘法+激活函数sigmoid+误差反向传播法)
  4. 开源一些Delphi系统:诗词成语字典
  5. 使用Jupyter notebook,按下ctrl+enter后,一直出现In[*]呢?
  6. 如何使用系统自带的日志转储功能logroate.存放应用日志
  7. Windows下安装python2和python3双版本
  8. kibana 查询_干货 | Elasticsearch、Kibana数据导出实战
  9. livevent的几个问题
  10. 为了能让你们用上flutter,我准备做几期视频教程
  11. BootDo:源代码打包与自启动
  12. AD中画PCB详细流程
  13. jdk版本和java版本一样吗_jdk版本查看,以及java -version 和JAVA_HOME不一致问题
  14. unity3D导入fbx模型,并实现fbx模型的自由旋转源码详解
  15. python +appium实现原理_Appium+python自动化(四十)-Appium自动化测试框架综合实践 - 代码实现(超详解)...
  16. 微信小程序显示空格符
  17. RTL8211F 硬件配置
  18. 要做单片机课课设的快看过来1:KEIL安装以及C51环境搭建和Protues安装保姆教程
  19. Mybatis-Plus用纯注解完成一对多多对多查询
  20. 导数的奇偶性(含证明)

热门文章

  1. 大学期间技术学习方面最有成就感的事?
  2. 基因数据处理88之vcf2omim得到omim和dbSnpId信息
  3. Fortran进行t检验后使用GrADS画打点图
  4. 分享一篇写的非常好的文章《如何掌握企业级技术和项目经验》,非常值得一看!
  5. 解决win10 软件商店出现错误,和edge浏览器打开无法访问网络
  6. 《Long Short-Term Memory》翻译,Sepp Hochreiter, ¨urgen Schmidhuber.1997,9(8):1735-1780
  7. python飞机大战实验报告心得_Python学习之路「第七篇」-Pygame之飞机大战1
  8. (转)blackrock的阿拉丁系统与风险管理
  9. 百问网物联网实战-STM32中断
  10. 手游逆向专题<英雄联盟手游>: Unity内还原亚索渲染效果