• cocos2d-x 2048小游戏源码+素材
  • cocos creator的2048游戏源码,适合初学者学习,需要下载cocos creator后安装然后根据提示安装完成后,打开这个项目就可以尝试运行。
  • lua文件直接放到cocos2dx的例子HelloLua项目中即可 参考目录 E:\cocos2d-x-2.2\samples\Lua\HelloLua\Resources 窗口大小 480 * 640
  • Cocos2d-x 3.x版2048游戏开发 本篇博客给大家介绍如何快速开发2048这样一款休闲游戏,理解整个2048游戏的开发流程,从本篇博客你将可以学习到以下内容:2048游戏的逻辑Cocos2d-x中上下左右手势的识别游戏中卡片类的...

    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头文件中声明两个需要实现的监听事件:
    // 加入手势识别的事件
    	virtual bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event);
    	virtual void onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unused_event);

    声明点击的位置属性
    // 点击的元素位置
    	int firstX, firstY, endX, endY;


    一个是触摸开始的事件,一个是触摸结束的事件。
    然后再HelloWorldScene.cpp文件中实现这两个方法:
    // 加入手势识别的事件
    bool HelloWorld::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event){
    	// 触摸点
    	Point touchP0 = touch->getLocation();
    
    	firstX = touchP0.x;
    	firstY = touchP0.y;
    
    
    	return true;
    }
    
    // 触摸结束触发
    void HelloWorld::onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unused_event){
        // 获取触摸点位置
    	Point touchP0 = touch->getLocation();
    	// 获取X轴和Y轴的移动距离
    	endX = firstX - touchP0.x;
    	endY = firstY - touchP0.y;
    
    	// 判断X轴和Y轴的移动距离,如果X轴的绝对值大于Y轴的绝对值就是左右否则是上下
    	if (abs(endX) > abs(endY)){
    		// 左右
    		if (endX + 5 > 0) {
    			// 左边
    			if(doLeft()) {
                    autoCreateCardNumber();
                    doCheckGameOver();
                }
    
    		} else {
    			// 右边
    			if(doRight()){
                    autoCreateCardNumber();
                    doCheckGameOver();
                }
    		}
    
    	} else {
            // 上下
    		if (endY + 5 > 0) {
    			// 下边
    			if(doDown()) {
                    autoCreateCardNumber();
                    doCheckGameOver();
                }
    		} else {
                // 上边
    			if(doUp()) {
                    autoCreateCardNumber();
                    doCheckGameOver();
                };
    		}
    
    	}
    }

    在HelloWorld的init方法中设置监听器的这两个方法的监听回调:
    	// 创建手势识别的事件监听器
    	auto touchListener = EventListenerTouchOneByOne::create();
    	touchListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
    	touchListener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
        // 添加事件监听
    	_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);

    上面中根据计算开始位置到结束位置X轴和Y轴的移动距离来判断是向左、向右、向上还是向下的方向:
    在头文件中声明四个方向的方法:
    // 上下左右的方法
    	bool doLeft();
    	bool doRight();
    	bool doUp();
    	bool doDown();

    然后对其进行实现。这四个方法的逻辑实现放到后面进行讲解。



    游戏中卡片类的创建

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

    创建CardSprite.h的头文件:
    //
    //  CardSprite.h
    //  2048Game
    //
    //  Created by mac on 14-7-16.
    //
    //
    
    #ifndef ___048Game__CardSprite__
    #define ___048Game__CardSprite__
    
    #include "cocos2d.h"
    
    class CardSprite:public cocos2d::Sprite {
        
    public:
        // 初始化游戏卡片的方法
        static CardSprite *createCardSprite(int numbers, int width, int height, float CardSpriteX, float CardSpriteY);
        virtual bool init();
        CREATE_FUNC(CardSprite);
        
        // 设置数字
        void setNumber(int num);
        
        // 获取数字
        int getNumber();
    private:
        // 显示在界面的数字
        int number;
        void enemyInit(int numbers, int width, int height, float CardSpriteX, float CardSpriteY);
        
        // 定义显示数字的控件
        cocos2d::LabelTTF *labTTFCardNumber;
        
        // 显示的背景
        cocos2d::LayerColor *layerColorBG;
        
        
    };
    
    #endif /* defined(___048Game__CardSprite__) */

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


    CardSprite.cpp中对头文件方法的实现:
    //
    //  CardSprite.cpp
    //  2048Game
    //
    //  Created by wwj on 14-7-16.
    //
    //
    
    #include "CardSprite.h"
    
    USING_NS_CC;
    
    // 初始化游戏卡片的方法
    CardSprite* CardSprite::createCardSprite(int numbers, int width, int height, float CardSpriteX, float CardSpriteY) {
        // new一个卡片精灵
        CardSprite *enemy = new CardSprite();
        if (enemy && enemy->init()) {
            enemy->autorelease();
            enemy->enemyInit(numbers, width, height, CardSpriteX, CardSpriteY);
            return enemy;
        }
        CC_SAFE_DELETE(enemy);
        return NULL;
    }
    
    // 卡片初始化方法
    bool CardSprite::init() {
        if (!Sprite::init()) {
            return false;
        }
        return true;
    }
    
    
    // 设置数字
    void CardSprite::setNumber(int num) {
        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) {
            layerColorBG->setColor(cocos2d::Color3B(240, 180, 120));
        }
        if (number == 16) {
            layerColorBG->setColor(cocos2d::Color3B(240, 140, 90));
        }
        if (number == 32) {
            layerColorBG->setColor(cocos2d::Color3B(240, 120, 90));
        }
        if (number == 64) {
            layerColorBG->setColor(cocos2d::Color3B(240, 90, 60));
        }
        if (number == 128) {
            layerColorBG->setColor(cocos2d::Color3B(240, 90, 60));
        }
        if (number == 256) {
            layerColorBG->setColor(cocos2d::Color3B(240, 200, 70));
        }
        if (number == 512) {
            layerColorBG->setColor(cocos2d::Color3B(240, 200, 70));
        }
        if (number == 1024) {
            layerColorBG->setColor(cocos2d::Color3B(0, 130, 0));
        }
        if (number == 2048) {
            layerColorBG->setColor(cocos2d::Color3B(0, 130, 0));
        }
        
        
        // 更新显示的数字
        if (number > 0) {
            labTTFCardNumber->setString(__String::createWithFormat("%i", num)->getCString() );
        } else {
            labTTFCardNumber->setString("");
        }
        
    }
    
    // 获取数字
    int CardSprite::getNumber() {
        return number;
    }
    
    
    //第1个参数为数字,第2、3个参数为卡片的宽高,第4、5个参数为卡片的位置
    void CardSprite::enemyInit(int numbers, int width, int height, float CardSpriteX, float CardSpriteY) {
        // 初始化数字
        number = numbers;
        
        // 加入游戏卡片的背景颜色
        layerColorBG = cocos2d::LayerColor::create(cocos2d::Color4B(200, 190, 180, 255), width - 15, height - 15);
        layerColorBG->setPosition(Point(CardSpriteX, CardSpriteY));
        
        // 判断如果不等于0就显示,否则为空
        if (number > 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);
            labTTFCardNumber->setPosition(Point(layerColorBG->getContentSize().width/2, layerColorBG->getContentSize().height/2));
            layerColorBG->addChild(labTTFCardNumber);
        }
        // 将卡片添加到层
        this->addChild(layerColorBG);
        
    }
    
    

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


    添加卡片到游戏中

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

    在HelloWorldScene.cpp中实现该方法:
    // 创建卡片,size为屏幕大小
    void HelloWorld::createCardSprite(cocos2d::Size size) {
        // 求出单元格的宽度和高度,28为左右距离
        int lon = (size.width - 28) / 4;
        
        // 4*4的单元格
        for (int j = 0; j < 4; j++) {
            for (int i = 0; i < 4; i++) {
                // 数字0,宽高相同为lon,lon+j+20为卡片X轴位置,如lon+0+20为第一个卡片的位置,20是每张卡片的间隙,lon+i+20+size.height/6代表的意思是屏幕大小竖方向分了六份,我们这里只放4个位置
               CardSprite *card = CardSprite::createCardSprite(0, lon, lon, lon * j + 10, lon * i + 10 + size.height / 6);
                addChild(card);
                
                // 添加卡片到二维数组中
                cardArr[j][i] = card;
            }
        }
    }

    笔者对每张卡片显示的位置在代码中进行了说明,读者也可以思考一下为什么要这么做。

    游戏中的逻辑实现

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




    游戏中随机卡片的生成

    在HelloWorldScene.h头文件中声明随机生成卡片的方法:
        // 自动卡片生成
        void autoCreateCardNumber();

    在HelloWorldScene.cpp实现该方法:
    // 自动生成卡片
    void HelloWorld::autoCreateCardNumber() {
        int i = CCRANDOM_0_1() * 4;
        int j = CCRANDOM_0_1() * 4;
        
        // 判断是否已经存在的位置
        if (cardArr[i][j]->getNumber() > 0) {
            // 已存在,递归创建
            autoCreateCardNumber();
        } else {
            // 生成2和4的比例是1:9的概率
            cardArr[i][j]->setNumber(CCRANDOM_0_1() * 10 < 1 ? 4:2);
        }
    }

    游戏结束判断

    在HelloWorldScene.h中声明判断游戏结束的方法:
    // 判断游戏是否还能继续运行下去
        void doCheckGameOver();
    在HelloWorldScene.cpp中实现该方法:
    // 游戏是否还能继续运行下去
    void HelloWorld::doCheckGameOver() {
        bool isGameOver = true;
        
        for (int y = 0; y < 4; y++) {
            for (int x = 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 = false;
                }
            }
        }
        if (isGameOver) {
            // 结束游戏
            Director::getInstance()->replaceScene(TransitionFade::create(1, HelloWorld::createScene()));
        }
    
    }

    游戏分数的添加

    2048中需要对分数进行统计并显示给玩家,我们在HelloWolrdScene.h文件中声明分数和显示分数的控件:
    // 整体游戏的分数
        int score;
        // 定义显示数据的控件
        cocos2d::LabelTTF *labelTTFCardNumber;

    在HelloWorldScene.cpp中对分数初始化为0,并显示“分数”的文本:
       score = 0;
        
        
        // 获得屏幕可视大小
        Size visibleSize = Director::getInstance()->getVisibleSize();
        // 加入游戏的背景
        auto layerColorBG = cocos2d::LayerColor::create(cocos2d::Color4B(180,170,160, 255));
        this->addChild(layerColorBG);
        // 在上方加入游戏的分数
        auto labelTTFCardNumberName = LabelTTF::create("分数:","HirakakuProN-W6", 80);
        labelTTFCardNumberName->setPosition(Point(visibleSize.width/5, visibleSize.height-100));
        addChild(labelTTFCardNumberName);
        
        
        labelTTFCardNumber = LabelTTF::create("0", "HirakakuProN-W6", 80);
        labelTTFCardNumber->setPosition(visibleSize.width/2+100, visibleSize.height - 100);
        addChild(labelTTFCardNumber
                 );
        

    关于分数的计算,在游戏中的逻辑已经实现,具体读者可以查看代码,后面笔者也会提供完整的代码。

    游戏美化

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

    这个功能的实现是在卡片类设置数值的时候实现的,代码逻辑如下:
    // 设置数字
    void CardSprite::setNumber(int num) {
        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) {
            layerColorBG->setColor(cocos2d::Color3B(240, 180, 120));
        }
        if (number == 16) {
            layerColorBG->setColor(cocos2d::Color3B(240, 140, 90));
        }
        if (number == 32) {
            layerColorBG->setColor(cocos2d::Color3B(240, 120, 90));
        }
        if (number == 64) {
            layerColorBG->setColor(cocos2d::Color3B(240, 90, 60));
        }
        if (number == 128) {
            layerColorBG->setColor(cocos2d::Color3B(240, 90, 60));
        }
        if (number == 256) {
            layerColorBG->setColor(cocos2d::Color3B(240, 200, 70));
        }
        if (number == 512) {
            layerColorBG->setColor(cocos2d::Color3B(240, 200, 70));
        }
        if (number == 1024) {
            layerColorBG->setColor(cocos2d::Color3B(0, 130, 0));
        }
        if (number == 2048) {
            layerColorBG->setColor(cocos2d::Color3B(0, 130, 0));
        }
        
        
        // 更新显示的数字
        if (number > 0) {
            labTTFCardNumber->setString(__String::createWithFormat("%i", num)->getCString() );
        } else {
            labTTFCardNumber->setString("");
        }
        
    }
    


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

    >>>AppDelegate.h
    #ifndef  _APP_DELEGATE_H_
    #define  _APP_DELEGATE_H_
    
    #include "cocos2d.h"
    
    /**
    @brief    The cocos2d Application.
    
    The reason for implement as private inheritance is to hide some interface call by Director.
    */
    class  AppDelegate : private cocos2d::Application
    {
    public:
        AppDelegate();
        virtual ~AppDelegate();
    
        /**
        @brief    Implement Director and Scene init code here.
        @return true    Initialize success, app continue.
        @return false   Initialize failed, app terminate.
        */
        virtual bool applicationDidFinishLaunching();
    
        /**
        @brief  The function be called when the application enter background
        @param  the pointer of the application
        */
        virtual void applicationDidEnterBackground();
    
        /**
        @brief  The function be called when the application enter foreground
        @param  the pointer of the application
        */
        virtual void applicationWillEnterForeground();
    };
    
    #endif // _APP_DELEGATE_H_
    

    >>>AppDelegate.cpp
    #include "AppDelegate.h"
    #include "HelloWorldScene.h"
    
    USING_NS_CC;
    
    AppDelegate::AppDelegate() {
    
    }
    
    AppDelegate::~AppDelegate() 
    {
    }
    
    bool AppDelegate::applicationDidFinishLaunching() {
        // initialize director
        auto director = Director::getInstance();
        auto glview = director->getOpenGLView();
        if(!glview) {
            glview = GLView::create("My Game");
            director->setOpenGLView(glview);
        }
    
    	glview->setDesignResolutionSize(480, 800, ResolutionPolicy::SHOW_ALL);
        // turn on display FPS
    	director->setDisplayStats(false);
    
        // set FPS. the default value is 1.0/60 if you don't call this
        director->setAnimationInterval(1.0 / 60);
    
        // create a scene. it's an autorelease object
        auto scene = HelloWorld::createScene();
    
        // run
        director->runWithScene(scene);
    
        return true;
    }
    
    // This function will be called when the app is inactive. When comes a phone call,it's be invoked too
    void AppDelegate::applicationDidEnterBackground() {
        Director::getInstance()->stopAnimation();
    
        // if you use SimpleAudioEngine, it must be pause
        // SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
    }
    
    // this function will be called when the app is active again
    void AppDelegate::applicationWillEnterForeground() {
        Director::getInstance()->startAnimation();
    
        // if you use SimpleAudioEngine, it must resume here
        // SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
    }
    

    >>>HelloWorldScene.h
    #ifndef __HELLOWORLD_SCENE_H__
    #define __HELLOWORLD_SCENE_H__
    
    #include "cocos2d.h"
    #include "CardSprite.h"
    
    class HelloWorld : public cocos2d::Layer
    {
    public:
        static cocos2d::Scene* createScene();
        virtual bool init();  
        void menuCloseCallback(cocos2d::Ref* pSender);
        CREATE_FUNC(HelloWorld);
    
    	// 加入手势识别的事件
    	virtual bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event);
    	virtual void onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unused_event);
    
    	// 上下左右的方法
    	bool doLeft();
    	bool doRight();
    	bool doUp();
    	bool doDown();
        // 自动卡片生成
        void autoCreateCardNumber();
        // 判断游戏是否还能继续运行下去
        void doCheckGameOver();
        
    
    private:
    	// 点击的元素位置
    	int firstX, firstY, endX, endY;
        
        // 定义一个二维数组
        CardSprite *cardArr[4][4];
        
        // 创建卡片
        void createCardSprite(cocos2d::Size size);
        
        // 整体游戏的分数
        int score;
        // 定义显示数据的控件
        cocos2d::LabelTTF *labelTTFCardNumber;
    };
    
    #endif // __HELLOWORLD_SCENE_H__
    

    >>>HelloWorldScene.cpp
    #include "HelloWorldScene.h"
    #include "CardSprite.h"
    
    USING_NS_CC;
    
    Scene* HelloWorld::createScene()
    {
    	// 'scene' is an autorelease object
    	auto scene = Scene::create();
    
    	// 'layer' is an autorelease object
    	auto layer = HelloWorld::create();
    
    	// add layer as a child to scene
    	scene->addChild(layer);
    
    	// return the scene
    	return scene;
    }
    
    // on "init" you need to initialize your instance
    bool HelloWorld::init()
    {
    	//////////////////////////////
    	// 1. super init first
    	if ( !Layer::init() )
    	{
    		return false;
    	}
        
        score = 0;
        
        
        // 获得屏幕可视大小
        Size visibleSize = Director::getInstance()->getVisibleSize();
        // 加入游戏的背景
        auto layerColorBG = cocos2d::LayerColor::create(cocos2d::Color4B(180,170,160, 255));
        this->addChild(layerColorBG);
        // 在上方加入游戏的分数
        auto labelTTFCardNumberName = LabelTTF::create("分数:","HirakakuProN-W6", 80);
        labelTTFCardNumberName->setPosition(Point(visibleSize.width/5, visibleSize.height-100));
        addChild(labelTTFCardNumberName);
        
        
        labelTTFCardNumber = LabelTTF::create("0", "HirakakuProN-W6", 80);
        labelTTFCardNumber->setPosition(visibleSize.width/2+100, visibleSize.height - 100);
        addChild(labelTTFCardNumber
                 );
        
       
    	// 创建手势识别的事件监听器
    	auto touchListener = EventListenerTouchOneByOne::create();
    	touchListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
    	touchListener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
        // 添加事件监听
    	_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
    
        
        // 调用生成卡片的方法
        createCardSprite(visibleSize);
        
        // 调用生成随机数
        autoCreateCardNumber();
        autoCreateCardNumber();
    	return true;
    }
    
    // 游戏是否还能继续运行下去
    void HelloWorld::doCheckGameOver() {
        bool isGameOver = true;
        
        for (int y = 0; y < 4; y++) {
            for (int x = 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 = false;
                }
            }
        }
        if (isGameOver) {
            // 结束游戏
            Director::getInstance()->replaceScene(TransitionFade::create(1, HelloWorld::createScene()));
        }
    
    }
    
    // 自动生成卡片
    void HelloWorld::autoCreateCardNumber() {
        int i = CCRANDOM_0_1() * 4;
        int j = CCRANDOM_0_1() * 4;
        
        // 判断是否已经存在的位置
        if (cardArr[i][j]->getNumber() > 0) {
            // 已存在,递归创建
            autoCreateCardNumber();
        } else {
            // 生成2和4的比例是1:9的概率
            cardArr[i][j]->setNumber(CCRANDOM_0_1() * 10 < 1 ? 4:2);
        }
    }
    
    // 创建卡片,size为屏幕大小
    void HelloWorld::createCardSprite(cocos2d::Size size) {
        // 求出单元格的宽度和高度,28为左右距离
        int lon = (size.width - 28) / 4;
        
        // 4*4的单元格
        for (int j = 0; j < 4; j++) {
            for (int i = 0; i < 4; i++) {
                // 数字0,宽高相同为lon,lon+j+20为卡片X轴位置,如lon+0+20为第一个卡片的位置,20是每张卡片的间隙,lon+i+20+size.height/6代表的意思是屏幕大小竖方向分了六份,我们这里只放4个位置
               CardSprite *card = CardSprite::createCardSprite(0, lon, lon, lon * j + 10, lon * i + 10 + size.height / 6);
                addChild(card);
                
                // 添加卡片到二维数组中
                cardArr[j][i] = card;
            }
        }
    }
    
    // 加入手势识别的事件
    bool HelloWorld::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event){
    	// 触摸点
    	Point touchP0 = touch->getLocation();
    
    	firstX = touchP0.x;
    	firstY = touchP0.y;
    
    
    	return true;
    }
    
    // 触摸结束触发
    void HelloWorld::onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unused_event){
        // 获取触摸点位置
    	Point touchP0 = touch->getLocation();
    	// 获取X轴和Y轴的移动距离
    	endX = firstX - touchP0.x;
    	endY = firstY - touchP0.y;
    
    	// 判断X轴和Y轴的移动距离,如果X轴的绝对值大于Y轴的绝对值就是左右否则是上下
    	if (abs(endX) > abs(endY)){
    		// 左右
    		if (endX + 5 > 0) {
    			// 左边
    			if(doLeft()) {
                    autoCreateCardNumber();
                    doCheckGameOver();
                }
    
    		} else {
    			// 右边
    			if(doRight()){
                    autoCreateCardNumber();
                    doCheckGameOver();
                }
    		}
    
    	} else {
            // 上下
    		if (endY + 5 > 0) {
    			// 下边
    			if(doDown()) {
                    autoCreateCardNumber();
                    doCheckGameOver();
                }
    		} else {
                // 上边
    			if(doUp()) {
                    autoCreateCardNumber();
                    doCheckGameOver();
                };
    		}
    
    	}
    }
    
    
    // 向左
    bool HelloWorld::doLeft(){
    	log("doLeft");
        
        bool isdo = false;
        // 最外层循环为4*4迭代
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                
                // 这一层循环为判断卡片是合并还是清空
                for (int x1 = 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 = true;
                            
                        } else if(cardArr[x][y]->getNumber() == cardArr[x1][y]->getNumber()) {
                            // 当前卡片的值与其比较卡片的值相等,设置为其的2倍
                            cardArr[x][y]->setNumber(cardArr[x][y]->getNumber()*2);
                            cardArr[x1][y]->setNumber(0);
                            
                            
                            // 设置分数
                            score += cardArr[x][y]->getNumber();
                            labelTTFCardNumber->setString(__String::createWithFormat("%i", score)->getCString());
                            isdo = true;
                        }
                        break;// 跳出
                    }
                }
            }
        }
        
    	return isdo;
    }
    
    // 向右
    bool HelloWorld::doRight(){
    	log("doRight");
        
        bool isdo = false;
        // 最外层循环为4*4迭代
        for (int y = 0; y < 4; y++) {
            for (int x = 3; x >= 0; x--) {
                
                // 循环判断左边卡片往右是合并还是清空
                for (int x1 = 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++;
                            isdo = true;
                        }
                        else if (cardArr[x][y]->getNumber() == cardArr[x1][y]->getNumber()) {
                            cardArr[x][y]->setNumber(cardArr[x][y]->getNumber() * 2);
                            cardArr[x1][y]->setNumber(0);
                            
                            // 设置分数
                            score += cardArr[x][y]->getNumber();
                            labelTTFCardNumber->setString(__String::createWithFormat("%i", score)->getCString());
    
                            isdo = true;
                        }
                        break;
                    }
    
                }
            }
            
        }
        
    	return isdo;
    
    }
    
    // 向上
    bool HelloWorld::doUp(){
    	log("doUp");
    	bool isdo = false;
        // 最外层循环为4*4迭代
        for (int x = 0; x < 4; x++) {
            for (int y = 3; y >= 0; y--) {
                
                // 这一层循环为判断卡片是合并还是清空
                for (int y1 = y - 1; y1 >= 0; y1--) {
                    if (cardArr[x][y1]->getNumber() > 0) {// 有数字
                        if (cardArr[x][y]->getNumber() <= 0) { // 为空
                            // 设置为右边卡片的数值
                            cardArr[x][y]->setNumber(cardArr[x][y1]->getNumber());
                            cardArr[x][y1]->setNumber(0);
                            
                            y++;
                            isdo = true;
                            
                        } else if(cardArr[x][y]->getNumber() == cardArr[x][y1]->getNumber()) {
                            // 当前卡片的值与其比较卡片的值相等,设置为其的2倍
                            cardArr[x][y]->setNumber(cardArr[x][y]->getNumber()*2);
                            cardArr[x][y1]->setNumber(0);
                            
                            // 设置分数
                            score += cardArr[x][y]->getNumber();
                            labelTTFCardNumber->setString(__String::createWithFormat("%i", score)->getCString());
    
                            isdo = true;
                        }
                        break;// 跳出
                    }
                }
            }
        }
        
    	return isdo;
    
    }
    
    // 向下
    bool HelloWorld::doDown(){
    	log("doDown");
        bool isdo = false;
        // 最外层循环为4*4迭代
        for (int x = 0; x < 4; x++) {
            for (int y = 0; y < 4; y++) {
                
                // 这一层循环为判断卡片是合并还是清空
                for (int y1 = y + 1; y1 < 4; y1++) {
                    if (cardArr[x][y1]->getNumber() > 0) {// 有数字
                        if (cardArr[x][y]->getNumber() <= 0) { // 为空
                            // 设置为右边卡片的数值
                            cardArr[x][y]->setNumber(cardArr[x][y1]->getNumber());
                            cardArr[x][y1]->setNumber(0);
                            
                            y--;
                            isdo = true;
                            
                        } else if(cardArr[x][y]->getNumber() == cardArr[x][y1]->getNumber()) {
                            // 当前卡片的值与其比较卡片的值相等,设置为其的2倍
                            cardArr[x][y]->setNumber(cardArr[x][y]->getNumber()*2);
                            cardArr[x][y1]->setNumber(0);
                            
                            
                            // 设置分数
                            score += cardArr[x][y]->getNumber();
                            labelTTFCardNumber->setString(__String::createWithFormat("%i", score)->getCString());
    
                            isdo = true;
                        }
                        break;// 跳出
                    }
                }
            }
        }
        
    	return isdo;
    }
    
    
    
    void HelloWorld::menuCloseCallback(Ref* pSender)
    {
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
    	MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
    	return;
    #endif
    
    	Director::getInstance()->end();
    
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    	exit(0);
    #endif
    }
    

    >>>CardSprite.h
    //
    //  CardSprite.h
    //  2048Game
    //
    //  Created by mac on 14-7-16.
    //
    //
    
    #ifndef ___048Game__CardSprite__
    #define ___048Game__CardSprite__
    
    #include "cocos2d.h"
    
    class CardSprite:public cocos2d::Sprite {
        
    public:
        // 初始化游戏卡片的方法
        static CardSprite *createCardSprite(int numbers, int width, int height, float CardSpriteX, float CardSpriteY);
        virtual bool init();
        CREATE_FUNC(CardSprite);
        
        // 设置数字
        void setNumber(int num);
        
        // 获取数字
        int getNumber();
    private:
        // 显示在界面的数字
        int number;
        void enemyInit(int numbers, int width, int height, float CardSpriteX, float CardSpriteY);
        
        // 定义显示数字的控件
        cocos2d::LabelTTF *labTTFCardNumber;
        
        // 显示的背景
        cocos2d::LayerColor *layerColorBG;
        
        
    };
    
    #endif /* defined(___048Game__CardSprite__) */
    

    >>>CardSprite.cpp
    //
    //  CardSprite.cpp
    //  2048Game
    //
    //  Created by wwj on 14-7-16.
    //
    //
    
    #include "CardSprite.h"
    
    USING_NS_CC;
    
    // 初始化游戏卡片的方法
    CardSprite* CardSprite::createCardSprite(int numbers, int width, int height, float CardSpriteX, float CardSpriteY) {
        // new一个卡片精灵
        CardSprite *enemy = new CardSprite();
        if (enemy && enemy->init()) {
            enemy->autorelease();
            enemy->enemyInit(numbers, width, height, CardSpriteX, CardSpriteY);
            return enemy;
        }
        CC_SAFE_DELETE(enemy);
        return NULL;
    }
    
    // 卡片初始化方法
    bool CardSprite::init() {
        if (!Sprite::init()) {
            return false;
        }
        return true;
    }
    
    
    // 设置数字
    void CardSprite::setNumber(int num) {
        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) {
            layerColorBG->setColor(cocos2d::Color3B(240, 180, 120));
        }
        if (number == 16) {
            layerColorBG->setColor(cocos2d::Color3B(240, 140, 90));
        }
        if (number == 32) {
            layerColorBG->setColor(cocos2d::Color3B(240, 120, 90));
        }
        if (number == 64) {
            layerColorBG->setColor(cocos2d::Color3B(240, 90, 60));
        }
        if (number == 128) {
            layerColorBG->setColor(cocos2d::Color3B(240, 90, 60));
        }
        if (number == 256) {
            layerColorBG->setColor(cocos2d::Color3B(240, 200, 70));
        }
        if (number == 512) {
            layerColorBG->setColor(cocos2d::Color3B(240, 200, 70));
        }
        if (number == 1024) {
            layerColorBG->setColor(cocos2d::Color3B(0, 130, 0));
        }
        if (number == 2048) {
            layerColorBG->setColor(cocos2d::Color3B(0, 130, 0));
        }
        
        
        // 更新显示的数字
        if (number > 0) {
            labTTFCardNumber->setString(__String::createWithFormat("%i", num)->getCString() );
        } else {
            labTTFCardNumber->setString("");
        }
        
    }
    
    // 获取数字
    int CardSprite::getNumber() {
        return number;
    }
    
    
    //第1个参数为数字,第2、3个参数为卡片的宽高,第4、5个参数为卡片的位置
    void CardSprite::enemyInit(int numbers, int width, int height, float CardSpriteX, float CardSpriteY) {
        // 初始化数字
        number = numbers;
        
        // 加入游戏卡片的背景颜色
        layerColorBG = cocos2d::LayerColor::create(cocos2d::Color4B(200, 190, 180, 255), width - 15, height - 15);
        layerColorBG->setPosition(Point(CardSpriteX, CardSpriteY));
        
        // 判断如果不等于0就显示,否则为空
        if (number > 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);
            labTTFCardNumber->setPosition(Point(layerColorBG->getContentSize().width/2, layerColorBG->getContentSize().height/2));
            layerColorBG->addChild(labTTFCardNumber);
        }
        // 将卡片添加到层
        this->addChild(layerColorBG);
        
    }
    
    

    最后,骚年们就不要向我要源码了,所有的代码在这里均有实现,只要把这些代码集成到你的项目中去就可以实现跟笔者一样的效果,希望各位能好好体会2048开发的流程。




    展开全文
  • 如今,H5游戏、微信小游戏、抖音小游戏、头条小游戏、快手小游戏、百度小游戏、QQ轻游戏等小程序游戏都特别火,而这些小游戏中80%都是用Cocos Creator开发的,Cocos Creator可以做到一次开发,多平台部署。...
  • cocos2d制作的2048游戏源码,用的版本是3.x版本,加压后直接加载进去Classes中的代码,替换掉原来的资源文件,然后自己冲洗编译一下就可以了
  • 话说,年仅19岁的意大利人...然而游戏飙升的人气超乎他的想象,人们忘记了Flappy Bird, 2048成了 网络上“最上瘾的东西”。 我是完全为了熟悉Cocos2d-x3.x版本,才写这个游戏的。这个游戏的玩法如下: 该游戏使用
    
    

    话说,年仅19岁的帅气小伙子Gabriele Cirulli于2014年3月完成并发布在github上,游戏设计来自于《1024》,而《1024》灵感来源于《Threes!》的移动端游戏。然而游戏飙升的人气超乎他的想象,人们忘记了Flappy Bird, 2048成了 网络上“最上瘾的东西”。

    我是完全为了熟悉Cocos2d-x3.x版本,才写这个游戏的。这个游戏的玩法如下:

    该游戏使用方向键让方块上下左右移动。如果两个带有相同数字的方块在移动中碰撞,则它们会合并为一个方块,且所带数字变为两者之和。每次移动时,会有一个值为2或者4的新方块出现。当值为2048的方块出现时,游戏即胜利。

    游戏难度在于移动加合并的操作,其实也不难了,只是我觉得写的不优雅。要是不用lambda,那会更加难看。其他功能实现起来都没啥说的。当然还有很多地方是可以完善的。

    最后我还给这个游戏写了个AI,理论上可以达到很高的成功率。当时是晚上8点测试的,跑到晚上12点,平均一局需要移动1000次,如果每0.5秒一次,500秒一局,即一局需要大概8分钟。因为有出现的不仅仅是2,还可能是4,而且失败时肯定不需要这么多时间,不管怎样,测的结果不是很好。我想主要是因为效率不高吧,计算量较大,其次是跟电脑配置有关系了,毕竟每一步的时间间隔不能太久,测试时间不够长也是个原因。这个留个以后改进吧。

    最后,附上图片和源代码:



    ************************全民2048上线啦*************************


    源码地址:https://github.com/booirror/game-2048

    APK下载:http://apk.hiapk.com/appinfo/com.uboxsoft.puzzle/2

    注:

    1. 有多名网友反映,移动或合并后位置错误。我电脑上很正常,根据网友的反映,貌似移动结束后坐标变成0,0了,这问题终于解决了,是cocos版本导致的。我用的是3.3版本,最新版由于底层函数做了修改,从而出现了这个问题。代码稍后我会更新到github上(6月8号之前)。对此,我很感谢其中一位网友,名字就不说了,不确定他是否愿意透露名字。

    2. 适配问题。这个我承认是代码没写好,使用FIXED_WIDTH并修改相应坐标可以达到满意效果。

    3. 想编译出Android版的同学,需要自己修改Android.mk文件。

    (完)


    展开全文
  • 刚学Lua, 写个脚本试试看 [img=...实现了2048游戏逻辑,触摸事件,动画等 直接将248.lua文件放到cocos2dx的HelloLua项目中即可,窗口大小 480 * 640 下载地址:[url=http://downl
    实现了2048的游戏逻辑,触摸事件,动画等
    直接将248.lua文件放到cocos2dx的HelloLua项目中即可,窗口大小 480 * 640
    下载地址:点击打开链接
    运行效果

    展开全文
  • Cocos Creator7个小游戏合集2048、小鸟、 黄金矿工 、开心消消乐、 跑酷、 扫雷、 飞机大战
  • 程序目标:实现2048小游戏的玩法功能,并且初步了解使用cocos2dx编写程序 计划用时:3到5天 使用引擎:cocos2dx-3.6版本 操作系统:OS IDE:Xcode

    程序目标:实现2048小游戏的玩法功能,并且初步了解使用cocos2dx编写程序

    计划用时:3到5天

    使用引擎:cocos2dx-3.6版本

    操作系统:OS

    IDE:Xcode

    前言:第一个项目来点简单的,不需要美术资源的2048当然是第一选择。小游戏,简单直观易于拆解需求更是我菜鸡的福音。好了,废话少说,我们下面就开始2048的编写吧。

    需求分析: 1.游戏标题。

    2.累积的分数展示。

    3.重置按钮。

    4.4 * 4的底盘以及可以变化的"卡牌"



    1.0 界面布置

    从头脑中的原型到一个实际完成的项目,总是有许多弯路要走。正所谓万事开头难,怎么来开始这个项目正是菜鸡的第一个难题。我选择根据需求分析建立界面布局作为第一个步骤。这个是最简单的,最好入手的,而且可以马上给一个完整的游戏画面。这样一来,貌似还是有点成就感的。

    好,根据网上的各路大神给的教程,我终于成功的建立了一个空的项目。(卧槽,Run起来还真是不容易)

    迫不及待了,马上打开工程,进入classes略过AppDelegate直接杀进HelloWorldScene.h

    在头文件中定义各种变量方法。。搞起走!

    对了,在这之前我们得梳理一下到底我们开始要做什么,对了就是根据需求分析建立界面布局。那么到底有哪些需要布局呢?如需求分析所列,游戏标题,累积的分数,重置按钮。


    在HelloWorld.h中

    private:
        //记录分数
        int score;
        
        //标题展示板
        cocos2d::Label *title;
        
        //分数标题板
        cocos2d::Label *showLabel;
        
        //分数展示板
        cocos2d::Label *scoreLabel;
        
        //重置游戏
        cocos2d::Label *restartLabel;

    声明完成后,除开分数,这里还有三个Label需要摆放位置。唔...背景颜色需要设置,搞起!


    在HelloWorld.cpp中

        //分数初始化
        score = 0;
    
        //设置背景颜色
        auto BgColor = LayerColor::create(Color4B(180,170,160,255));
        this->addChild(BgColor);
        
        //摆放标题板
        title = Label::createWithTTF("My2048", "fonts/arial.ttf", 60);
        title->setColor(Color3B(255,255,153));
        title->setPosition(visibleSize.width / 2,visibleSize.height - 50);
        this->addChild(title);
        
        //摆放重置板
        restartLabel = Label::createWithTTF("Rest", "fonts/arial.ttf", 30);
        restartLabel->setColor(Color3B(200,255,250));
        restartLabel->setPosition(visibleSize.width / 2,visibleSize.height - 110);
        this->addChild(restartLabel);
        
        //摆放分数标题板
        showLabel = Label::createWithTTF("score", "fonts/arial.ttf", 30);
        showLabel->setPosition(visibleSize.width / 5,visibleSize.height - 150);
        this->addChild(showLabel);
        
        //摆放分数板
        scoreLabel = Label::createWithTTF("0", "fonts/arial.ttf", 30);
        scoreLabel->setPosition(visibleSize.width / 2 + 60,visibleSize.height - 110);
        this->addChild(scoreLabel);

    好了,到目前位置,菜鸡终于将这些板子都摆好了。运行一下看看效果,毕竟辛苦了半天,坐标可是用猜的。。。来,我们看看在Iphone4s模拟器上跑出来的效果。高清无码献给各位


    卧槽,好像有点不对。。这不是竖屏的,好把,继续查资料。发现了,要在工程设置中更改属性

    接着再来运行一下看看效果


    借用金星的一句话:“完美!”

    总结:1.不要在头文件中使用using namespace。  2.注意命名规范。 3.注释尽量详尽,前后格式要统一。 

    展开全文
  • 目录 关于cocos  cocos creator学习路线建议 ...要开发微信小游戏,需要选择 cocoscocos creator:cocos creator, 不要选择错了哦。 cocos creator的官方文档:cocos开发文档  注意事项:请注意c...

    目录

    关于cocos 

    cocos creator学习路线建议

    cocos creator 发布微信小游戏

    解决问题的方法:


    关于cocos 

    cocos 的官方网址:cocos 引擎

    要开发微信小游戏,需要选择 cocos的cocos creator:cocos creator, 不要选择错了哦。

    cocos creator的官方文档:cocos开发文档  

    注意事项:请注意cocos creator文档所对应的版本号,由于2.X版本与1.X版本做了比较大的改动,版本选择见下图红框所示

    cocos creator文档版本选择

     

    cocos creator学习路线建议

    首先浏览cocos creator官方文档中的 新手上路 与 基本工作流程,按照文档中的说明搭建开发环境后,可以跑一遍cocos creator自带的示例工程。

    cocos creator新建工程

     

    cocos creator 发布微信小游戏

    发布到微信: 发布微信小游戏

     

    解决问题的方法:

    所有开发中的细节内容,cocos creator 官方文档说的都比较清楚了。此篇文章适合未接触过cocos creator的人打开学习之门,以及提供一个学习的思路。

    学习任何一门语言或者知识,最好的方法就是查阅官方文档和加入官方的社区论坛。

    当开发过程中碰到无法解决的问题时,多数的问题都可以官方的论坛中找到答案。如不能,可以向官方的技术支持发邮件咨询。

    最后才是百度一下,适合百度解决的多数是普遍性大众化的问题。小概率发生的问题最好找论坛。

    展开全文
  • 本课程以实战为主,游戏中需要什么功能,我们就讲解相应的知识点,这样学到的知识会马上用起来也就不会枯燥。 本课程讲解相当完整,从最基础的软件安装开始,到最后打出安卓apk,一套完整的课程讲解。 ...
  • 整合了多个小游戏 供大家分享 2048 傻鸟. 消消乐等6个小程序. cocoscreator 实现. 可直接运行 大家互相学习
  •  小游戏cocos creator场景图结构 代码文件 小游戏完整工程 小游戏介绍 一个左右跳一跳小游戏,点屏幕左边向左跳,点右边向右跳,落水为失败。 PC chrome浏览器下游戏截图: chrome浏览器运行截图微信开发者...
  • cocos2dx-js 发布小游戏

    2018-04-08 16:07:58
    前言:由于公司当下的产品是用cocos2dx-js 3.9写的 产品刚得到认可突然间小游戏问世所以就得转战小游戏领域 了解到cocos官方 creator1.8最新的编辑器可以直接发布小游戏但是编码习惯以及产品大规模都得转线好在官方...
  • Cocos2d-JS 适配小游戏

    2018-07-26 10:48:39
    Cocos2d-JS 适配小游戏版本来了!   Cocos 老友们无须一直担心 「Cocos2d-JS 开发的游戏能否适配到小游戏上面」, 答案是:当然可以!第一波上线的游戏里面,既有用 Cocos Creator,也有老游戏用 Cocos2d-JS。...
  • 一、介绍 Cocos2d-JS是Cocos2d-x的Javascript版本,它的前身是Cocos2d...我们知道Cocos2d-x支持使用C++、Lua、Javascript来进行程序开发,其所内置的是一个Javascript引擎,通过用C++解析Javascript去执行;而Cocos2d-h
  • 目录 我的开发环境: 使用cocos creator开发中涉及的主要内容: ...3 游戏过程中要避免频繁的创建与销毁对象。在PC浏览器上测试时可能帧率比较稳定看不出来,发布到微信上就会比较明显了。 4:关于c...
  • CocosCreator在1.8版本开始,就支持一键发布微信小程序,下面是详细的发布步骤: 1、在微信公众平台下载微信开发者工具; 地址:... 小游戏开发:https://developers.weixin...
  • 最近微信小游戏开始萌芽,根据老师的要求开始学习cocos creator紧跟互联网的潮流,先是花了几天大概学了学HTML/CSS/Javascript,之后就直接开始看cocos creator的官方文档,看了两三天总算是根据教程一步一步的做了...
1 2 3 4 5 ... 20
收藏数 25,116
精华内容 10,046