欢迎大家转载http://blog.csdn.net/demon_wu/article/details/9925663

上一章节是一个下午的功劳,做了基础的界面和发射的功能,发射完了我们需要停止,停止是在两种情况下,一是在顶层,一是碰撞到其他球的时候,所以需要添加一个函数来进行判断的

bool MainLayer::checCollideBoard()
{bool bRet = false;//判断是否是顶层if (ready->getPosition().y > 960 -30){bRet = true;return bRet;}//检验是否与其他的泡泡发生碰撞for (int i = MAX_ROWS - 1; i >= 0; --i){for (int j = 0; j < MAX_COLS; ++ j){PaoPao *obj = board[i][j];//采取圆形碰撞检验if (obj && isCircleCollision(obj->getPosition(), 30.0, ready->getPosition(), 30.0)){bRet = true;break;}}if (bRet) break;}return bRet;
}

同时需要在update里面移动完位置的时候进行此判断,然后执行位置确认,因为我们如果现在停止,那么位置将不会是准确的位置,所以需要进行修改,修改完位置过后需要做的是判断是否有可以消除的泡泡以及是否有可以掉落的泡泡,如果有的话执行相关操作。先添加update里面需要添加的代码:

void MainLayer::update(float fDelta) //update函数
{if (isCollideBorder()) //先判断是否碰撞{real.x = -real.x; //如果碰撞就需要反方向移动}CCPoint pos = ready->getPosition(); //获取当前发射的泡泡的位置ready->setPosition(ccp(pos.x + real.x * PAOPAO_SPEED, pos.y + real.y * PAOPAO_SPEED)); //设置泡泡的位置if (checCollideBoard()) //检验可以停止碰撞了{real = CCPointZero;correctReadyPosition(); //修正位置this->unscheduleUpdate(); //取消updatechangeWaitToReady(); //将等待使用的泡泡移动位置setEnable();return ;}
}

我们判断可以停止过后先做修正位置,因为之前有一个函数是通过行、列和_flag来确定泡泡的位置,所以我采用了一个笨办法来确认位置,就是遍历所有的泡泡位置,哪一个位置与我当前位置最近并且没有泡泡存在,那么我将泡泡移动过去,使用的效果还不错。

//确认发射出去泡泡的位置
void MainLayer::correctReadyPosition()
{int offX, offY;offX = 0;offY = 0;CCPoint pos = ready->getPosition();float length = FLT_MAX;bool flag = getFirstRowFlag(); //获取第一行的flag值,虽然暂时没有做下移,但是当增加下移的时候这个方法是需要的bool tempFlag = flag;for (int i = 0; i < MAX_ROWS; ++ i) //此方法可以优化,暂时先采取笨办法{for (int j = 0; j < MAX_COLS; ++ j){if (!board[i][j]){CCPoint tPos = getPointByRowAndCol(i, j, flag);if (ccpDistance(tPos, pos) < length){offX = i;offY = j;tempFlag = flag;length = ccpDistance(tPos, pos);}}}flag = !flag;}//将ready数据转换board[offX][offY] = ready;ready->setFlag(tempFlag);ready->setPosition(getPointByRowAndCol(offX, offY, tempFlag));ready = NULL;sameSum = 0;findTheSamePaoPao(offX, offY, tempFlag, board[offX][offY]->getType()); //检查出所有相同的泡泡,并且执行消除动画效果resetAllPass(); //初始化所有的pass,表示所有泡泡是不能到达checkDownPaoPao(); //检验出哪些泡泡是能够到达的downPaoPao(); //对于不能到达的泡泡来说是可以掉落的
}

当确认泡泡停止的位置时候将ready也就是使用中的球球状态设置为NULL,同时去查找出所有相同的泡泡,重点来了,对于泡泡龙游戏来说,只是根据我当前发射泡泡停的位置开始寻找出附近是否是有相同的泡泡,如果有相同的泡泡并且超过或等于三个的时候表示可以消除。一个泡泡与它相邻的位置有六个,左、右、左上、右上、左下、右下,只要其中任何一个位置泡泡符合相同这个条件,那么我们需要通过那个位置泡泡以相同的方法去寻找,这正是用递归的好时候呀,代码如下:

