打包好的APK:http://pan.baidu.com/share/link?shareid=847502897&uk=185595768
游戏分析请看【Android重制2048】
打包方法:
(1)将工程导入eclipse中(记得将xml文档中调成竖屏模式)
(2)将VS工程中的D:\hello\Card\cocos2d\cocos\2d\platform\android\java\src里的org文件夹拖进eclipse的src
(3)修改eclipse工程中jni文件下的Android.mk文件
参考:http://blog.youkuaiyun.com/gf771115/article/details/34414449
(4)打开CMD,运行到VS工程中的proj.android下,执行Build_native.py
(5)成功后重新导入工程到eclipse中
(6)最后导出apk
效果:
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::createWithRect("My2048",Rect(0,0,286,512),1.0f);
- director->setOpenGLView(glview);
- }
- //分辨率适应
- glview->setDesignResolutionSize(268,512,ResolutionPolicy::EXACT_FIT);
- director->setDisplayStats(true);
- director->setAnimationInterval(1.0 / 60);
- auto scene = HelloWorld::createScene();
- director->runWithScene(scene);
- return true;
- }
- void AppDelegate::applicationDidEnterBackground() {
- Director::getInstance()->stopAnimation();
- }
- void AppDelegate::applicationWillEnterForeground() {
- Director::getInstance()->startAnimation();
- }
2.游戏主场景
HelloWorld.h
- #ifndef __HELLOWORLD_SCENE_H__
- #define __HELLOWORLD_SCENE_H__
- #include "cocos2d.h"
- #include "Card.h"
- USING_NS_CC;
- class HelloWorld : public Layer
- {
- public:
- static Scene* createScene();
- virtual bool init();
- void menuCloseCallback(Ref* pSender);
- CREATE_FUNC(HelloWorld);
- //自动生成卡片
- void autoCreateCard();
- //判断是否游戏结束
- void checkGameOver();
- //判断是否移动
- bool isMoveLeft();
- bool isMoveRight();
- bool isMoveUp();
- bool isMoveDown();
- private:
- //记录按下时坐标和偏移量
- float startX,startY,offsetX,offsetY;
- //创建触控监听
- bool onTouchBegan(Touch *t, Event *e);
- void onTouchEnded(Touch *t, Event *e);
- //创建卡片
- void createCard(Size size);
- //储存卡片的二维数组,以便控制每一张卡片
- Card* cardArr[4][4];
- //游戏分数
- int score ;
- //显示分数的控件
- LabelTTF *scoreLabel;
- //设置重新开始游戏按钮
- LabelTTF *restartBtn;
- };
- #endif // __HELLOWORLD_SCENE_H__
HelloWorld.cpp
- #include "HelloWorldScene.h"
- USING_NS_CC;
- Scene* HelloWorld::createScene()
- {
- auto scene = Scene::create();
- auto layer = HelloWorld::create();
- scene->addChild(layer);
- return scene;
- }
- bool HelloWorld::init()
- {
- if ( !Layer::init() )
- {
- return false;
- }
- Size visibleSize = Director::getInstance()->getVisibleSize();
- Point origin = Director::getInstance()->getVisibleOrigin();
- //加入游戏背景
- auto layerClourBG = LayerColor::create(Color4B(180,170,160,255));
- this->addChild(layerClourBG);
- //加入游戏标题
- auto title = LabelTTF::create("My2048","Arial",60);
- title->setColor(Color3B(255,255,153));
- title->setPosition(Point(visibleSize.width/2,visibleSize.height-50));
- addChild(title);
- //加入restart按钮
- restartBtn = LabelTTF::create("Restart","Arial",30);
- restartBtn->setColor(Color3B(204,255,253));
- restartBtn->setPosition(Point(visibleSize.width/2,visibleSize.height-110));
- addChild(restartBtn);
- //加入游戏分数
- auto slabel = LabelTTF::create("Score","Arial",30);
- slabel->setPosition(Point(visibleSize.width/5,visibleSize.height-150));
- addChild(slabel);
- score = 0;
- scoreLabel = LabelTTF::create("0","Arial",30);
- scoreLabel->setPosition(Point(visibleSize.width/2+60,visibleSize.height-150));
- addChild(scoreLabel);
- //创建触控监听
- auto listener = EventListenerTouchOneByOne::create();
- listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan,this);
- listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded,this);
- _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
- //调用卡片生成方法
- createCard(visibleSize);
- //一开始生成随机数
- autoCreateCard();
- autoCreateCard();
- return true;
- }
- bool HelloWorld::onTouchBegan(Touch *t, Event *e)
- {
- //记录开始点击的坐标
- Point startPoint = t->getLocation();
- startX = startPoint.x;
- startY = startPoint.y;
- if(restartBtn->getBoundingBox().containsPoint(restartBtn->convertToNodeSpace(t->getLocation())))
- {
- Director::getInstance()->replaceScene(TransitionFade::create(1,HelloWorld::createScene()));
- }
- return true;
- }
- void HelloWorld::onTouchEnded(Touch *t, Event *e)
- {
- //计算出偏移量,用于判断用户的滑动方向意图
- Point endPoint = t->getLocation();
- offsetX = startX - endPoint.x;
- offsetY = startY - endPoint.y;
- //如果X轴的偏移量比Y轴的大,则说明是水平方向的滑动
- if(abs(offsetX) > abs(offsetY))
- {
- //向左滑动
- if(offsetX > -5){
- if(isMoveLeft())
- //调用生成随机数
- autoCreateCard();
- //判断游戏是否结束
- checkGameOver();
- }
- //向右滑动
- else{
- if(isMoveRight())
- autoCreateCard();
- checkGameOver();
- }
- }
- else
- {
- //向上滑动
- if(offsetY > -5){
- if(isMoveUp())
- autoCreateCard();
- checkGameOver();
- }
- //向下滑动
- else{
- if(isMoveDown())
- autoCreateCard();
- checkGameOver();
- }
- }
- }
- //逻辑一样,只需实现一个方向的逻辑,其他复制修改就好了
- bool HelloWorld::isMoveLeft()
- {
- bool moved = false;
- 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--;
- moved = true;
- }else if(cardArr[x][y]->getNumber() == cardArr[x1][y]->getNumber())
- {//当前位置不为空,而且同一行有数字,相同的就叠加,并清空原位置
- cardArr[x][y]->setNumber(cardArr[x1][y]->getNumber()*2);
- cardArr[x1][y]->setNumber(0);
- //合并时同时加分
- score += (cardArr[x][y]->getNumber());
- scoreLabel->setString(__String::createWithFormat("%i",score)->getCString());
- moved = true;
- }
- break;
- }
- }
- }
- }
- return moved;
- }
- bool HelloWorld::isMoveRight()
- {
- bool moved = false;
- 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());
- cardArr[x1][y]->setNumber(0);
- //再扫描一次,确保所有结果正确
- x++;
- moved = true;
- }
- else if(cardArr[x][y]->getNumber() == cardArr[x1][y]->getNumber())
- {//当前位置不为空,而且同一行有数字,相同的就叠加,并清空原位置
- cardArr[x][y]->setNumber((cardArr[x1][y]->getNumber())*2);
- cardArr[x1][y]->setNumber(0);
- score += (cardArr[x][y]->getNumber());
- scoreLabel->setString(__String::createWithFormat("%i",score)->getCString());
- moved = true;
- }
- break;
- }
- }
- }
- }
- return moved;
- }
- bool HelloWorld::isMoveUp()
- {
- bool moved = false;
- 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--;
- moved = true;
- }
- else if(cardArr[x][y]->getNumber() == cardArr[x][y1]->getNumber())
- {//当前位置不为空,而且同一行有数字,相同的就叠加,并清空原位置
- cardArr[x][y]->setNumber((cardArr[x][y1]->getNumber())*2);
- cardArr[x][y1]->setNumber(0);
- score += (cardArr[x][y]->getNumber());
- scoreLabel->setString(__String::createWithFormat("%i",score)->getCString());
- moved = true;
- }
- break;
- }
- }
- }
- }
- return moved;
- }
- bool HelloWorld::isMoveDown()
- {
- bool moved = false;
- 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++;
- moved = true;
- }
- else if(cardArr[x][y]->getNumber() == cardArr[x][y1]->getNumber())
- {//当前位置不为空,而且同一行有数字,相同的就叠加,并清空原位置
- cardArr[x][y]->setNumber((cardArr[x][y1]->getNumber())*2);
- cardArr[x][y1]->setNumber(0);
- score += (cardArr[x][y]->getNumber());
- scoreLabel->setString(__String::createWithFormat("%i",score)->getCString());
- moved = true;
- }
- break;
- }
- }
- }
- }
- return moved;
- }
- void HelloWorld::createCard(Size size)
- {
- //求出单元格的宽高
- int cardLen = (size.width-20)/4;
- //4*4单元格
- for (int i = 0; i < 4; i++)
- {
- for (int j = 0; j < 4; j++)
- {
- Card *cards = Card::createCard(0,cardLen,cardLen,cardLen*i+12,cardLen*j+12+size.height/6);
- addChild(cards);
- //把卡片存在一个二维数组里面
- cardArr[i][j] = cards;
- }
- }
- }
- void HelloWorld::autoCreateCard()
- {
- //随机生成横坐标和纵坐标
- int row = CCRANDOM_0_1()*4;
- int col = CCRANDOM_0_1()*4;
- //判断位置是否已经存在数字
- if(cardArr[row][col]->getNumber() > 0)
- {
- autoCreateCard();
- }
- else
- { //4出现的几率是%10
- cardArr[row][col]->setNumber(CCRANDOM_0_1()*10<1?4:2);
- }
- }
- 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
- }
- void HelloWorld::checkGameOver()
- {
- 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()))||
- (y<3 && (cardArr[x][y]->getNumber() == cardArr[x][y+1]->getNumber()))){
- isGameOver = false;//满足以上条件则游戏继续
- }
- }
- }
- if(isGameOver)
- {
- Director::getInstance()->replaceScene(TransitionFade::create(1,HelloWorld::createScene()));
- }
- }
3.游戏卡片精灵类
Card.h
- #include "cocos2d.h"
- USING_NS_CC;
- class Card : public Sprite
- {
- public:
- //初始化框架三件套
- static Card* createCard(int num, int cardWeight, int cardHeight, float positionX, float positionY);
- virtual bool init();
- CREATE_FUNC(Card);
- //设置数字并显示的方法
- void setNumber(int num);
- //获取数字的方法
- int getNumber();
- private:
- //卡片中的数字
- int number;
- void cardInit(int num, int cardWeight, int cardHeight, float positionX, float positionY);
- //用于显示数字的控件
- LabelTTF *cardLabel;
- //控件的背景颜色
- LayerColor *cardBgColour;
- };
Card.cpp
- #include "Card.h"
- USING_NS_CC;
- Card* Card::createCard(int num, int cardWeight, int cardHeight, float positionX, float positionY)
- {
- Card* card = new Card();
- if(card && card->init())
- {
- card->autorelease();
- card->cardInit(num,cardWeight,cardHeight,positionX,positionY);
- return card;
- }
- CC_SAFE_DELETE(card);
- return NULL;
- }
- bool Card::init()
- {
- if(!Sprite::init())
- return false;
- return true;
- }
- void Card::setNumber(int num)
- {
- number = num;
- //设置字体的大小
- if(number >= 0 && number < 16)
- {
- cardLabel->setFontSize(50);
- }
- if(number >= 16 && number < 128)
- {
- cardLabel->setFontSize(40);
- }
- if(number >= 128 && number < 1024)
- {
- cardLabel->setFontSize(30);
- }
- if(number >= 1024)
- {
- cardLabel->setFontSize(20);
- }
- //设置数字颜色
- if(number == 0){
- cardBgColour->setColor(Color3B(200,190,180));
- }
- if(number == 2){
- cardBgColour->setColor(Color3B(240,230,220));
- }
- if(number == 4){
- cardBgColour->setColor(Color3B(51,153,51));
- }
- if(number == 8){
- cardBgColour->setColor(Color3B(255,153,102));
- }
- if(number == 16){
- cardBgColour->setColor(Color3B(153,204,153));
- }
- if(number == 32){
- cardBgColour->setColor(Color3B(153,204,255));
- }
- if(number == 64){
- cardBgColour->setColor(Color3B(255,204,204));
- }
- if(number == 128){
- cardBgColour->setColor(Color3B(204,102,0));
- }
- if(number == 256){
- cardBgColour->setColor(Color3B(153,204,51));
- }
- if(number == 512){
- cardBgColour->setColor(Color3B(255,102,102));
- }
- if(number == 1024){
- cardBgColour->setColor(Color3B(204,204,255));
- }
- if(number == 2048){
- cardBgColour->setColor(Color3B(255,204,00));
- }
- //显示数字
- if(number > 0)
- cardLabel->setString(__String::createWithFormat("%d",number)->getCString());
- else
- cardLabel->setString("");
- }
- int Card::getNumber()
- {
- return number;
- }
- void Card::cardInit(int num, int cardWeight, int cardHeight, float positionX, float positionY)
- {
- number = num;
- //添加卡片背景颜色
- cardBgColour = LayerColor::create(Color4B(200,190,180,255),cardWeight-5,cardHeight-5);
- cardBgColour->setPosition(Point(positionX,positionY));
- //判断num是否大于0,是就显示,否则显示空
- if(num > 0)
- {
- //设置字体
- cardLabel = LabelTTF::create(__String::createWithFormat("%d",number)->getCString(),"Arial",50);
- cardLabel->setPosition(Point(cardBgColour->getContentSize().width/2,cardBgColour->getContentSize().height/2));
- cardBgColour->addChild(cardLabel);
- }
- else
- {
- cardLabel = LabelTTF::create("","Arial",50);
- cardLabel->setPosition(Point(cardBgColour->getContentSize().width/2,cardBgColour->getContentSize().height/2));
- cardBgColour->addChild(cardLabel);
- }
- this->addChild(cardBgColour);
- }
FROM: http://blog.youkuaiyun.com/ns2250225/article/details/39697373