您的位置:首页 > 移动开发 > Cocos引擎

Cocos2dx制作2048(2.数字方块的创建)

2016-03-12 21:42 288 查看
我们今天来完成数字方块的创建以及把方块添加到主场景中,完成4行4列矩阵方块的添加

1.数字方块的创建

1.1 新增方块精灵

我们在Classes目录上右键添加新建项,如下图



注意,点击浏览,统一把代码放到Classes目录下,

一次添加源文件

如图



1.2 分析游戏,编写方块精灵头文件

第一步:首先我们的数字方块其实就是一个一个的精灵,总共是4X4=16个精灵,所以我们的SquareSprite类是继承与CCSprite的

#ifndef _SQUARE_SPRITE_H_

#define _SQUARE_SPRITE_H_

#include "cocos2d.h"

using namespace cocos2d;

class SquareSprite:public CCSprite

{

public:

SquareSprite();

private:

};

#endif // !_SQUARE_SPRITE_H_

第二步:创建的方块需要多大?方块需要摆放在什么位置上?16个方块都是在不同位置的,然后,方块显示的数字是多少?

分析 得出,我们需要定义几个变量和方块创建的方法

变量:m_number(方块中的数字)

m_lablenumber(显示数字的标签)

m_layercolor(带颜色的层,用于显示方块)

形参:pointx(方块的X轴)

pointy(方块的Y轴)

width(方块的宽度)

height(方块的高度)

方法:createSquareSprite(创建方块精灵的方法)

initSquareSprite(初始化方块精灵的方法)

getNumber(获得方块中数字)setNumber

#ifndef _SQUARE_SPRITE_H_

#define _SQUARE_SPRITE_H_

#include "cocos2d.h"

using namespace cocos2d;

class SquareSprite:public CCSprite

{

public:

SquareSprite();

static SquareSprite* createSquareSprite(int number,float pointx,float pointy,int width,int height);

int getNumber();

void setNumber(int number);

CREATE_FUNC(SquareSprite);

private:

int m_number;

CCLabelTTF* m_lablenumber;

CCLayerColor* m_layercolor;

void initSquareSprite(int number,float pointx,float pointy,int width,int height);

};

#endif // !_SQUARE_SPRITE_H_

1.3 编写方块精灵的实现

一个个来实现

第一:实现构造函数,初始化成员变量

#include "SquareSprite.h"

SquareSprite::SquareSprite()

:m_number(0)

,m_lablenumber(NULL)

,m_layercolor(NULL)

{

}

第二

:实现创建方块精灵的函数(creteSquareSprite)

我们可以在基类CCSprite中找到create源码,复制一份,在改成如下:

SquareSprite* SquareSprite::createSquareSprite(int number,float pointx,float pointy,int width,int height)

{

SquareSprite *pSprite = new SquareSprite();

if (pSprite && pSprite->init())

{

pSprite->autorelease();

return pSprite;

}

CC_SAFE_DELETE(pSprite);

return NULL;

}

第三:实现getNumber和setNumber

int SquareSprite::getNumber()

{

return m_number;

}

void SquareSprite::setNumber(int number)

{

m_number=number;

m_lablenumber->setString("");

if (m_number>0)

{

m_lablenumber->setString(CCString::createWithFormat("%i",m_number)->getCString());

}

}

第四

:实现initSquareSprite

void SquareSprite::initSquareSprite(int number,float pointx,float pointy,int width,int height)

{

m_number=number;

m_layercolor=CCLayerColor::create(ccc4(200,190,180,255),width,height);

m_layercolor->setPosition(ccp(pointx,pointy));

this->addChild(m_layercolor);

//创建字体

m_lablenumber=CCLabelTTF::create("","arial.ttf",50);

m_lablenumber->setColor(ccc3(0,0,0));

m_lablenumber->setPosition(ccp(m_layercolor->getContentSize().width/2,m_layercolor->getContentSize().height/2));

m_layercolor->addChild(m_lablenumber);

setNumber(number);

}

第五:修改createSquareSprite和HelloWorldScene中的init

测试创建的精灵

此时createSquareSprite代码如下:

SquareSprite* SquareSprite::createSquareSprite(int number,float pointx,float pointy,int width,int height)

{

SquareSprite *pSprite = new SquareSprite();

if (pSprite && pSprite->init())

{

pSprite->autorelease();

pSprite->initSquareSprite( number, pointx, pointy, width, height);

return pSprite;

}

CC_SAFE_DELETE(pSprite);

return NULL;

}

