Cocos2d-x 3.x版2048游戏开发

Cocos2d-x 3.x版2048游戏开发


本篇博客给大家介绍如何快速开发2048这样一款休闲游戏,理解整个2048游戏的开发流程,从本篇博客你将可以学习到以下内容:

这里注明一下,本教程来自极客学院,小巫对其中代码进行了解释。

  • 2048游戏的逻辑
  • Cocos2d-x中上下左右手势的识别
  • 游戏中卡片类的创建
  • 添加卡片到游戏中
  • 游戏中的逻辑实现
  • 游戏中随机卡片的生成
  • 游戏结束判断
  • 游戏分数的添加
  • 游戏美化

笔者的开发环境:
Cocos2d-x 3.1.1(开发引擎)
Visual Studio 2012(Win32)
Xcode 5.1(Mac系统下)

理解2048游戏逻辑

2048游戏逻辑并不复杂,4*4的卡片布局,玩家通过手势上下左右滑动来累加卡片数值,直到累加到2048。笔者用一张图说明:
这是一张游戏中的图,在图中同一方向并且数值相同的卡片可以进行叠加,比如128和128在同一行,玩家可以通过向左或向右的手势,对其进行叠加。笔者向右滑动手势,则会变成以下效果:


Cocos2d-x中上下左右手势的识别

玩家在玩2048游戏时,手势是最频繁的操作,所以我们需要对手势所产生的事件进行监听。
在HelloWorldScene.h头文件中声明两个需要实现的监听事件:
[objc] view plain copy
  1. //加入手势识别的事件
  2. virtualboolonTouchBegan(cocos2d::Touch*touch,cocos2d::Event*unused_event);
  3. voidonTouchEnded(cocos2d::Event*unused_event);

声明点击的位置属性
[cpp] copy
    //点击的元素位置
  1. intfirstX,firstY,endX,endY;


一个是触摸开始的事件,一个是触摸结束的事件。
然后再HelloWorldScene.cpp文件中实现这两个方法:
在HelloWorld的init方法中设置监听器的这两个方法的监听回调:
在头文件中声明四个方向的方法:



游戏中卡片类的创建

卡片类是组成2048游戏的基础,4*4的方格的16个位置放置不同的卡片,每个位置为独立的一张卡片。

创建CardSprite.h的头文件:
我们可以从游戏中看到,每张卡片有背景颜色和一个数字,所以我们在头文件需要声明它这两个属性。


