Cocos2d-x 3.4 之 消灭星星 >前言+第一篇<
***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************
前言: 五一假期完毕,学校放运动会四天小长假, 去泰山耍了耍,从红门爬到顶,累惨了。。。 但在 玉皇顶 俯瞰山河的感觉真是不错的呀, 在山上无人的地方,静静的坐了一段时间,瞎想了很多, 回来,还是要接着奋斗下去呀....
这次是用 cocos2d-x 3.4 开发 消灭星星 很早之前就有这想法,一直没实施,做一做也挺好的,顺便熟悉下 粒子引擎的玩法。 消灭星星 这款老牌游戏,在今年4月份很是抢眼啊, 在360手游 单机游戏榜单中, 下载榜 位居第六! 畅销榜 位居第三! 老牌游戏的强势崛起么~ PS: 360手游4月指数报告:http://www.gameres.com/338687.html
我特地下载了 消灭星星(第一版) 和 消灭星星3 都玩了几天 消灭星星3 比 第一版 好在: 背景音乐很激情啊,节奏快了很多,第一版还有 两下消除 和 一下消除的切换,但是消灭星星3 好像没有(反正我是没找到),而且3的 过关分数成长系统做的不错,比第一版强。
Ok,废话不多说,来开搞吧
第一篇: 这一篇,我主要想实现: > 游戏场景:星星地图 > 点击星星,处于选中状态
1. 星星 类的创建 做这个和之前三消感觉有点类似, 所以,这个星星类就和之前 精灵类差不多: /* 初始化 */ Star(); static Star* create( int row,int col ); // 设定星星显示状态 void setDisplayMode(DisplayMode mode); /* 设定函数 */ CC_SYNTHESIZE(int,m_row,Row); CC_SYNTHESIZE(int,m_col,Col); CC_SYNTHESIZE(int,m_imgIndex,ImgIndex); CC_SYNTHESIZE_READONLY(DisplayMode,m_displayMode,DisplayMode); 具体的实现,就不列出了,后面会有源码
2. GameDefine 游戏相关设定头文件 看过之前的 三消游戏 ,对于这个头文件不陌生吧? 这个头文件 放一些 游戏相关设定的东东, 比如 游戏界面大小、每个星星大小等等, 这样做的好处,就是后期修改起来很方便,不需要再一堆CPP的源码中翻找 // 定义屏幕宽高,这与所做的图片有关 #define GAME_SCREEN_WIDTH 480 #define GAME_SCREEN_HEIGHT 800 // 定义每个精灵大小与边框大小 #define STAR_WIDTH 48 #define BOADER_WIDTH 0.5 // 行列值 #define ROWS 10 #define COLS 10 // 关于这些星星 // 星星的模式,NORMAL 普通状态,HEART 高亮状态 enum DisplayMode{ DISPLAY_MODE_NORMAL = 0,DISPLAY_MODE_HEART }; // 星星总数 #define TOTAL_STAR 5 // 普通状态 static const char *starNormal[TOTAL_STAR] = { "red.png","blue.png","green.png","purple.png","yellow.png" }; // 高亮状态 static const char *starHeart[TOTAL_STAR] = { "red_heart.png","blue_heart.png","green_heart.png","purple_heart.png","yellow_heart.png" };
3.游戏场景 游戏场景很简单,东西不多, 这次先简单的把星星地图摆上去, 之前我在 三消 中,虽然是 3.4版本,但是还是用了以前版本的SpriteBatchNode 这次,就不用它了,不是已经更新了么,直接用 Sprite就可以绘制一批图片了。 这个也没有什么道理, 用一个二维数组来存储星星个体, 不要忘记,将plist文件加载进来哟 // 加载plist和png SpriteFrameCache::getInstance()->addSpriteFramesWithFile("stars.plist"); starSheet = Sprite::create(); starSheet->setAnchorPoint(Vec2::ZERO); this->addChild(starSheet,1); // 初始化坐标值 mapLBX = (GAME_SCREEN_WIDTH - STAR_WIDTH * COLS - (COLS - 1) * BOADER_WIDTH) / 2; mapLBY = (GAME_SCREEN_HEIGHT - STAR_WIDTH * ROWS - (ROWS - 1) * BOADER_WIDTH) / 2; auto sprite = Sprite::create("bg_mainscene.jpg"); sprite->setPosition(Vec2(GAME_SCREEN_WIDTH/2,GAME_SCREEN_HEIGHT/2)); this->addChild(sprite,0); initMap(); 初始化地图的函数 和 创建星星的函数: // 初始化地图 void GameScene::initMap( ) { for( int r = 0 ; r < ROWS ; ++r ){ for( int c = 0 ; c < COLS ; ++c ){ createStar(r,c); } } } // 创建星星 void GameScene::createStar( int row,int col ) { Star* spr = Star::create(row,col); Point pos = positionOfItem(row,col); spr->setPosition(pos); starSheet -> addChild(spr); // 填充数组相应位置 map[row][col] = spr; } 这样,运行下,可以发现,星星已经在地图上蓄势待发啦~
> 接下来就是要做 点击星星 让其处于 高亮 状态 4.触摸事件的处理 要与星星互动,当然,先要进行触摸事件的处理: // GameScene.cpp init函数 // 触摸事件处理 auto touchListener = EventListenerTouchOneByOne::create(); touchListener->onTouchBegan = CC_CALLBACK_2(GameScene::onTouchBegan,this); _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,this); 然后设定它的触摸函数 逻辑:当我们一个星星时,要让它和它四个方向上同色的星星都处于高亮状态。 方法:用一个搜索算法, ① 让当前星星处于高亮状态 ② 将当前星星分别与和四个方向上星星进行 颜色比较 如果相同,将该星星坐标,扔进函数 如果不同,则跳过 当然,还有一点要注意,需要一个标记二维数组,让遍历过的星星不再被遍历。 否则可能出现死循环。 // 触摸事件 bool GameScene::onTouchBegan(Touch *touch,Event *unused) { auto location = touch->getLocation(); Star* sta; sta = starOfPoint(&location); if( sta ) { // 初始化记忆地图mapR+恢复普通状态 for( int i = 0 ; i < ROWS ; i++ ) { for( int j = 0 ; j <COLS ; j++ ) { mapR[i][j] = false; map[i][j]->setDisplayMode(DISPLAY_MODE_NORMAL); } } // 如果只有当前一个星星这个颜色,不要让它处于高亮状态 if( waitPop(sta->getRow(),sta->getCol()) == 1 ) sta->setDisplayMode(DISPLAY_MODE_NORMAL); } return true; } 这里的mapR数组就是负责标记已经遍历过的星星, int GameScene::waitPop(int row,int col) { int i,r,c,tol; // 四个方向 int search[4][2]={-1,1,-1}; tol = 1; map[row][col]->setDisplayMode(DISPLAY_MODE_HEART); mapR[row][col] = true; // 四个方向遍历 for( i = 0 ; i < 4 ; i++ ) { r = row + search[i][0]; c = col + search[i][1]; if( r >= 0 && r < ROWS && c >= 0 && c < COLS ) { if( map[row][col]->getImgIndex() == map[r][c]->getImgIndex() && !mapR[r][c] ) { mapR[r][c] = true; tol += waitPop(r,c); } } } return tol; }
5.工具函数 ?positionOfItem 这个函数是根据行列值来获取坐标位置: // 根据行列,获取坐标值 Point GameScene::positionOfItem(int row,int col) { float x = mapLBX + (STAR_WIDTH + BOADER_WIDTH) * col + STAR_WIDTH / 2; float y = mapLBY + (STAR_WIDTH + BOADER_WIDTH) * row + STAR_WIDTH / 2; return Point(x,y); } ?starOfPoint 这个函数是根据 坐标位置,来获取那个位置的星星 // 根据触摸点,判断地图上的星星位置 Star* GameScene::starOfPoint(Point *point) { Star *sta = NULL; Rect rect = Rect(0,0); Size sz; sz.height=STAR_WIDTH; sz.width=STAR_WIDTH; for( int r = 0 ; r < ROWS ; ++r ) { for( int c = 0 ; c < COLS ; ++c ) { sta = map[r][c]; if( sta ) { rect.origin.x = sta->getPositionX() - ( STAR_WIDTH / 2); rect.origin.y = sta->getPositionY() - ( STAR_WIDTH / 2); rect.size = sz; if (rect.containsPoint(*point)) { return sta; } } } } return NULL; } 演示一下:
OK,这一篇就先到这里吧~
本篇源码: > 这里 <
PS: 本文图片资源来自 hezijian22
******************************************** (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |