Cocos2d-x制作《单机斗地主》源码解剖1:创建一副扑克牌

2015年03月24日 08:26 1 点赞 0 评论 更新于 2025-11-21 18:21

本系列文章将详细讲解如何基于Cocos2d-x引擎制作《单机斗地主》游戏,并对游戏源码进行深入剖析,旨在帮助读者理解游戏逻辑以及掌握开发关键技术。

本项目基于Cocos2d-x引擎开发,参考了网上搜索的斗地主相关资料,由本人独立完成。下面将对项目中创建一副扑克牌的部分进行详细总结。

1. 创建一张扑克牌类

在编写代码时,首先需要创建一个表示一张牌的类。以下是 Poker 类的定义:

class Poker : public Sprite {
public:
Poker();
~Poker();
static Poker* create(const char *pszFileName, const CCRect& rect);
virtual void onEnter();
virtual void onExit();
virtual bool onTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void onTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void onTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void onTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
void showFront(); // 显示正面
void showLast();  // 显示背面
Poker* copy();    // 拷贝
void setTouchPriority(int num);
void SelectPkLuTou(); // 如果选择了牌就露出头
void SelectPkSuoTou(); // 如果选择了牌就缩头

private:
CC_SYNTHESIZE(bool, m_isSelect, Select); // 是否已选
CC_SYNTHESIZE(GameScene*, m_gameMain, GameMain);
CC_SYNTHESIZE(bool, m_isDianJi, DianJi); // 是否能被点击
CC_SYNTHESIZE(int, m_huaSe, HuaSe);      // 花色
CC_SYNTHESIZE(int, m_num, Num);          // 牌值
EventListenerTouchOneByOne* touchListener;
};

这个类继承自 Sprite,包含了扑克牌的基本属性和操作方法,如显示正反、拷贝、处理触摸事件等。同时,使用 CC_SYNTHESIZE 宏来自动生成属性的 getter 和 setter 方法。

2. 生成一张扑克牌的函数

基于上述 Poker 类,我们编写了一个函数来生成一张牌,该函数位于源码的 GameScene 类中:

Poker* GameScene::selectPoker(int huaSe, int num) {
Poker* pk;
if (huaSe != Gui)
pk = Poker::create("poker.png", CCRect(num * pkWidth, huaSe * pkHeight, pkWidth, pkHeight));
else
pk = Poker::create("poker.png", CCRect((num - XiaoGui) * pkWidth, huaSe * pkHeight, pkWidth, pkHeight));
pk->setHuaSe(huaSe);
pk->setNum(num);
pk->setGameMain(this);
return pk;
}

此函数根据传入的花色和牌值,从 poker.png 图片中截取相应的部分来创建一张扑克牌,并设置其花色、牌值和所属的游戏场景。

poker.png 图片说明

poker.png 图片是包含所有扑克牌图案的图片,通过 CCRect 来指定截取的区域,从而获取不同的扑克牌。

3. 创建一副扑克牌

接下来,我们使用上述函数来创建一副完整的扑克牌,代码位于 GameScene 文件中:

bool GameScene::createPokers() {
bool isRet = false;
do {
Size size = Director::sharedDirector()->getVisibleSize();
Poker* pk;

// 创建52个除大鬼小鬼外的牌
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 13; ++j) {
pk = selectPoker(i, j);
pk->setPosition(ccp(size.width / 2 /*+j*20*/, size.height / 2 /*-i*20*/));
pk->showLast();
this->addChild(pk);
this->m_arrPokers->addObject(pk);
}
}

// 创建小鬼
pk = selectPoker(Gui, XiaoGui);
pk->setPosition(ccp(size.width / 2, size.height / 2 /*-4*20*/));
pk->showLast();
this->addChild(pk);
this->m_arrPokers->addObject(pk);

// 创建大鬼
pk = selectPoker(Gui, DaGui);
pk->setPosition(ccp(size.width / 2 /*+20*/, size.height / 2 /*-4*20*/));
pk->showLast();
this->addChild(pk);
this->m_arrPokers->addObject(pk);

isRet = true;
} while (0);
return isRet;
}

该函数首先创建 52 张除大小鬼外的扑克牌,然后分别创建小鬼和大鬼,将它们添加到游戏场景中,并设置初始位置和显示背面。最后将所有扑克牌添加到 m_arrPokers 数组中。

通过以上步骤,我们完成了一副扑克牌的创建。后续文章将继续剖析《单机斗地主》游戏的其他部分。

作者信息

boke

boke

共发布了 3994 篇文章