尊重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/17327287
<捕鱼达人>回顾
【cocos2d-x IOS游戏开发-捕鱼达人1】内容介绍
上节回顾
【cocos2d-x IOS游戏开发-城市跑酷15】完善积分板【CCLabelBMFont】
到现在为止,如果不做碰撞检测,就会看到主角一直在一条线上运动,甚至还会被房子遮挡;
也不会撞到忽然高起来的房子,也不会从房子上掉下来;
所以就需要在update函数里增加碰撞检测,以增强游戏的可玩性!!!
首先来了解一下CCNODE的几个常用到的几个函数:
CCNode类的setPosition,getPosition函数:如果是一个Node的Child则获取的坐标就是该Node的本地坐标;
CCPoint CCDirector::convertToGL(const CCPoint& uiPoint) { CCSize s = m_obWinSizeInPoints; float newY = s.height - uiPoint.y; }
CCPoint CCDirector::convertToUI(const CCPoint& glPoint) { CCSize winSize = m_obWinSizeInPoints; float oppositeY = winSize.height - glPoint.y; return ccp(glPoint.x,oppositeY); }
到这里,我们就很清楚了,碰撞检测可以这样实现:
碰撞检测:检查XY轴,即检查底部碰撞和侧边碰撞,
从房子上掉下来:利用boundingBox,获取当前主角的位置,已经小于了主角是身体的时候就认为是掉房子下面了;
看具体的代码:
碰撞检测实现代码:
void Terrain::checkCollision (Player * player) { //检查主角状态,死亡则跳出 if (player->getState() == kPlayerDying) return; //街区总块数 int count = _blocks->count(); Block * block; //是否在空中 bool inAir = true; int i; for (i = 0; i < count; i++) { block = (Block *) _blocks->objectAtIndex(i); if (block->getType() == kBlockGap) continue; //if within x, check y (bottom collision) //当主角和房子在X轴上时 if (player->right() >= this->getPositionX() + block->left() && player->left() <= this->getPositionX() + block->right()) { if (player->bottom() >= block->top() && player->next_bottom() <= block->top() && player->top() > block->top()) { player->setNextPosition(ccp(player->getNextPosition().x, block->top() + player->getHeight())); player->setVector ( ccp(player->getVector().x, 0) ); // Sets the rotation (angle) of the node in degrees player->setRotation(0.0); inAir = false; break; } } } for (i = 0; i < count; i++) { block = (Block *) _blocks->objectAtIndex(i); if (block->getType() == kBlockGap) continue; //now if within y, check x (side collision) //右侧房子突然高起 if ((player->bottom() < block->top() && player->top() > block->bottom()) || (player->next_bottom() < block->top() && player->next_top() > block->bottom())) { if (player->right() >= this->getPositionX() + block->getPositionX() && player->left() < this->getPositionX() + block->getPositionX()) { player->setPositionX( this->getPositionX() + block->getPositionX() - player->getWidth() * 0.5f ); player->setNextPosition(ccp(this->getPositionX() + block->getPositionX() - player->getWidth() * 0.5f, player->getNextPosition().y)); player->setVector ( ccp(player->getVector().x * -0.5f, player->getVector().y) ); //主角装墙上了 if (player->bottom() + player->getHeight() * 0.2f < block->top()) { player->setState(kPlayerDying); return; } break; } } } if (inAir) { //设置下降状态 player->setState(kPlayerFalling); } else { //设置一直移植状态 player->setState(kPlayerMoving); player->setFloating (false); } }
//主角未死亡则检查碰撞冲突 if (_player->getState() != kPlayerDying) _terrain->checkCollision(_player);主角掉下去了:
//获取主角位置 if (_player->getPositionY() < -_player->getHeight() || _player->getPositionX() < -_player->getWidth() * 0.5f) { if (_state == kGamePlay) { _running = false; //create GAME OVER state _state = kGameOver;}}