HelloWorld:Scene.cpp中的init如下:

bool HelloWorld::init()

{

//////////////////////////////

// 1. super init first

if ( !CCLayer::init() )

{

return false;

}

CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();

CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

SquareSprite* pSquareSprite=SquareSprite::createSquareSprite(2,50,50,100,100);

this->addChild(pSquareSprite);

return true;

}

运行看看效果:



还不错,呵呵

我们再来优化优化方块,不同的字体显示不同的颜色

第六:修改setNumber,优化方块颜色

void SquareSprite::setNumber(int number)

{

m_number=number;

m_lablenumber->setString("");

m_layercolor->setColor(ccc3(200,190,180));

if (m_number>0)

{

m_lablenumber->setString(CCString::createWithFormat("%i",m_number)->getCString());

//设置卡片颜色

switch (m_number)

{

case 2:

m_layercolor->setColor(ccc3(255,245,238));

break;

case 32:

case 4:

m_layercolor->setColor(ccc3(255,0,0));

break;

case 8:

m_layercolor->setColor(ccc3(244,164,96));

break;

case 16:

m_layercolor->setColor(ccc3(255,69,0));

break;

case 64:

m_layercolor->setColor(ccc3(250,128,114));

break;

case 128:

m_layercolor->setColor(ccc3(255,228,181));

break;

case 256:

m_layercolor->setColor(ccc3(240,230,140));

break;

case 512:

m_layercolor->setColor(ccc3(255,250,205));

break;

case 1024:

m_layercolor->setColor(ccc3(255,160,122));

break;

case 2048:

m_layercolor->setColor(ccc3(250,240,230));

break;

case 4096:

m_layercolor->setColor(ccc3(255,228,225));

break;

case 8192:

m_layercolor->setColor(ccc3(188,143,143));

break;

case 16384:

m_layercolor->setColor(ccc3(205,92,92));

break;

default:

break;

}

}

}

现在我们改下number的值看看效果



嗯,最终修改完成后,我们的方块代码头文件如下:

#ifndef _SQUARE_SPRITE_H_

#define _SQUARE_SPRITE_H_

#include "cocos2d.h"

using namespace cocos2d;

class SquareSprite:public CCSprite

{

public:

SquareSprite();

static SquareSprite* createSquareSprite(int number,float pointx,float pointy,int width,int height);

int getNumber();

void setNumber(int number);

CREATE_FUNC(SquareSprite);

private:

int m_number;

CCLabelTTF* m_lablenumber;

CCLayerColor* m_layercolor;

void initSquareSprite(int number,float pointx,float pointy,int width,int height);

};

#endif // !_SQUARE_SPRITE_H_

源文件:

#include "SquareSprite.h"

SquareSprite::SquareSprite()

:m_number(0)

,m_lablenumber(NULL)

,m_layercolor(NULL)

{

}

SquareSprite* SquareSprite::createSquareSprite(int number,float pointx,float pointy,int width,int height)

{

SquareSprite *pSprite = new SquareSprite();

if (pSprite && pSprite->init())

{

pSprite->autorelease();

pSprite->initSquareSprite( number, pointx, pointy, width, height);

return pSprite;

}

CC_SAFE_DELETE(pSprite);

return NULL;

}

int SquareSprite::getNumber()

{

return m_number;

}

void SquareSprite::setNumber(int number)

{

m_number=number;

m_lablenumber->setString("");

m_layercolor->setColor(ccc3(200,190,180));

if (m_number>0)

{

m_lablenumber->setString(CCString::createWithFormat("%i",m_number)->getCString());

//设置卡片颜色

switch (m_number)

{

case 2:

m_layercolor->setColor(ccc3(255,245,238));

break;

case 32:

case 4:

m_layercolor->setColor(ccc3(255,0,0));

break;

case 8:

m_layercolor->setColor(ccc3(244,164,96));

break;

case 16:

m_layercolor->setColor(ccc3(255,69,0));

break;

case 64:

m_layercolor->setColor(ccc3(250,128,114));

break;

case 128:

m_layercolor->setColor(ccc3(255,228,181));

break;

case 256:

m_layercolor->setColor(ccc3(240,230,140));

break;

case 512:

m_layercolor->setColor(ccc3(255,250,205));

break;

case 1024:

m_layercolor->setColor(ccc3(255,160,122));

break;

case 2048:

m_layercolor->setColor(ccc3(250,240,230));

break;

case 4096:

m_layercolor->setColor(ccc3(255,228,225));

break;

case 8192:

m_layercolor->setColor(ccc3(188,143,143));

break;

case 16384:

m_layercolor->setColor(ccc3(205,92,92));

break;

default:

break;

}

}

}

