Cocos2d-X开发中国象棋《八》走棋,cocos2d-x《八》
在上一节中实现了新局,至此中国象棋的准备工作差不多都完成了,在接下来的博客中将介绍玩家的走棋和一些游戏属性的设置,今天先介绍走棋和走棋规则
老规则,先看走棋的效果图,然后根据效果图一步一步分析游戏逻辑,最后会贴出代码
走棋分为两个步骤:第一步选棋:通过点击棋子实现选棋子,当选中某个棋子的时候,选择框会套在选中的棋子上
第二步走棋:通过点击棋盘上的位置可以实现棋子的移动,当点击的位置是允许棋子移动的位置时,棋子会移动到点击的位置
走棋的实现思路
1、游戏走棋时采用红先黑后原则,红棋和黑棋轮流走
2、通过点击选择需要走的棋子
3、当点击的位置上有棋子的时候,棋子上显示选择框,并且记录点击了一次
4、当点击的位置上没有棋子的时候,判断上次是否点击了棋子,如果上一次点击了棋子,则将棋子移动到第二次点中的位置上
5、游戏走棋时采用红先黑后原则,红棋和黑棋轮流走
实现代码
首先在SceneGame.h中声明一个ccTouchBegan(CCTouch* pTouch, CCEvent* pEvent)函数,然后在SceneGame.cpp中定义ccTouchBegan(CCTouch* pTouch, CCEvent* pEvent)
//通过点击选择棋子,走棋子
bool SceneGame::ccTouchBegan(CCTouch* pTouch, CCEvent* pEvent)
{
CCObject* obj = (CCObject*)pTouch;
//获取触摸点的窗口坐标
CCPoint ptInWin = pTouch->getLocation();
//当触摸到了游戏结果框
if(sprite->boundingBox().containsPoint(ptInWin) && visible == true)
{
//隐藏结果
HideResult(sprite, obj);
}
elseif(sprite1->boundingBox().containsPoint(ptInWin) && visible == true)
{
//隐藏结果
HideResult(sprite1, obj);
}
int x, y;//保存触摸点的棋盘坐标
//通过触摸点的窗口坐标获取棋盘的x坐标和y坐标
if(!getClickPos(ptInWin, x, y))
{
return false;
}
//通过触摸点在棋盘中的坐标获取选中的棋子的id
int clickid = getStone(x, y);
//当触摸点的位置上有棋子的时候,clickid为选中的棋子的id,表示玩家在选棋
//当触摸点的位置上没有棋子的时候,clickid为-1,表示玩家在走棋
//-1 == _selectid表示没有选中棋子
if(-1 == _selectid)
{
setSelectId(clickid);
}
else
{
//移动棋子
//第一个参数:移动的棋子的id
//第二个参数:通过触摸点的位置判断触摸点上是否有棋子
//第三个参数:触摸点的x坐标
//第四个参数:触摸点的y坐标
//moveStone执行了两个步骤选棋和走棋
//选棋子:当_selectid == clickid时,表示选定了id为_selectid的棋子
//走棋子:当selectid != clickid时, 表示将id为_selectid的棋子移动到(x,y)所在的位置上
moveStone(_selectid, clickid, x, y);
}
// CCLog("_selectid=%d, clickid=%d", _selectid, clickid);
//CCLog("x=%d, y=%d", x, y);
return true;
}
在SceneGame.h中声明一个成员函数MoveStone()实现移动棋子
//移动棋子
//第一个参数:移动的棋子的id
//第二个参数:通过触摸点的位置判断触摸点上是否有棋子
//第三个参数:触摸点的x坐标
//第四个参数:触摸点的y坐标
void SceneGame::moveStone(int moveId, int killId, int x, int y)
{
//killId != -1表示触摸点的位置上有一个棋子
//_s[moveId]->getRed() == _s[killId]->getRed()表示触摸点上
//的棋子和走棋的棋子的颜色相同
if(killId != -1 && _s[moveId]->getRed() == _s[killId]->getRed())
{
//更换选择框
setSelectId(killId);
return;
}
//CCLog("killId=%d, moveId=%d", killId, moveId);
//CCLog("_s[moveId]->getRed()=%d", _s[moveId]->getRed());
//走棋规则
bool bCanMove =canMove(moveId, killId, x, y);
//如果bCanMove为false
//不能走棋
if(false == bCanMove)
{
return;
}
//走棋之前记录棋子的信息
//第一个参数:需要移动的棋子的id
//第二个参数:通过触摸点的位置判断触摸点上是否有棋子
//第三个参数:棋子当前的位置的x坐标
//第四个参数:棋子当前的位置的y坐标
//第五个参数:棋子移动后的位置的x坐标
//第六个参数:棋子移动后的位置的y坐标
Step* step = Step::create(moveId, killId, _s[moveId]->getX(), _s[moveId]->getY(), x, y);
//将棋子的信息添加到数组中
_steps->addObject(step);
//设置棋子的坐标(移动棋子)
_s[moveId]->setX(x);
_s[moveId]->setY(y);
//_s[moveId]->setPosition(getStonePos(x,y));
//SetRealPos(_s[moveId]);
//设置移动棋子时的动作
CCMoveTo* move = CCMoveTo::create(.5f, getStonePos(x, y));
//动作回调
CCCallFuncND* call = CCCallFuncND::create(this,
callfuncND_selector(SceneGame::moveComplete),
(void*)(intptr_t)killId);
//设置动作的执行顺序(先移动棋子,后调用回调函数)
CCSequence* seq = CCSequence::create(move, call, NULL);
//设置移动的棋子的优先级
_s[moveId]->setZOrder(_s[moveId]->getZOrder() + 1);
//执行棋子移动的动作
_s[moveId]->runAction(seq);
}