扫雷03 游戏主场景布局设计
游戏主场景的布局如图
游戏场景类的设计
游戏主场景类GameScene继承自Layer类,这是cocos2.2.3时代的习惯,现在其实不需要这样做了。继承自Layer是为了添加触摸事件的方便,现在3.x版本没有必要这样了。
1: class GameScene : public cocos2d::Layer
2: {
3: public:
4:
5: virtual bool init();
6:
7: //创建scene的时候选关,1==》9*9,2==》16*16,3==》24*24
8: static cocos2d::CCScene* scene(int customs = 1);
9: //创建的时候就要确定
10: static GameScene* create(int customs = 1);
11:
12: protected:
13: bool LoadResource(); //加载资源
14: bool addBackGround(); //设置背景
15: private:
16: int _mine; //地雷数
17: int _customs; //关数
18: int _MaxRanks; //最大可用土地行列
19: Sprite * _bgland; //雷区背景精灵
20: Sprite * _bgmenu; //菜单项背景精灵
21: };
create函数与scene函数的实现
create函数创建了一个类实例,并对其的一些自有的成员(非继承Layer的)进行了赋值。
1: GameScene* GameScene::create(int customs)
3: GameScene *s = new GameScene();
4: if (s != NULL) {
5: if (customs<0 || customs >3) {
6: CCLog("customs value error");
7: return NULL;
8: }
9: s->_customs = customs;
10: s->_count = 0; //记录当前扫了多少块区域
11: s->_toFlag = false; //是不是去标记雷块
12: s->init();
13: s->autorelease(); //此处需要,在addChile的时候自然会被retain
14: }
15: else {
16: CC_SAFE_DELETE(s); //安全删除
17: //#define CC_SAFE_DELETE(p) do { if(p) { delete (p); (p) = 0; } } while(0)
18: //等价于===> do{ //使用do while是为了适应我们习惯性了加上分号,没有分号会提示错误
19: // if(s!=NULL) {
20: // delete s;
21: // s=NULL;
22: // }
23: // }while(0)
24: }
25: return s;
26: }
27:
28:
29: CCScene* GameScene::scene(int customs)
30: {
31: CCScene *scene = CCScene::create();
32:
33: GameScene *layer = GameScene::create(customs);
34:
35: scene->addChild(layer);
36:
37: return scene;
38: }
加载资源本来不应该在此处,因为还没有设计游戏起始选关界面,所以在此处做了。游戏需要加载的资源也不多,就几张小图片。音效素材没有,什么时候找到了随时可以添加。
1: /////////////////////////////////////////////////////////////////////////
2: // 初始化加载资源
3: bool GameScene::LoadResource()
4: {
5: const char* ImgFile[] = {
6: "0.png",
7: "1.png",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"> 8: "2.png",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"> 9: "3.png",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"> 10: "4.png",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"> 11: "5.png",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"> 12: "6.png",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"> 13: "7.png",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"> 14: "8.png",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"> 15: "no.png",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"> 16: "-1.png",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"> 17: "bg_land.png",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"> 18: "bg_menu.png",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"> 19: "boom.png",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"> 20: "flag.png",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"> 21: "blink_1.png",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"> 22: "blink_2.png",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"> 23: "exit.png",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: "exits.png",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: "restart.png",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"> 26: "restarts.png"
27: };
28: for (int i = 0; i < sizeof(ImgFile) / sizeof(char*); ++i) {
29: if (NULL == TextureCache::getInstance()->addImage(ImgFile[i])) {
30: return false;
31: }
32: }
33: return true;
34: }
init函数的实现
init函数要做的事情如下面代码的注释,因为这是之前写的,所以本次不一定如此。
大致流程是这样的,被注释掉的说明本次还没有完全做好。现在只要加载背景来显示即可。
1: bool GameScene::init()
2: {
3: //////////////////////////////
4: // 1. super init first
5: if (!CCLayer::init()) {
6: return false;
7: }
8: //加载资源
9: LoadResource();
10: //设置背景
11: addBackGround();
12: //设置菜单项
13: //addMenu();
14: //初始化土地,埋雷
15: //BuryMine();
16:
17: //初始化雷区精灵
18: //InitMine();
19:
20: //设置触摸事件
21: //setTouchEnabled(true);
22: //setTouchMode(kCCTouchesOneByOne);
23: //setTouchPriority(2);
24:
25: CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
26: CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
27:
28: return true;
29: }
addBackGround()加载背景函数的实现
1: //////////////////////////////////////////////////////////////////////
2: // 设置背景
3: bool GameScene::addBackGround()
5: //创建一个土地放置层,其是一个CCSprite,因为要显示背景
6: Texture2D * texture = TextureCache::getInstance()->textureForKey("bg_land.png");
7: if (!texture) {
8: return false;
9: }
10: //设置雷区背景
11: Sprite * bgland = Sprite::createWithTexture(texture);
12: //设置背景为宽度适应
13: bgland->setScale(WinWidth / bgland->getContentSize().width);
14: //中央点为锚点
15: bgland->setAnchorPoint(ccp(.0f,.0f));
16: addChild(bgland);
17: bgland->setPosition(ccp(0,WinHeigth - bgland->getBoundingBox().size.height)); //放置在中央
18: _bgland = bgland;
19:
20: //设置菜单背景
21: texture = TextureCache::getInstance()->textureForKey("bg_menu.png");
22: Sprite * bgmenu = Sprite::createWithTexture(texture);
23: bgmenu->setScale(WinWidth / bgmenu->getContentSize().width);
24: bgmenu->setAnchorPoint(CCPointZero);
25: bgmenu->setPosition(CCPointZero);
26: addChild(bgmenu);
28: //添加了一个半透明的Layer,到时候用来防止雷区的格子块
29: //本来是想放置在Sprite上的,算了,还是这个比较实在
30: //加载一个半透明的CCLayerColor,来遮住背景
31: _layerColor = LayerColor::create(ccc4(128,128,128),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: WinWidth,//设置其大小和雷区背景一致
33: bgland->getBoundingBox().size.height);
34: _layerColor->setPosition(bgland->getPosition());
35: addChild(_layerColor);
36: //设置触摸优先级 这个没有用,就没有在这里设置触摸事件
37: //_layerColor->setTouchPriority(10);
38: return true;
39: }
测试一下加载背景效果
本来应该把菜单项也加进去的,不急这一点。先看看效果,待会再加。
运行前应该把相关的资源拷贝到项目目录下的res文件夹
测试前要先修改下窗口的尺寸和设计尺寸
修改后的效果
6: Texture2D * texture = TextureCache::getInstance()->getTextureForKey("bg_land.png");
14: //零点为锚点
15: bgland->setAnchorPoint(Vec2::ZERO);
17: bgland->setPosition(Vec2(0,WinHeigth - bgland->getBoundingBox().size.height)); //放置在上半屏幕
19: bgland = nullptr;
21: texture = TextureCache::getInstance()->getTextureForKey("bg_menu.png");
23: //设置缩放宽度为适应屏幕宽度
24: bgmenu->setScaleX(WinWidth / bgmenu->getContentSize().width);
25: //设置高度为适应除去_bgland后剩下的部分
26: bgmenu->setScaleY(_bgland->getBoundingBox().getMinY() / bgmenu->getContentSize().height);
28: bgmenu->setAnchorPoint(Vec2::ZERO);
29: bgmenu->setPosition(Vec2::ZERO);
30: addChild(bgmenu);
31: _bgmenu = bgmenu;
32: bgmenu = nullptr;
33: //添加了一个半透明的Layer,到时候用来防止雷区的格子块
34: //本来是想放置在Sprite上的,算了,还是这个比较实在
35: //加载一个半透明的CCLayerColor,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: _layerColor = LayerColor::create(Color4B(128,64),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"> 37: WinWidth,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"> 38: _bgland->getBoundingBox().size.height);
39: _layerColor->setPosition(_bgland->getPosition());
40: addChild(_layerColor);
41: //设置触摸优先级 这个没有用,就没有在这里设置触摸事件
42: //_layerColor->setTouchPriority(10);
43: return true;
44: }