废话不多说,直接上代码:
SceneGame:“主要战场”
#ifndef SCENEGAME_H
#define SCENEGAME_H
#include "cocos2d.h"
USING_NS_CC;
#include "Stone.h"
class SceneGame : public CCLayer
{
public:
CCSize winSize =CCDirector::sharedDirector()->getWinSize();
SceneGame();
static CCScene*scene(bool isRed);
static SceneGame*create(bool isRed);
bool init(bool isRed);
void adddesk();
void addchessboard();
void addstone(bool);
private:
Stone *_s[32];
CCPoint getBoardpos(float x,float y);
float _d;
CCPoint backgroundOff;//set the background
CCPoint stoneOff;
};
#endif // SCENEGAME_H
#include "SceneGame.h"
SceneGame::SceneGame()
{
}
CCScene * SceneGame::scene(bool red)
{
CCScene *s = CCScene::create();
SceneGame*layer = SceneGame::create(red);
s->addChild(layer);
return s;
}
SceneGame *SceneGame::create(bool red)
{
SceneGame* pRet = new SceneGame();
if(pRet)
{
if(pRet->init(red))
pRet->autorelease();
else
{
pRet->release();
return NULL;
}
}
else
{
return NULL;
}
return pRet;
}
bool SceneGame::init(bool red)
{
if(!CCLayer::init())
return false;
this->backgroundOff = ccp(15,10);
this->_d = 46;
this->stoneOff = ccp(60,33);
adddesk();
addchessboard();
addstone(red);
//move the stone
return true;
}
void SceneGame::adddesk()
{
CCSprite *back = CCSprite::create("floor.jpg");
addChild(back);
back->setPosition(ccp(winSize.width/2,winSize.height/2));
back->setScaleX(winSize.width/back->getContentSize().width);
back->setScaleY(winSize.height/back->getContentSize().height);
}
void SceneGame::addchessboard()
{
CCSprite *chessboard = CCSprite::create("background.png");
addChild(chessboard);
chessboard->setAnchorPoint(CCPointZero);//set Anchor to the left-down
chessboard->setScale((winSize.height-backgroundOff.y*2)/chessboard->getContentSize().height);
chessboard->setPosition(backgroundOff);
}
void SceneGame::addstone(bool red)
{
for(int i = 0; i<32; i++)
{
_s[i] = Stone::create(i,red);
addChild(_s[i]);
_s[i]->setPosition(ccp(600+CCRANDOM_0_1()*200,CCRANDOM_0_1()*winSize.height)); //
CCMoveTo *moveto = CCMoveTo::create(1,this->getBoardpos(_s[i]->getX(),_s[i]->getY()));
_s[i]->runAction(moveto);
}
}
CCPoint SceneGame::getBoardpos(float x, float y)
{
float xx = x*_d;
float yy = y*_d;
return ccp(xx,yy)+this->stoneOff;
}
好了,料已加号。开始叨唠叨唠。
在SceneGame.c文件中,我们看到有这样一个函数的定义:bool SceneGame::init(bool red);其实init是每个类似于SceneGame的类都会有的。在头文件中我们看到SceneGame是继承于CCLayer的。CCLayer是场景类,而且场景的创建的时候我们需要去初始化我们的场景,所以在create函数中我们就可以看到有init函数的存在。因为这里的创建和初始化都有着特殊的需要,所以我们重写了虚函数create和init。
这里面我们对单例模式设计的对象SceneGame进行了new操作。一般是不允许的,但是在这边我们可以很方便的找到开源库中的类定义。所以我们可以重写,而且重写函数中我们也将new出来的对象通过autorelease()函数加入了Cocos2dX的内存管理器中,方便管理。
场景的叠加
addfloor:添加桌子
只有添加了桌子才能放我们的棋盘。那么怎么去布局桌子的?其实也就是一个图片精灵啦~然后调用其设置位置等函数即可咯~
void SceneGame::adddesk()
{
CCSprite *back = CCSprite::create("floor.jpg");
addChild(back);//将精灵添加到渲染树里面去,方便渲染
back->setPosition(ccp(winSize.width/2,winSize.height/2));
back->setScaleX(winSize.width/back->getContentSize().width);
back->setScaleY(winSize.height/back->getContentSize().height);
}
addchessboard:添加棋盘
void SceneGame::addchessboard()
{
CCSprite *chessboard = CCSprite::create("background.png");
addChild(chessboard);
chessboard->setAnchorPoint(CCPointZero);//set Anchor to the left-down
chessboard->setScale((winSize.height-backgroundOff.y*2)/chessboard->getContentSize().height);
chessboard->setPosition(backgroundOff);
}
addstone:添加棋子
void SceneGame::addstone(bool red)
{
for(int i = 0; i<32; i++)
{
_s[i] = Stone::create(i,red);
addChild(_s[i]);
_s[i]->setPosition(ccp(600+CCRANDOM_0_1()*200,CCRANDOM_0_1()*winSize.height)); //
CCMoveTo *moveto = CCMoveTo::create(1,this->getBoardpos(_s[i]->getX(),_s[i]->getY()));
_s[i]->runAction(moveto);
}
}
其实在添加棋子这边还是有很多值得说道的地方的。首先就是我们怎么将那么多棋子精灵给创建出来,创建出来之后我们该怎么做才能很方便的去对应到棋盘上,是不是有什么我们所不知道的方法可以很方便的去做到;
写到这里的时候,总是有种特别的感觉,因为每当我去面对这样的事情的时候总是想着怎么去找最优解,或者说是正确解而不是我所能想到的最优解。其实,就我目前所认识到的事情而言,所有的事情只有更优秀而没有所谓的正确。这应该是自我以前学习和自我管理的时候不当所引起的。这里给自己也给有同样缺点的同学打个桩,希望能改之。万事万物都是在挫折学习中的,不能一步到位,所以要踏实,也不能妄自菲薄,要做事,踏实做事。
好了,闲扯了。回来过我们再想棋子的事情,由于棋子的特殊性,所以我们有必要去新建一个Stone类来表示和解释棋子的位置,对应属性,是否被吃掉的情况。
#include "Stone.h"
Stone::Stone()
{
}
Stone::InitPos Stone::_initPos[16]=
{
{0,0,Stone::CHE},
{1,0,Stone::MA},
{2,0,Stone::XIANG},
{3,0,Stone::SHI},
{4,0,Stone::JIANG},
{5,0,Stone::SHI},
{6,0,Stone::XIANG},
{7,0,Stone::MA},
{8,0,Stone::CHE},
{1,2,Stone::PAO},
{7,2,Stone::PAO},
{0,3,Stone::BING},
{2,3,Stone::BING},
{4,3,Stone::BING},
{6,3,Stone::BING},
{8,3,Stone::BING},
};
Stone * Stone::create(int id, bool red)
{
Stone *s = new Stone();
s->init(id,red);
s->autorelease();
return s;
}
bool Stone::init(int id, bool red)
{
this->setID(id);//_id = id
this->setisRed(getID()<16);//_red = red
if(getID()<16)
setType(_initPos[getID()]._type);//
else
setType(_initPos[getID()-16]._type);
const char *stonePic[14] = {
"rshuai.png",
"rshi.png",
"rxiang.png",
"rche.png",
"rma.png",
"rpao.png",
"rbing.png",
"bjiang.png",
"bshi.png",
"bxiang.png",
"bche.png",
"bma.png",
"bpao.png",
"bzu.png",
};
int idx = (getisRed()?0:1)*7 + getType();//nice place!!!
CCSprite::initWithFile(stonePic[idx]);
setScale(0.8f);
reset(red);
return true;
}
void Stone::reset(bool red)
{
setisDead(false);
if(red)
{
if(getID()<16)
{
this->setX(_initPos[getID()]._x);
this->setY(_initPos[getID()]._y);
}
else
{
this->setX(8 - _initPos[getID()-16]._x);
this->setY(9 - _initPos[getID()-16]._y);
}
}
else
{
if(getID()<16)
{
this->setX(8 - _initPos[getID()]._x);
this->setY(9 - _initPos[getID()]._y);
}
else
{
this->setX(_initPos[getID()-16]._x);
this->setY(_initPos[getID()-16]._y);
}//sequence is import,but it should not appear here.
}
}
希望有兴趣的同学可以对照着,查看下。
#ifndef STONE_H
#define STONE_H
#include "cocos2d.h"
USING_NS_CC;
class Stone:public CCSprite
{
public:
Stone();
enum TYPE{
JIANG,SHI,XIANG,CHE,MA,PAO,BING
};
CC_SYNTHESIZE(TYPE,_type,Type)//TYPE getType() void setType(TYPE _type)
CC_SYNTHESIZE(int,_x,X)
CC_SYNTHESIZE(int,_y,Y)
CC_SYNTHESIZE(int,_id,ID)
CC_SYNTHESIZE(bool,_red,isRed)
CC_SYNTHESIZE(bool,_dead,isDead)
static struct InitPos
{
int _x;
int _y;
Stone::TYPE _type;
}_initPos[16];
static Stone *create(int id,bool red);
bool init(int id,bool red);
void reset(bool red);
};
#endif // STONE_H
不过这里面我觉得很优秀的地方是Stone的头文件里对于enum枚举的使用:枚举的每个元素对应着数字0123等,所以我们在.c文件中发现了这样的代码:
int idx = (getisRed()?0:1)*7 + getType();//nice place!!!
getType()实际上就是数字0123的对应值。当时看到这里真是大开眼界。看来我还需要多多练习啊~
好啦~总体基本附上,自己觉得不错的地方也已经点出。代码都是自己考量过的。有什么问题还希望能进一步交流~O啦~
附上成功的图片:
具体规则呢~等我参透了,这和大家细谈哈。这个项目主要有人机对战和即时对战。分别对应着人工智能的相关算法,和socket通信。主要是学习啦,但是贴出来的代码都能解释的。如有疑惑,欢迎交流~~^_^