void MainLayer::findTheSamePaoPao(int i, int j, bool flag, PAOPAO_TYPE type)
{if (i < 0 || i >= MAX_ROWS || j < 0 || j >= MAX_COLS) //退出递归条件一:超出范围{return ;}if (!board[i][j]) //退出递归条件二:该位置没有泡泡{return ;}if (board[i][j]->getType() != type) //退出递归条件三:当前的类型不一样{return ;}if (board[i][j]->getIsSame()) //退出递归条件三:当前已经判断过是相同的{return;}//现在时符合条件的,将会进行递归调用/*首先将自己isSame设置为true,并且增加theSame从当前位置左上,右上,左下,右下,左,右六个方向进行寻找*/board[i][j]->setIsSame(true);++sameSum;//左上if (flag && j > 0 && i > 0) //当该行是最左的时候,要求不是第一个{findTheSamePaoPao(i - 1, j - 1, !flag, type);}else if (!flag && i > 0) //不是最左的时候只需要控制不是第一行{findTheSamePaoPao(i - 1, j, !flag, type);}//右上if (flag && i > 0) //当时最左的时候右上{findTheSamePaoPao(i - 1, j, !flag, type);}else if (!flag && i > 0 && j < MAX_COLS - 1) //当不是最左的时候右上{findTheSamePaoPao(i - 1, j + 1, !flag, type);}//左下if (flag && j > 0 && i < MAX_ROWS) //当该行是最左的时候,要求不是第一个{findTheSamePaoPao(i + 1, j - 1, !flag, type);}else if (!flag && i < MAX_ROWS) //不是最左的时候只需要控制不是第一行{findTheSamePaoPao(i + 1, j, !flag, type);}//右下if (flag && i < MAX_ROWS) //当时最左的时候右上{findTheSamePaoPao(i + 1, j, !flag, type);}else if (!flag && i < MAX_ROWS && j < MAX_COLS - 1) //当不是最左的时候右上{findTheSamePaoPao(i + 1, j + 1, !flag, type);}//左if (j > 0){findTheSamePaoPao(i, j - 1, flag, type);}//右if (j < MAX_COLS){findTheSamePaoPao(i, j + 1, flag, type);}//当找到三个以上的时候开始进行设置消除,如果没有三个的时候将会还原if (sameSum >= 3){PaoPao *obj = board[i][j];paopaoAction(obj);board[i][j] = NULL;}else{board[i][j]->setIsSame(false);}
}

上面说的六个方向是对于正常的泡泡,但是在边界的泡泡需要采取判断,判断依据是通过flag和是否是第一个或者是最后一个等,找到泡泡后通过paopaoAction函数来给泡泡相应的动画效果,执行完动画后将其移除掉。

当泡泡消除后将会使一些泡泡是孤立在一起的,也就是没有悬挂点,这些泡泡是需要掉落的泡泡,当初想怎么判断是否没有悬挂点的时候走了弯路,我直接说出现在的思想,因为第一行的是不用判断是否有悬挂点,因为他们就是初始的悬挂点,但是我们需要通过这些悬挂点找出有哪些是被悬挂的,现在假如这个泡泡是悬挂点,那么我们要判断它左、右、左下、右下是否是有泡泡,有的话设置pass值为true,表示可以到达,也就是可以继续作为悬挂点,因为使用循环一行一行找的话有一个问题,我从该行第一个找到最后一个的时候是通过自身来判断的,但是有可能右边一个是悬挂点,但是自己不是悬挂点,那么将会影响到判断,所有采取了两次遍历,一次从第一个找到最后一个,一次是从最后找到第一个来解决。刚说的情况如下图:

如果按照一次遍历,左边那个泡泡将不会被认为是悬挂点,所以需要从左到右两次遍历才可以的,其代码如下:

void MainLayer::checkDownPaoPao()
{for (int i = 0; i < MAX_COLS; ++ i) //设置好第一行关联{if (board[0][i]) board[0][i]->setIsPass(true);}//通过第一行来设置下一行的链接情况for (int i = 0; i < MAX_ROWS; ++ i){//当该点符合条件的时候,因为从左到右判断一次,再从右到左判断一次/*当第一次的时候横着只关心右边,第二次的时候横着只关心左边剩下关心与自己相关的下面两个*///第一次for (int j = 0; j < MAX_COLS; ++ j){if (board[i][j] && board[i][j]->getIsPass()){//右边if (j < MAX_COLS - 1 && board[i][j + 1]) board[i][j + 1]->setIsPass(true);if (i < MAX_ROWS - 1){//左下if (board[i][j]->getFlag() && j > 0 && board[i + 1][j - 1]) board[i + 1][j - 1]->setIsPass(true);else if (!(board[i][j]->getFlag()) && board[i + 1][j]) board[i + 1][j]->setIsPass(true);//右下if (board[i][j]->getFlag() && board[i + 1][j]) board[i + 1][j]->setIsPass(true);else if (!(board[i][j]->getFlag()) && j < MAX_COLS - 1 && board[i + 1][j + 1]) board[i + 1][j + 1]->setIsPass(true);}}}//第二次for (int j = MAX_COLS - 1; j >= 0; -- j){if (board[i][j] && board[i][j]->getIsPass()){//左边if (j > 0 && board[i][j - 1]) board[i][j - 1]->setIsPass(true);if (i < MAX_ROWS - 1){//左下if (board[i][j]->getFlag() && j > 0 && board[i + 1][j - 1]) board[i + 1][j - 1]->setIsPass(true);else if (!(board[i][j]->getFlag()) && board[i + 1][j]) board[i + 1][j]->setIsPass(true);//右下if (board[i][j]->getFlag() && board[i + 1][j]) board[i + 1][j]->setIsPass(true);else if (!(board[i][j]->getFlag()) && j < MAX_COLS - 1 && board[i + 1][j + 1]) board[i + 1][j + 1]->setIsPass(true);}}}}
}