void SquareSprite::initSquareSprite(int number,float pointx,float pointy,int width,int height)

{

m_number=number;

m_layercolor=CCLayerColor::create(ccc4(200,190,180,255),width,height);

m_layercolor->setPosition(ccp(pointx,pointy));

this->addChild(m_layercolor);

//创建字体

m_lablenumber=CCLabelTTF::create("","arial.ttf",50);

m_lablenumber->setColor(ccc3(0,0,0));

m_lablenumber->setPosition(ccp(m_layercolor->getContentSize().width/2,m_layercolor->getContentSize().height/2));

m_layercolor->addChild(m_lablenumber);

setNumber(number);

}

添加方块到主场景

2.1 修改整个窗体的大小,让它更像手机竖屏

main.cpp中的这么一句

eglView->setFrameSize(320, 480);

设置FPS隐藏,AppDelagate.cpp中

pDirector->setDisplayStats(false);



有点像了哼

2.2 新增方法用来初始化4X4矩阵

首先我们根据下图来分析一下,因为我们的方块得根据手机屏幕来自适应的,所以不能像测试一样给定死咯



我们的窗体是320宽度,其中每个方块之间的间隔是10,故而,我们得出计算方块的算法是什么呢??

很简单: (窗体的宽度-5*间隔)/4

大小计算出来了,然后双重循环遍历,创建方块

在创建的时候,还记得我们有什么参数吗??

现在我们缺少的参数有,方块位置的起点

怎么破呢??

这里需要注意,我们用了Layer作为精灵,CCLayer的锚点不是0.5了 而是0 即左下角

起点X的算法:

空隙+方块的横向下标*方块的宽度+方块的横向下标*空隙

不理解??上图



起点Y的算法: 这个其实和X是一样的,这里最下面一片的这个间隔可以自己调,这个不能居中,因为最后我们还得在顶部增加用了显示总分数的

// on "init" you need to initialize your instance

bool HelloWorld::init()

{

//////////////////////////////

// 1. super init first

if ( !CCLayer::init() )

{

return false;

}

CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();

CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

initMatrix(visibleSize);

return true;

}

void HelloWorld::initMatrix(CCSize size)

{

//两个方块之间的空隙

int space=10;

int SquareSize=(size.width-space*5)/4;

for (int x = 0; x < 4; x++)

{

for (int y = 0; y < 4; y++)

{

float pointx=space+x*SquareSize+x*space;

float pointy=40+y*SquareSize+y*space;

SquareSprite* pSquareSprite=SquareSprite::createSquareSprite(0,pointx,pointy,SquareSize,SquareSize);

this->addChild(pSquareSprite);

}

}

}



当然,你如果觉得太挤了也可以改成这样:

void HelloWorld::initMatrix(CCSize size)

{

//两个方块之间的空隙

int space=10;

//2*20 最左边和最右边的空隙

int SquareSize=(size.width-space*3-2*20)/4;

for (int x = 0; x < 4; x++)

{

for (int y = 0; y < 4; y++)

{

float pointx=20+x*SquareSize+x*space;

float pointy=40+y*SquareSize+y*space;

SquareSprite* pSquareSprite=SquareSprite::createSquareSprite(0,pointx,pointy,SquareSize,SquareSize);

this->addChild(pSquareSprite);

}

}

}

2.3 定义数组用了存储每个方块

//二维数组存储方块

SquareSprite* m_squarearray[4][4];

void HelloWorld::initMatrix(CCSize size)

{

//两个方块之间的空隙

int space=10;

int SquareSize=(size.width-space*5)/4;

for (int x = 0; x < 4; x++)

{

for (int y = 0; y < 4; y++)

{

float pointx=space+x*SquareSize+x*space;

float pointy=40+y*SquareSize+y*space;

SquareSprite* pSquareSprite=SquareSprite::createSquareSprite(0,pointx,pointy,SquareSize,SquareSize);

this->addChild(pSquareSprite);

m_squarearray[x][y]=pSquareSprite;

}

}

}

2.4 创建随机产生方块的方法 (其实就是随机产生数字而已)

void HelloWorld::initMatrix(CCSize size)