CardSprite.cpp中对头文件方法的实现:
copy
//CardSprite.cpp
  • //Createdbywwjon14-7-16.
  • #include"CardSprite.h"
  • USING_NS_CC;
  • CardSprite*CardSprite::createCardSprite(intnumbers,intwidth,87); font-weight:bold; background-color:inherit">intheight,87); font-weight:bold; background-color:inherit">floatCardSpriteX,87); font-weight:bold; background-color:inherit">floatCardSpriteY){
  • //new一个卡片精灵
  • CardSprite*enemy=newCardSprite();
  • if(enemy&&enemy->init()){
  • enemy->autorelease();
  • enemy->enemyInit(numbers,width,height,CardSpriteX,CardSpriteY);
  • returnenemy;
  • CC_SAFE_DELETE(enemy);
  • returnNULL;
  • //卡片初始化方法
  • boolCardSprite::init(){
  • if(!Sprite::init()){
  • false;
  • true;
  • //设置数字
  • voidCardSprite::setNumber(intnum){
  • number=num;
  • //判断数字的大小来调整字体的大小
  • if(number>=0){
  • labTTFCardNumber->setFontSize(80);
  • if(number>=16){
  • labTTFCardNumber->setFontSize(60);
  • if(number>=128){
  • labTTFCardNumber->setFontSize(40);
  • if(number>=1024){
  • labTTFCardNumber->setFontSize(20);
  • //判断数组的大小调整颜色
  • if(number==0){
  • layerColorBG->setColor(cocos2d::Color3B(200,190,180));
  • if(number==2){
  • layerColorBG->setColor(cocos2d::Color3B(240,230,220));
  • if(number==4){
  • layerColorBG->setColor(cocos2d::Color3B(240,220,200));
  • if(number==8){
  • if(number==16){
  • if(number==32){
  • if(number==64){
  • if(number==128){
  • if(number==256){
  • if(number==512){
  • if(number==1024){
  • layerColorBG->setColor(cocos2d::Color3B(0,0));
  • if(number==2048){
  • layerColorBG->setColor(cocos2d::Color3B(0,0));
  • //更新显示的数字
  • if(number>0){
  • labTTFCardNumber->setString(__String::createWithFormat("%i",num)->getCString());
  • labTTFCardNumber->setString("");
  • intCardSprite::getNumber(){
  • returnnumber;
  • //第1个参数为数字,第2、3个参数为卡片的宽高,第4、5个参数为卡片的位置
  • voidCardSprite::enemyInit(//初始化数字
  • number=numbers;
  • //加入游戏卡片的背景颜色
  • layerColorBG=cocos2d::LayerColor::create(cocos2d::Color4B(200,255),width-15,height-15);
  • layerColorBG->setPosition(Point(CardSpriteX,CardSpriteY));
  • //判断如果不等于0就显示,否则为空
  • //加入中间字体
  • labTTFCardNumber=cocos2d::LabelTTF::create(__String::createWithFormat("%i",number)->getCString(),"HirakakuProN-W6",100);
  • //显示卡片数字的位置,这里显示在背景的中间
  • labTTFCardNumber->setPosition(Point(layerColorBG->getContentSize().width/2,layerColorBG->getContentSize().height/2));
  • //添加卡片数字到背景中
  • layerColorBG->addChild(labTTFCardNumber);
  • }else{
  • //加入中间字体
  • labTTFCardNumber=cocos2d::LabelTTF::create("","HirakakuProN-w6",80);
  • layerColorBG->addChild(labTTFCardNumber);
  • //将卡片添加到层
  • this->addChild(layerColorBG);
  • }

  • 每张卡片都有相同的宽和高,但数字和位置不同,数字是显示在背景中间的,所以我们需要5个参数来初始化卡片的位置。


    添加卡片到游戏中

    卡片放置在4*4方框中的不同位置,首先我们需要计算出每张卡片的宽高,然后计算每张卡片所在的位置,最后进行显示。
    在HelloWorldScene.h头文件中声明创建卡片的方法:

    游戏中的逻辑实现

    2048游戏最重要的部分就是四个方向的逻辑实现,也是开发这个游戏的难点所在。
    copy
    //向左
  • boolHelloWorld::doLeft(){
  • log("doLeft");
  • boolisdo=//最外层循环为4*4迭代
  • inty=0;y<4;y++){
  • intx=0;x<4;x++){
  • //这一层循环为判断卡片是合并还是清空
  • intx1=x+1;x1<4;x1++){
  • if(cardArr[x1][y]->getNumber()>0){//有数字
  • if(cardArr[x][y]->getNumber()<=0){//为空
  • //设置为右边卡片的数值
  • cardArr[x][y]->setNumber(cardArr[x1][y]->getNumber());
  • cardArr[x1][y]->setNumber(0);
  • x--;
  • isdo=elseif(cardArr[x][y]->getNumber()==cardArr[x1][y]->getNumber()){
  • //当前卡片的值与其比较卡片的值相等,设置为其的2倍
  • cardArr[x][y]->setNumber(cardArr[x][y]->getNumber()*2);
  • //设置分数
  • score+=cardArr[x][y]->getNumber();
  • labelTTFCardNumber->setString(__String::createWithFormat("%i",score)->getCString());
  • isdo=break;//跳出
  • returnisdo;
  • //向右
  • boolHelloWorld::doRight(){
  • log("doRight");
  • intx=3;x>=0;x--){
  • //循环判断左边卡片往右是合并还是清空
  • intx1=x-1;x1>=0;x1--){
  • if(cardArr[x1][y]->getNumber()>0){
  • if(cardArr[x][y]->getNumber()<=0){
  • cardArr[x][y]->setNumber(cardArr[x1][y]->getNumber());
  • x++;
  • cardArr[x][y]->setNumber(cardArr[x][y]->getNumber()*2);
  • cardArr[x1][y]->setNumber(0);
  • break;
  • returnisdo;
  • //向上
  • boolHelloWorld::doUp(){
  • log("doUp");
  • false;
  • //最外层循环为4*4迭代
  • inty=3;y>=0;y--){
  • //这一层循环为判断卡片是合并还是清空
  • inty1=y-1;y1>=0;y1--){
  • if(cardArr[x][y1]->getNumber()>0){//有数字
  • //为空
  • //设置为右边卡片的数值
  • cardArr[x][y]->setNumber(cardArr[x][y1]->getNumber());
  • cardArr[x][y1]->setNumber(0);
  • y++;
  • if(cardArr[x][y]->getNumber()==cardArr[x][y1]->getNumber()){
  • //当前卡片的值与其比较卡片的值相等,设置为其的2倍
  • //跳出
  • //向下
  • boolHelloWorld::doDown(){
  • log("doDown");
  • inty1=y+1;y1<4;y1++){
  • y--;
  • //设置分数
  • score+=cardArr[x][y]->getNumber();
  • labelTTFCardNumber->setString(__String::createWithFormat("%i",score)->getCString());
  • }




  • 游戏中随机卡片的生成

    在HelloWorldScene.h头文件中声明随机生成卡片的方法:

    游戏结束判断

    在HelloWorldScene.h中声明判断游戏结束的方法:

    游戏分数的添加

    2048中需要对分数进行统计并显示给玩家,我们在HelloWolrdScene.h文件中声明分数和显示分数的控件:
    关于分数的计算,在游戏中的逻辑已经实现,具体读者可以查看代码,后面笔者也会提供完整的代码。

    游戏美化

    2048中我们会发现不同的数字会有不同的背景,然后字体大小也会随数值的变化而变化,实现这个需要通过判断数值的大小来显示不同的颜色背景和设置不同字体大小。

    这个功能的实现是在卡片类设置数值的时候实现的,代码逻辑如下:
    copy
    }


    最后笔者给出所有代码清单:
    AppDelegate.h
    AppDelegate.cpp
    HelloWorldScene.h
    HelloWorldScene.cpp
    CardSprite.h
    CardSprite.cpp

    >>>AppDelegate.h

    >>>HelloWorldScene.h
    copy
    #include"HelloWorldScene.h"
  • #include"CardSprite.h"
  • Scene*HelloWorld::createScene()
  • //'scene'isanautoreleaseobject
  • autoscene=Scene::create();
  • //'layer'isanautoreleaseobject
  • autolayer=HelloWorld::create();
  • //addlayerasachildtoscene
  • scene->addChild(layer);
  • //returnthescene
  • returnscene;
  • //on"init"youneedtoinitializeyourinstance
  • boolHelloWorld::init()
  • //////////////////////////////
  • //1.superinitfirst
  • if(!Layer::init())
  • score=0;
  • autotouchListener=EventListenerTouchOneByOne::create();
  • touchListener->onTouchBegan=CC_CALLBACK_2(HelloWorld::onTouchBegan,this);
  • touchListener->onTouchEnded=CC_CALLBACK_2(HelloWorld::onTouchEnded,153); font-weight:bold; background-color:inherit">this);
  • //调用生成卡片的方法
  • createCardSprite(visibleSize);
  • //调用生成随机数
  • //游戏是否还能继续运行下去
  • voidHelloWorld::doCheckGameOver(){
  • inty=0;y<4;y++){
  • intx=0;x<4;x++){
  • if(cardArr[x][y]->getNumber()==0
  • ||(x>0&&(cardArr[x][y]->getNumber()==cardArr[x-1][y]->getNumber()))
  • ||(x<3&&(cardArr[x][y]->getNumber()==cardArr[x+1][y]->getNumber()))
  • ||(y<0&&(cardArr[x][y]->getNumber()==cardArr[x][y-1]->getNumber()))
  • ||(x<3&&(cardArr[x][y]->getNumber()==cardArr[x][y+1]->getNumber()))){
  • isGameOver=if(isGameOver){
  • //结束游戏
  • Director::getInstance()->replaceScene(TransitionFade::create(1,HelloWorld::createScene()));
  • //自动生成卡片
  • voidHelloWorld::autoCreateCardNumber(){
  • inti=CCRANDOM_0_1()*4;
  • intj=CCRANDOM_0_1()*4;
  • //判断是否已经存在的位置
  • if(cardArr[i][j]->getNumber()>0){
  • //已存在,递归创建
  • //生成2和4的比例是1:9的概率
  • cardArr[i][j]->setNumber(CCRANDOM_0_1()*10<1?4:2);
  • boolHelloWorld::onTouchBegan(cocos2d::Touch*touch,cocos2d::Event*unused_event){
  • PointtouchP0=touch->getLocation();
  • firstX=touchP0.x;
  • firstY=touchP0.y;
  • voidHelloWorld::onTouchEnded(cocos2d::Touch*touch,248)"> endX=firstX-touchP0.x;
  • endY=firstY-touchP0.y;
  • if(endX+5>0){
  • if(endY+5>0){
  • voidHelloWorld::menuCloseCallback(Ref*pSender)
  • #if(CC_TARGET_PLATFORM==CC_PLATFORM_WP8)||(CC_TARGET_PLATFORM==CC_PLATFORM_WINRT)
  • MessageBox("Youpressedtheclosebutton.WindowsStoreAppsdonotimplementaclosebutton.","Alert");
  • return;
  • #endif
  • Director::getInstance()->end();
  • #if(CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
  • exit(0);
  • }

  • >>>CardSprite.h




    FROM:http://blog.csdn.net/wwj_748/article/details/38168649

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 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在载入图片方面也有了非常大改变,仅仅只是