cocos2dx象棋二

废话不多说,直接上代码:

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啦~

附上成功的图片:

211744_6Zqi_1866291.jpg

211745_fRhT_1866291.jpg

具体规则呢~等我参透了,这和大家细谈哈。这个项目主要有人机对战和即时对战。分别对应着人工智能的相关算法,和socket通信。主要是学习啦,但是贴出来的代码都能解释的。如有疑惑,欢迎交流~~^_^

转载于:https://my.oschina.net/sunnyandjj/blog/288089

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值