Cocos2d-x 3.4 之 消灭星星 > 第二篇 <
2015-05-24 22:42
260 查看
***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************
这个,要说一下,
本系列文章,我是边写边发,所以可能前后有些改动。
上篇文章,已经做到了 游戏场景,点击星星,使其高亮状态。
这篇文章,将游戏逻辑玩法搞定:
> 星星 高亮状态 再次点击,消除
> 星星消除后,剩下的星星整合(下落或左移)
> 检测是否有可消除的星星,没有则跳转到 游戏结束界面
正文:
1. 星星 高亮状态下的消除
触摸事件函数 onTouchBegan需要重写一下:
// 触摸事件
bool GameScene::onTouchBegan(Touch *touch, Event *unused) {
auto location = touch->getLocation();
Star* sta;
sta = starOfPoint(&location);
// 当前对象不为空
if( sta ) {
// 看该 星星 处于什么状态
if( sta->getDisplayMode() == DISPLAY_MODE_NORMAL ) {
// 初始化记忆地图mapR+恢复普通状态
for( int i = 0 ; i < ROWS ; i++ ) {
for( int j = 0 ; j <COLS ; j++ ) {
mapR[i][j] = false;
if( map[i][j]!=NULL )
map[i][j]->setDisplayMode(DISPLAY_MODE_NORMAL);
}
}
// 如果只有当前一个星星这个颜色,不要让它处于高亮状态
if( waitPop(sta->getRow(),sta->getCol()) == 1 ) {
mapR[sta->getRow()][sta->getCol()]=false;
sta->setDisplayMode(DISPLAY_MODE_NORMAL);
}
}
else
{
deleteStar();
}
}
return true;
}
在 所触摸的星星 非空的前提下,
判断该星星是否为高亮状态,如果不是,则初始化mapR,并将所有 星星 的显示状态恢复成 普通,
注意,这里所有星星的显示状态中,要把消除掉的过滤掉,否则会出错的。
然后是 deleteStar函数:
void GameScene::deleteStar( void )
{
int r,c;
for( r = 0 ; r < ROWS ; r++ ) {
for( c = 0 ;c < COLS ; c++ ) {
if( mapR[r][c] == true ) {
// popStar(map[i][j]);
map[r][c]->removeFromParent();
map[r][c]=NULL;
}
}
}
}
这里的popStar函数,是用来后期加一些特效啥的,先保留一下。
注意,在删除某个星星的时候,不要忘了 removeFromParent,将该对象从父节点拿掉。
还有一点,在本类构造函数时候,要对 mapR数组初始化,
可以用 memset,也可以两个for循环,甚至你写N个false赋值也没问题...
这里我用的memset,但要包含 string.h 头文件
现在,我们就可以将高亮的 星星 删除掉了
演示一下:(PS:一直想用GIF演示,但是没找到合适的GIF录制工具(GIFCAM不好用),求大家推荐一款)
2.消除后的整合
在将星星消除后,我们要将剩余的星星聚起来,
所有的星星就是向左下角移动,先向下,再向左....
说一下思路:
向下归拢: 按列为单位,每列中从下往上找,
若该对象为空,将上面第一个不为空的,落下来;
然后再向上找,直到最后。
向左归拢:依旧按列为单位,先判断每列第一行是否为空,
若为空,需要将右面的平移动过来,(因为先下落,再左移,如果第一行为空,上面肯定也为空,所以可以平移)
要注意,这个与下落不一样,每列向左平移相同距离(不是补齐)
Ok,实现起来就是这样:
void GameScene::adjustStar( )
{
int r,c;
// 向下归拢
for( c = 0 ; c < COLS ; c++ ) {
for( r = 0 ; r < ROWS-1 ; r++ ) {
if( map[r][c] == NULL ) {
for( int newR = r+1 ; newR < ROWS ; newR++ ) {
Star* sta = map[newR][c];
if( sta != NULL ) {
map[r][c] = sta;
map[newR][c] = NULL;
Point startPosition = sta->getPosition();
Point endPosition = positionOfItem(r, c);
float speed = (startPosition.y - endPosition.y) / GAME_SCREEN_HEIGHT*2;
sta->stopAllActions();
sta->runAction(MoveTo::create(speed, endPosition));
sta->setRow(r);
break;
}
}
}
}
}
// 向左归拢
for( c = 0 ; c < COLS-1 ; c++ )
if( map[0][c] == NULL ) {
for( int newC=c+1; newC < COLS ; newC++ ) {
if( map[0][newC] != NULL ) {
for( int moveR = 0 ; moveR < ROWS ; moveR++ ) {
Star* sta = map[moveR][newC];
if( sta!=NULL ) {
map[moveR][c] = sta;
map[moveR][newC] = NULL;
Point startPosition = sta->getPosition();
Point endPosition = positionOfItem(moveR,c);
float speed = (startPosition.x - endPosition.x) / GAME_SCREEN_WIDTH*2;
sta->stopAllActions();
sta->runAction(MoveTo::create(speed, endPosition));
sta->setCol(c);
}
}
break;
}
}
}
}
一个非常重要一点,在runAction之前,一定要 stopAllActions!!!
就这一句,我调了一下午,~~o(>_<)o ~~
演示一下:(PS:一直想用GIF演示,但是没找到合适的GIF录制工具(GIFCAM不好用),求大家推荐一款)
3.判断游戏是否结束
这个相对来说就简单很多,因为数组不大,直接遍历,
将 本对象 与上下左右四个方向上对象比较,
如果有同颜色,直接返回false(表示 未结束)
遍历结束后,若没有出现相同颜色的,返回true(表示 结束)
bool GameScene::isFinish( )
{
int i,r,c;
// 四个方向
int search[4][2]={-1,0,1,0,0,1,0,-1};
for( r = 0 ; r < ROWS ; r++ ) {
for( c = 0 ; c < COLS ; c++ ) {
if( !map[r][c] ) continue;
for( i = 0 ; i < 4 ; i++ ) {
int nr = r + search[i][0];
int nc = c + search[i][1];
if( nr>=0 && nr<ROWS && nc>=0 && nc<COLS ) {
if( map[nr][nc]!=NULL ) {
if( map[r][c]->getImgIndex() == map[nr][nc]->getImgIndex() )
return false;
}
}
}
}
}
return true;
}
接下来,简单设置一下,跳转什么的,就可以了。
加新的场景(主界面场景)及跳转那些就不再列出了,直接看下面的源码吧。
游戏大体逻辑已经搞定了,
接下来就是一些增分性内容了,
分数、动画、还有我最想练的 粒子特效~
本篇文章源码: >
这里 <
***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************
这个,要说一下,
本系列文章,我是边写边发,所以可能前后有些改动。
上篇文章,已经做到了 游戏场景,点击星星,使其高亮状态。
这篇文章,将游戏逻辑玩法搞定:
> 星星 高亮状态 再次点击,消除
> 星星消除后,剩下的星星整合(下落或左移)
> 检测是否有可消除的星星,没有则跳转到 游戏结束界面
正文:
1. 星星 高亮状态下的消除
触摸事件函数 onTouchBegan需要重写一下:
// 触摸事件
bool GameScene::onTouchBegan(Touch *touch, Event *unused) {
auto location = touch->getLocation();
Star* sta;
sta = starOfPoint(&location);
// 当前对象不为空
if( sta ) {
// 看该 星星 处于什么状态
if( sta->getDisplayMode() == DISPLAY_MODE_NORMAL ) {
// 初始化记忆地图mapR+恢复普通状态
for( int i = 0 ; i < ROWS ; i++ ) {
for( int j = 0 ; j <COLS ; j++ ) {
mapR[i][j] = false;
if( map[i][j]!=NULL )
map[i][j]->setDisplayMode(DISPLAY_MODE_NORMAL);
}
}
// 如果只有当前一个星星这个颜色,不要让它处于高亮状态
if( waitPop(sta->getRow(),sta->getCol()) == 1 ) {
mapR[sta->getRow()][sta->getCol()]=false;
sta->setDisplayMode(DISPLAY_MODE_NORMAL);
}
}
else
{
deleteStar();
}
}
return true;
}
在 所触摸的星星 非空的前提下,
判断该星星是否为高亮状态,如果不是,则初始化mapR,并将所有 星星 的显示状态恢复成 普通,
注意,这里所有星星的显示状态中,要把消除掉的过滤掉,否则会出错的。
然后是 deleteStar函数:
void GameScene::deleteStar( void )
{
int r,c;
for( r = 0 ; r < ROWS ; r++ ) {
for( c = 0 ;c < COLS ; c++ ) {
if( mapR[r][c] == true ) {
// popStar(map[i][j]);
map[r][c]->removeFromParent();
map[r][c]=NULL;
}
}
}
}
这里的popStar函数,是用来后期加一些特效啥的,先保留一下。
注意,在删除某个星星的时候,不要忘了 removeFromParent,将该对象从父节点拿掉。
还有一点,在本类构造函数时候,要对 mapR数组初始化,
可以用 memset,也可以两个for循环,甚至你写N个false赋值也没问题...
这里我用的memset,但要包含 string.h 头文件
GameScene::GameScene() : starSheet(NULL) ,mapLBX ( (GAME_SCREEN_WIDTH - STAR_WIDTH * COLS - (COLS - 1) * BOADER_WIDTH) / 2 ) ,mapLBY ( (GAME_SCREEN_HEIGHT - STAR_WIDTH * ROWS - (ROWS - 1) * BOADER_WIDTH) / 2 ) { // 初始化 mapR 数组(string.h 头文件) memset(mapR,false,sizeof(mapR)); }
现在,我们就可以将高亮的 星星 删除掉了
演示一下:(PS:一直想用GIF演示,但是没找到合适的GIF录制工具(GIFCAM不好用),求大家推荐一款)
2.消除后的整合
在将星星消除后,我们要将剩余的星星聚起来,
所有的星星就是向左下角移动,先向下,再向左....
说一下思路:
向下归拢: 按列为单位,每列中从下往上找,
若该对象为空,将上面第一个不为空的,落下来;
然后再向上找,直到最后。
向左归拢:依旧按列为单位,先判断每列第一行是否为空,
若为空,需要将右面的平移动过来,(因为先下落,再左移,如果第一行为空,上面肯定也为空,所以可以平移)
要注意,这个与下落不一样,每列向左平移相同距离(不是补齐)
Ok,实现起来就是这样:
void GameScene::adjustStar( )
{
int r,c;
// 向下归拢
for( c = 0 ; c < COLS ; c++ ) {
for( r = 0 ; r < ROWS-1 ; r++ ) {
if( map[r][c] == NULL ) {
for( int newR = r+1 ; newR < ROWS ; newR++ ) {
Star* sta = map[newR][c];
if( sta != NULL ) {
map[r][c] = sta;
map[newR][c] = NULL;
Point startPosition = sta->getPosition();
Point endPosition = positionOfItem(r, c);
float speed = (startPosition.y - endPosition.y) / GAME_SCREEN_HEIGHT*2;
sta->stopAllActions();
sta->runAction(MoveTo::create(speed, endPosition));
sta->setRow(r);
break;
}
}
}
}
}
// 向左归拢
for( c = 0 ; c < COLS-1 ; c++ )
if( map[0][c] == NULL ) {
for( int newC=c+1; newC < COLS ; newC++ ) {
if( map[0][newC] != NULL ) {
for( int moveR = 0 ; moveR < ROWS ; moveR++ ) {
Star* sta = map[moveR][newC];
if( sta!=NULL ) {
map[moveR][c] = sta;
map[moveR][newC] = NULL;
Point startPosition = sta->getPosition();
Point endPosition = positionOfItem(moveR,c);
float speed = (startPosition.x - endPosition.x) / GAME_SCREEN_WIDTH*2;
sta->stopAllActions();
sta->runAction(MoveTo::create(speed, endPosition));
sta->setCol(c);
}
}
break;
}
}
}
}
一个非常重要一点,在runAction之前,一定要 stopAllActions!!!
就这一句,我调了一下午,~~o(>_<)o ~~
演示一下:(PS:一直想用GIF演示,但是没找到合适的GIF录制工具(GIFCAM不好用),求大家推荐一款)
3.判断游戏是否结束
这个相对来说就简单很多,因为数组不大,直接遍历,
将 本对象 与上下左右四个方向上对象比较,
如果有同颜色,直接返回false(表示 未结束)
遍历结束后,若没有出现相同颜色的,返回true(表示 结束)
bool GameScene::isFinish( )
{
int i,r,c;
// 四个方向
int search[4][2]={-1,0,1,0,0,1,0,-1};
for( r = 0 ; r < ROWS ; r++ ) {
for( c = 0 ; c < COLS ; c++ ) {
if( !map[r][c] ) continue;
for( i = 0 ; i < 4 ; i++ ) {
int nr = r + search[i][0];
int nc = c + search[i][1];
if( nr>=0 && nr<ROWS && nc>=0 && nc<COLS ) {
if( map[nr][nc]!=NULL ) {
if( map[r][c]->getImgIndex() == map[nr][nc]->getImgIndex() )
return false;
}
}
}
}
}
return true;
}
接下来,简单设置一下,跳转什么的,就可以了。
加新的场景(主界面场景)及跳转那些就不再列出了,直接看下面的源码吧。
游戏大体逻辑已经搞定了,
接下来就是一些增分性内容了,
分数、动画、还有我最想练的 粒子特效~
本篇文章源码: >
这里 <
***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************
相关文章推荐
- Cocos2d-x 3.4 之 消灭星星 > 第三篇(终) <
- Cocos2d-x 3.4 之 消灭星星 >前言+第一篇<
- Cocos2d-x 3.4 之 消灭星星 > 第三篇(终) <
- cocos2d-x3.0模版容器详解之一:cocos2d::Vector<T>
- cocos2d-x对Vector<Node*>排序
- 自定义控件系列<第二篇>--多维表头
- <cocos2d-x for wp7>动画制作
- Cocos2d-x中Vector<T>容器以及实例介绍
- 关于cocos2d-x2.2.3中定时器<update>的详细解释和使用
- PopStar(消灭星星)游戏源代码下载、分析及跨平台移植---第二篇(算法)
- quick-cocos2d-x的热更新机制实现<六>后记
- Cocos2d-x简单游戏<植物大战僵尸>代码实现|第二部分:菜单场景<后续会提供源码下载链接>
- Cocos2d-x简单游戏<植物大战僵尸>代码实现|第六部分:植物类<后续会提供源码下载链接>
- Cocos2d-x简单Box2d代码示例|点击碰撞>HelloWorldScene.cpp<代码演示>
- Cocos2d-x控件使用CCControlSwitch<代码演示>
- Cocos2d-x简单游戏<捕鱼达人>代码实现|第二部分:子弹、渔网、大炮类
- Redis常用命令速查 <第二篇>
- <编程珠玑>3.4 日期问题 && 杭电hdu acm 2133题目代码
- Cocos2d-x3.0模版容器详解:cocos2d::Vector<T>
- 《Cocos2D-iPhone 游戏开发之路》第4节 高仿<Flappy Bird>教程(2)