{

//两个方块之间的空隙

int space=10;

int SquareSize=(size.width-space*5)/4;

for (int x = 0; x < 4; x++)

{

for (int y = 0; y < 4; y++)

{

float pointx=space+x*SquareSize+x*space;

float pointy=40+y*SquareSize+y*space;

SquareSprite* pSquareSprite=SquareSprite::createSquareSprite(0,pointx,pointy,SquareSize,SquareSize);

this->addChild(pSquareSprite);

m_squarearray[x][y]=pSquareSprite;

}

}

//刚开始游戏,创建两个方块

autoSquare();

autoSquare();

}

void HelloWorld::autoSquare()

{

int x=CCRANDOM_0_1()*4;

int y=CCRANDOM_0_1()*4;

if (m_squarearray[x][y]->getNumber()>0)

{

autoSquare();

}

else

{

m_squarearray[x][y]->setNumber(2);

}

}

2.5 搞点背景色

//搞点背景

CCLayerColor* layerColorBG= CCLayerColor::create(ccc4(180,170,160,255));

this->addChild(layerColorBG,0);



最后代码就不传了,反正也没用到任何资源,就直接贴出来算了

SquareSprite.h

#ifndef _SQUARE_SPRITE_H_

#define _SQUARE_SPRITE_H_

#include "cocos2d.h"

using namespace cocos2d;

class SquareSprite:public CCSprite

{

public:

SquareSprite();

static SquareSprite* createSquareSprite(int number,float pointx,float pointy,int width,int height);

int getNumber();

void setNumber(int number);

CREATE_FUNC(SquareSprite);

private:

int m_number;

CCLabelTTF* m_lablenumber;

CCLayerColor* m_layercolor;

void initSquareSprite(int number,float pointx,float pointy,int width,int height);

};

#endif // !_SQUARE_SPRITE_H_

SquareSprite.cpp

#include "SquareSprite.h"

SquareSprite::SquareSprite()

:m_number(0)

,m_lablenumber(NULL)

,m_layercolor(NULL)

{

}

SquareSprite* SquareSprite::createSquareSprite(int number,float pointx,float pointy,int width,int height)

{

SquareSprite *pSprite = new SquareSprite();

if (pSprite && pSprite->init())

{

pSprite->autorelease();

pSprite->initSquareSprite( number, pointx, pointy, width, height);

return pSprite;

}

CC_SAFE_DELETE(pSprite);

return NULL;

}

int SquareSprite::getNumber()

{

return m_number;

}

void SquareSprite::setNumber(int number)

{

m_number=number;

m_lablenumber->setString("");

m_layercolor->setColor(ccc3(200,190,180));

if (m_number>0)

{

m_lablenumber->setString(CCString::createWithFormat("%i",m_number)->getCString());

//设置卡片颜色

switch (m_number)

{

case 2:

m_layercolor->setColor(ccc3(255,245,238));

break;

case 32:

case 4:

m_layercolor->setColor(ccc3(255,0,0));

break;

case 8:

m_layercolor->setColor(ccc3(244,164,96));

break;

case 16:

m_layercolor->setColor(ccc3(255,69,0));

break;

case 64:

m_layercolor->setColor(ccc3(250,128,114));

break;

case 128:

m_layercolor->setColor(ccc3(255,228,181));

break;

case 256:

m_layercolor->setColor(ccc3(240,230,140));

break;

case 512:

m_layercolor->setColor(ccc3(255,250,205));

break;

case 1024:

m_layercolor->setColor(ccc3(255,160,122));

break;

case 2048:

m_layercolor->setColor(ccc3(250,240,230));

break;

case 4096:

m_layercolor->setColor(ccc3(255,228,225));

break;

case 8192:

m_layercolor->setColor(ccc3(188,143,143));

break;

case 16384:

m_layercolor->setColor(ccc3(205,92,92));

break;

default:

break;

}

}

}

void SquareSprite::initSquareSprite(int number,float pointx,float pointy,int width,int height)

{

m_number=number;

m_layercolor=CCLayerColor::create(ccc4(200,190,180,255),width,height);

m_layercolor->setPosition(ccp(pointx,pointy));

this->addChild(m_layercolor);

//创建字体

m_lablenumber=CCLabelTTF::create("","arial.ttf",30);

m_lablenumber->setColor(ccc3(0,0,0));

m_lablenumber->setPosition(ccp(m_layercolor->getContentSize().width/2,m_layercolor->getContentSize().height/2));

m_layercolor->addChild(m_lablenumber);

setNumber(number);

}

HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__

#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

#include "SimpleAudioEngine.h"

#include "SquareSprite.h"

using namespace CocosDenshion;

using namespace cocos2d;

class HelloWorld : public cocos2d::CCLayer

{

public:

HelloWorld();

// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone

virtual bool init();

// there's no 'id' in cpp, so we recommend returning the class instance pointer

static cocos2d::CCScene* scene();

// implement the "static node()" method manually

CREATE_FUNC(HelloWorld);

public:

virtual void onEnter();

virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);

virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);

//上下左右滑动时调用

bool doTop();

bool doDown();

bool doReight();

bool doLeft();

//初始化矩阵

void initMatrix(CCSize size);

//随机产生方块

void autoSquare();

private:

//启点的X坐标,Y坐标

//起点到终点X的距离,Y的距离

int m_StartX,m_StartY,m_RangeX,m_RangeY;

//二维数组存储方块

SquareSprite* m_squarearray[4][4];

};

#endif // __HELLOWORLD_SCENE_H__

HelloWorldScene.cpp

#include "HelloWorldScene.h"

USING_NS_CC;

HelloWorld::HelloWorld()

:m_StartX(0)

,m_StartY(0)

,m_RangeX(0)

,m_RangeY(0)

{

}

CCScene* HelloWorld::scene()

{

// 'scene' is an autorelease object

CCScene *scene = CCScene::create();

// 'layer' is an autorelease object

HelloWorld *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 ( !CCLayer::init() )

{

return false;

}

CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();

CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

initMatrix(visibleSize);

//搞点背景

CCLayerColor* layerColorBG= CCLayerColor::create(ccc4(180,170,160,255));

this->addChild(layerColorBG,0);

return true;

}

void HelloWorld::initMatrix(CCSize size)

{

//两个方块之间的空隙

int space=10;

int SquareSize=(size.width-space*5)/4;

for (int x = 0; x < 4; x++)

{

for (int y = 0; y < 4; y++)

{

float pointx=space+x*SquareSize+x*space;

float pointy=40+y*SquareSize+y*space;

SquareSprite* pSquareSprite=SquareSprite::createSquareSprite(0,pointx,pointy,SquareSize,SquareSize);

this->addChild(pSquareSprite,1);

m_squarearray[x][y]=pSquareSprite;

}

}

//刚开始游戏,创建两个方块

autoSquare();

autoSquare();

}

void HelloWorld::autoSquare()

{

int x=CCRANDOM_0_1()*4;

int y=CCRANDOM_0_1()*4;

if (m_squarearray[x][y]->getNumber()>0)

{

autoSquare();

}

else

{

m_squarearray[x][y]->setNumber(2);

}

}

void HelloWorld::onEnter()

{

CCLayer::onEnter();

this->setTouchMode(kCCTouchesOneByOne);

this->setTouchEnabled(true);

}

bool HelloWorld::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)

{

m_StartX=pTouch->getLocation().x;

m_StartY=pTouch->getLocation().y;

return true;

}

void HelloWorld::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)

{

CCPoint point= pTouch->getLocation();

m_RangeX=m_StartX-point.x;

m_RangeY=m_StartY-point.y;

if (abs(m_RangeX)>abs(m_RangeY))

{

//X大于Y 左右移动

if (m_RangeX>5)

{

//正数 向左

doLeft();

}

else if(m_RangeX<-5)

{

//负数 向右

doReight();

}

}

else

{

//否则 上下移动

if (m_RangeY>5)

{

//正数 向下

doDown();

}

else if(m_RangeY<-5)

{

//负数 向上

doTop();

}

}

}

bool HelloWorld::doTop()

{

CCLOG("doTop Runing");

return true;

}

bool HelloWorld::doDown()

{

CCLOG("doDown Runing");

return true;

}

bool HelloWorld::doReight()

{

CCLOG("doReight Runing");

return true;

}

bool HelloWorld::doLeft()

{

CCLOG("doLeft Runing");

return true;

}

OK,今天先到这来,写的有点多,其实内容不多,说的比较细而已,

最起码,我认为,认真看完就完全能理解变为自己的东西,就算没有此博文,自己也能写出来代码,这才是硬道理

而不像其他的博文,看完还是不理解,云里雾里的,不看着博文写自己完全无从下手

下一篇就开始写游戏的逻辑了,反正偶觉得这个游戏逻辑不是一般的复杂啊,

上次写了两个下午,最后因为JNI问题,移植了2小时,往Android上一安装,测试一下,居然还有BUG

这次写这个系列的博客,也是为了把自己的思路理一理

FROM: http://www.58player.com/blog-2537-90021.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: