扫雷07 游戏逻辑设计
这才是这里最重要的,整个游戏这里的代码是最关键的。
查看这个游戏的相关函数调用
在GameScene这个类中,相关的调用如下。
NoAroundMine函数
NoAroundMine函数的作用是在点击的区域满足以下三个条件的时候被调用
1、 没有被挖开
2、 不是去标记(插旗)
3、 其代笔的是周围没有雷(属性值为0)
当我们点击到属性值为0的区块的时候,说明这个位置周围没有雷。这个函数的作用就是将这个区块周围没有雷的区块都照出来。这是一个递归调用的函数
1: ///////////////////////////////////////////////////////////////////
2: // 周边无雷块的连带显示
3: void GameScene::NoAroundMine(int row,int col,CCArray * arr)
4: {
5: if (row == 0 || col == 0 || row == _MaxRanks + 1 || col == _MaxRanks + 1) {
6: return; //不需要设置的位置
7: }
8: MineBlock * mb = getRowColAddr(row,col);
9: if (mb->getValue() == -1 || mb->getDig()) {
10: return; //是雷或者被挖开,直接返回退出
11: }
12:
13:
14: //CCLog("row = %d col = %d ",row,col);
15: // 此处有问题,为何不可以获取?
16: //CCTexture2D * texture = CCTextureCache::sharedTextureCache()->textureForKey("0.png");
17:
18: // 设置当前的纹理
19: //getRowColAddr(row,col)->setTexture(CCTextureCache::sharedTextureCache()->textureForKey("0.png"));
20:
21: arr->addObject(mb);
22: mb->setDig(true);
23: if (mb->getValue() != 0) {
24: return; //不是0,不再继续
25: }
26: //getRowColAddr(row,col)->setValue(-2); //方便终止递归
27: //设置四周纹理
28: NoAroundMine(row + 1,col + 1,arr);
29: NoAroundMine(row + 1,col,monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 16pt; padding-right: 0px; background-color: #f4f4f4"> 30: NoAroundMine(row + 1,col - 1,monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 16pt; padding-right: 0px; background-color: white"> 31: NoAroundMine(row,monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 16pt; padding-right: 0px; background-color: #f4f4f4"> 32: NoAroundMine(row,monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 16pt; padding-right: 0px; background-color: white"> 33: NoAroundMine(row - 1,monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 16pt; padding-right: 0px; background-color: #f4f4f4"> 34: NoAroundMine(row - 1,monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 16pt; padding-right: 0px; background-color: white"> 35: NoAroundMine(row - 1,monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 16pt; padding-right: 0px; background-color: #f4f4f4"> 36: }
ContinueGame函数
ContinueGame函数是判断是否继续游戏的函数,其作用是在游戏的过程中判断输赢。
如果踩到雷或者全部非雷区都找到的话就返回false,告诉callTouchEnded游戏不再继续。否则返回true,游戏继续。
当游戏不再继续的时候,这个函数负责根据输赢显示背景或者动画。
1: ///////////////////////////////////////////////////////////////
2: // 游戏输赢判断,是否继续游戏
3: bool GameScene::ContinueGame()
5: if (_count == -1) {
6: LabelTTF* ttf = LabelTTF::create("Your fail!","Felt",WinWidth / 10);
7: _bgland->setZOrder(100);
8: _bgland->addChild(ttf);
9: ttf->setPosition(Vec2(WinWidth / 3,50));
10: ttf->setColor(ccc3(255,0));
11:
12: return false;
13: }
14: if (_count == _MaxRanks*_MaxRanks - _mine) {
15: Texture2D * texture1 = TextureCache::getInstance()->addImage("blink_1.png");
16: Texture2D * texture2 = TextureCache::getInstance()->addImage("blink_2.png");
17: Animation * animation = Animation::create();
18:
19: animation->addSpriteFrameWithTexture(texture1,//设置动画的矩形的定位点
20: CCRectMake(.0f,.0f
21:,texture1->getContentSize().width,texture1->getContentSize().height));
22: animation->addSpriteFrameWithTexture(texture2,
23: CCRectMake(.0f,.0f,monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 16pt; padding-right: 0px; background-color: #f4f4f4"> 24: texture2->getContentSize().width,monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 16pt; padding-right: 0px; background-color: white"> 25: animation->setDelayPerUnit(0.1f);
26:
27: Animate *animate = Animate::create(animation);
28:
29: _bgland->setZOrder(100);
30: _bgland->runAction(CCRepeatForever::create(animate));
31: //适应_bglang的显示高度来缩放
32: _bgland->setScale(_bgland->getBoundingBox().size.height / texture1->getContentSize().height);
33: return false; //胜利了
34: }
35: return true;
36: }
callTouchEnden函数
这个函数负责判断点击到了什么样的雷块
1: // Touch 判断点击的位置以及更新图片
2: void GameScene::callTouchEnded(Touch * pTouch,Event * pEvent)
3: {
4: Point pt = pTouch->getLocation();
5: // CCLog("pt.x = %f\t pt.y = %f",pt.x,pt.y);
6: CCObject * obj;
7:
8: CCARRAYDATA_FOREACH(_ArraySprite->data,obj)
9: {
10: MineBlock * mb = (MineBlock*)obj;
11: //如果点击的这个像素不在这个精灵所在的矩形范围内
12: if (!mb->boundingBox().intersectsRect(CCRectMake(pt.x,pt.y,1,1))) {
13: continue; // 下一个
14: }
15: // 点击的位置在这个精灵的范围之内
16: if (mb->getDig()) {
17: return; //已经被挖开
18: }
19: char filename[16] = { 0 };
20: int t = mb->getValue();
21: // 如果是去标记
22: if (_toFlag) {
23: const char *ptx = mb->getFlag() ? "no.png" : "flag.png";
24: mb->setTexture(CCTextureCache::getInstance()->getTextureForKey(ptx));
25: mb->setFlag(!mb->getFlag());
26: return;
27: }
28: //踩到雷------------------------------------------------------------------------
29: if (t == -1) {
30: _count = -1; //设置计数为-1,代表输了
31: //显示所有雷
32: CCARRAYDATA_FOREACH(_ArraySprite->data,monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 16pt; padding-right: 0px; background-color: white"> 33: {
34: MineBlock * mine = (MineBlock*)obj;
35: if (mine->getValue() == -1) {
36: mine->setTexture(CCTextureCache::sharedTextureCache()->textureForKey("-1.png"));
37: }
38: }
39: //显示爆炸
40: mb->setTexture(CCTextureCache::sharedTextureCache()->textureForKey("boom.png"));
41: goto CONTINUEGAME; //到此结束
42: } // end if t == -1
43:
44: //没有踩到雷,但是周围有雷
45: if (t>0) {
46: //在移植到安卓的时候,全部精灵的_value都为0,出现错误,sprintf函数没有问题
47: sprintf(filename,"%d.png",t);
48: mb->setTexture(CCTextureCache::sharedTextureCache()->textureForKey(filename));
49: mb->setDig(true);
50: ++_count; //扫区计数加一
51: goto CONTINUEGAME; //到此结束
52: }
53:
54: //只剩下t==0的情况了,就是周围没有雷的位置
55: for (int r = 1; r <= _MaxRanks; ++r) {
56: for (int c = 1; c <= _MaxRanks; ++c) {
57:
58: if (getRowColAddr(r,c) == mb) {
59: CCArray * arr = CCArray::create();
60: arr->retain();
61: NoAroundMine(r,c,monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 16pt; padding-right: 0px; background-color: #f4f4f4"> 62: CCObject *obj = NULL;
63: CCARRAYDATA_FOREACH(arr->data,monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 16pt; padding-right: 0px; background-color: #f4f4f4"> 64: {
65: MineBlock * noMine = (MineBlock*)obj;
66: // if (noMine->getValue() == -2) {
67: // noMine->setTexture(CCTextureCache::getInstance()->getTextureForKey("0.png"));
68: // }
69: // else {
70: sprintf(filename,noMine->getValue());
71: noMine->setTexture(CCTextureCache::getInstance()->getTextureForKey(filename));
72: // }
73:
74: }
75: _count += arr->count(); //扫区计数加一
76: arr->release();
77: goto CONTINUEGAME; //到此结束
78: }// end if...
79:
80: }
81: }
82:
83: } //end CCARRAYDATA_FOREACH...
84: CONTINUEGAME: //goto到此区判断游戏是否继续
85: _isContinue=ContinueGame();
86: }