在这里我们需要给Stone类添加多几个成员变量以方便后面解决棋子摆放问题。
- bool _red 颜色标记,判断当前棋子是否为红棋
- int _row 记录棋子行号,行号不大于9
- int _col 记录棋子列号,列号不大于8
- int _id 记录棋子的id,id号不大于32
因为创建棋子时需要传入棋子的id,所以我们对Stone类的create函数及init函数稍做修改。(create函数原来由cocos的工厂方法CREATE_FUNC帮我们创建,我们重写时可以参考一下CREATE_FUNC的写法)
bool Stone::init(int id)
{
if (!Sprite::init())
{
return false;
}
Sprite *stone = Sprite::create("Stone/rche.png");
stone->setPosition(getPositionFromPlate());
this->addChild(stone);
return true;
}
Stone* Stone::create(int id)
{
Stone *ret = new Stone();
if (!ret && ret->init(id))
{
ret->autorelease();
}
else
{
delete ret;
ret = nullptr;
}
return ret;
}
摆棋分析:
摆棋前我们要引入一个对称的概念,我们可以把棋盘平分为四块矩形,而这四块矩形上只要摆好第一块矩形上的棋子,那么另外三块即可通过对称或旋转和控制棋子颜色获得,在这里我们需要用枚举的方法列出棋子的类型,然后通过棋子的类型记录棋子在第一块矩形相应的行号及列号,接着我们就可以通过旋转和棋子的颜色标记来设置剩下的棋子的位置及纹理。
我们先确定第一块矩形的棋子的行列,以方便我们后面的对称和旋转摆棋。如图。
然后在Stone.h中枚举出各类棋子
enum TYPE{
CHE,MA,XIANG,SHI,JIANG,PAO,BING
};
接着通过一个结构体记录第一块矩形的行号和列号(该结构体放在了初始化棋子信息的函数里,后面会提到)
struct
{
TYPE type;
int row;
int col;
} proper[9] = {
{CHE, 0, 0},
{MA, 0, 1},
{XIANG, 0, 2},
{SHI, 0, 3},
{BING, 3, 2},
{BING, 3, 0},
{PAO, 2, 1},
{JIANG, 0, 4},
{BING, 3, 4}
};
有了前面的逻辑后,我们可以开始写一个initStone来初始化棋子信息
void Stone::initStone(int id)
{
struct
{
TYPE type;
int col;
int row;
}proper[9] = {
{CHE,0,0},
{MA,0,1},
{XIANG,0,2},
{SHI,0,3},
{BING,3,2},
{BING,3,0},
{PAO,2,1},
{JIANG,0,4},
{BING,3,4}
};
_red = id < 16;
if (id < 8)
{
this->_id = id;
this->_col = proper[id].col;
this->_row = proper[id].row;
}
}
因为添加了行列成员变量,相应地改一下原来的getPositionFromPlate函数
Point Stone::getPositionFromPlate()
{
Point ret = Point(Stone::_offx + this->_row*_d, Stone::_offy + this->_col*_d);
return ret;
}
因为本人表达能力有限,为了避免混乱或有人看不懂,在最后就把Stone类修改后的代码贴出来。
Stone.h
#ifndef __STONE_H__
#define __STONE_H__
#include "cocos2d.h"
USING_NS_CC;
/*
布局棋子时因为棋盘左侧及下侧都空出一段,
所以在布局时,每个棋子都需要加上左侧空白段_offx及下侧空白段_offy。
*/
class Stone : public Sprite
{
public:
static int _d;//棋子直径
static int _offx;//棋子左侧空白段
static int _offy;//棋子下侧空白段
int _id;//棋子id
int _col;//棋子的列号
int _row;//棋子的行号
bool _red;//标记当前棋子颜色
//枚举出所有棋子类型
enum TYPE{
CHE,MA,XIANG,SHI,JIANG,PAO,BING
};
static Stone* create(int id);
virtual bool init(int id);
void initStone(int id);//该函数用于初始化棋子成员变量
Point getPositionFromPlate();//该函数用于获取棋子相对于棋盘的位置
};
#endif
Stone.cpp
#include "Stone.h"
int Stone::_d = 32;
int Stone::_offx = 32;
int Stone::_offy = 16;
bool Stone::init(int id)
{
if (!Sprite::init())
{
return false;
}
//设置纹理图片,此处与2.x版本有点区别,但是区别不大
Texture2D *texture = Director::getInstance()->getTextureCache()->addImage("Stone/rche.png");
this->setTexture(texture);
this->setTextureRect(Rect(0, 0, texture->getContentSize().width, texture->getContentSize().height));
initStone(id);
setPosition(getPositionFromPlate());
return true;
}
Stone* Stone::create(int id)
{
Stone *ret = new Stone();
if (ret && ret->init(id))
{
ret->autorelease();
}
else
{
delete ret;
ret = nullptr;
}
return ret;
}
void Stone::initStone(int id)
{
struct
{
TYPE type;
int row;
int col;
}proper[9] = {
{CHE,0,0},
{MA,0,1},
{XIANG,0,2},
{SHI,0,3},
{BING,3,2},
{BING,3,0},
{PAO,2,1},
{JIANG,0,4},
{BING,3,4}
};
_red = id < 16;
if (id < 8)
{
this->_id = id;
this->_col = proper[_id].col;
this->_row = proper[_id].row;
}
/*此处添加后续摆棋代码*/
}
Point Stone::getPositionFromPlate()
{
Point ret = Point(Stone::_offx + this->_col*_d, Stone::_offy + this->_row*_d);
return ret;
}
此时可以通过修改id号(不大于8)摆放车的位置
运行图: