• 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);
        }
        else  if(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);
    }
    


    
  • 相关阅读:
    Vue.js-项目目录结构解析
    Vue.js-创建Vue项目(Vue项目初始化)并不是用Webstrom创建,只是用Webstrom打开
    Node.js-npm安装包目录修改
    Node.js-Webstorm2018配置nodejs
    Node.js-ReferenceError: _filename is not defined
    cas系列-自定义异常提示(五)
    cas系列-cas登出(四)
    cas系列-cas REST协议(三)
    maven引入第三方jar包
    持续api管理翻译
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4216150.html
Copyright © 2020-2023  润新知