当找到所有可以到达点,就只需要知道哪些不可以到达,不可以到达就需要掉落动画就可以了。

源码地址,VS版源码地址源码是完整的。

欢迎大家光临。

基于cocos2d-x简易泡泡龙游戏二相关推荐

  1. 基于cocos2d-x简易泡泡龙游戏

    欢迎转载http://blog.csdn.net/demon_wu/article/details/9919115 最近公司的项目一直没有开工,所以自己给自己点事情做,写了一个简易的泡泡龙游戏.实习三 ...

  2. 『牛角书』基于JS实现的鸿蒙游戏——二十四点纸牌

    目录 前言 概述 正式开始 一.创建项目 二.编码 1.项目结构 2.实现思路 3.主要代码块 三.页面及功能展示 1.运算正确 2.运算错误 3.换一批及重置 本人项目仓库链接 前言 相信大家都有玩 ...

  3. 基于前端实现的JS游戏-二开水果忍者

    下来看看效果吧! 这个是游戏结束! 游戏均可二开,自己可以下载后,吧图片,音乐改成自己的.这个是文件 图片在image里面修改,游戏难度在js代码修改,目前已经在重要难度修改的地方已经添加注释. 音乐 ...

  4. 基于控制台的五子棋小游戏(简易)

    基于控制台的五子棋小游戏(简易) 展示 源码: 使用: GoBang类: 展示 话不多说上代码 Don't talk much, say the code! 源码: 使用: new完直接运行 publ ...

  5. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第十二讲:盒子的定位方式

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第十二讲:盒子的定位方式 摘要:通过前节<第十一讲:浮动>学习了贵阳网站建设中的DIV+CSS中盒子模型和浮动进行介绍.框模型是CSS的基础,本文 ...

  6. 基于Python pygame简易版斗兽棋小游戏源代码

    基于Python pygame简易版斗兽棋小游戏源代码 游戏规则如下: 胜利条件: 1.吃掉对方全部棋子 2.走入对方兽穴(不可进入自己洞穴) 吃法: 1.象>狮>虎>豹>狼& ...

  7. unity塔防游戏开发之基于标点法来简易实现敌人路线移动

    unity塔防游戏开发之基于标点法来简易实现敌人路线移动 首先创建一个物体,把它设置为静态物体,给他创建一系列子物体,将这些子物体放在各个路线的转角处,这样就实现标点的目的,然后将这些路标的位置都设置 ...

  8. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第51讲:PHP中smarty模板技术介绍

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第51讲:PHP中smarty模板技术介绍 smarty模板技术PHP程序设计中必须掌握的知识,本文结合贵阳网站建设中的案例介绍了基于smarty技术的员工列 ...

  9. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第37讲:HTTP协议请求(响应)

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第37讲:HTTP协议请求(响应) 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.h ...

最新文章

  1. 【HDU】3308 LCIS
  2. Windows10上使用VS2017编译OpenCV3.4.2+OpenCV_Contrib3.4.2+Python3.6.2操作步骤
  3. 无监督学习:大数据带我们洞察现在,但小数据将带我们抵达未来
  4. 使用ueditor小结
  5. 基于keras 的神经网络股价预测模型
  6. [已解决] java 增加 ALPN支持
  7. maven环境下,控制台中文乱码
  8. 安防工业交换机将成为安防监控系统主要的传输设备
  9. 大数据统计学之概率论(三)
  10. (50)Xilinx Multiplier IP核配置(十一)(第10天)
  11. Linux下的Python Socket网络编程(聊天机器人)
  12. 哪几种人会被房价拐点忽悠
  13. ubuntu切换用户root时认证失败
  14. Core Graphics Paths
  15. 运维自动化之zabbix(添加Graph screen)(3)
  16. java类中静态变量自增_Java中静态变量(类变量)、实例变量、局部变量和成员变量...
  17. 用程序关闭、注销、重启计算机
  18. Hamming(汉明)窗的原理介绍及实例解析
  19. 传奇服务端GOM引擎和GEE引擎区别在哪里?
  20. 测试电脑整机功耗软件,最真实的耗电!PConline权威整机功耗评测

热门文章

  1. 使用基于Apache Spark的随机森林方法预测贷款风险
  2. [Demo]提取个人博客园闪存+评论
  3. XCTF Leaking
  4. python找到一行单词中最长的_python - 查找.txt文件中最长的单词,不带标点符号 - SO中文参考 - www.soinside.com...
  5. 老铁是要塞里最出名的铁匠大师,小铁是老铁的儿子,老铁希望小铁能传承他的衣钵为要塞的骑士们锻造护甲。经近一段时间的学习,小铁逐渐掌握了打铁的技术,但是他很快发现,每一天手臂的力量总是不如前一天
  6. unity3D赛车游戏项目源代码
  7. MMA8452加速传感器的应用(简)
  8. 温度传感器LM35实验
  9. 用户角色及权限管理设计实例(基于RBAC模型)
  10. 步进电机正反转实验_只用一个接触器实现三相电机正反转