假设不适用Box2D物理引擎。那么要进行Cocos2d-x的碰撞检測那我们的方法往往就是进行“矩形和点”、“矩形和矩形”这样粗略的碰撞检測。我们一般採取开启scheduleUpdate定时器。然后重写update函数进行每一帧都进行碰撞检測。
<1>碰撞检測的代码较为繁琐。恕我无法为你具体列出其思路能够是在update中遍历全部的sprite, 然后推断每一个sprite和其它sprite(还需遍历一遍。刨除自己)是否碰撞。这样等于推断次数是sprite的数量的平方,效率非常低。
所以你须要优化一下,比方将“其它sprite(还需遍历一遍)”这个逻辑改成“附近的sprite。 两个sprite的碰撞检測就非常easy了,假设不过矩形推断,非常多教程都会有。
<2>捕鱼达人人家写的碰撞检測。 bool GameScene::checkOutCollisionBetweenFishesAndBullet() { Weapon* weapon = _cannonLayer->getWeapon(); CCPoint bulletCollision = weapon->getCollisionPoint(); CCArray* fishes = _fishLayer->getFishes(); CCObject* iterator; CCARRAY_FOREACH(fishes, iterator){ Fish* fish = (Fish*)iterator; //isRunnning推断fish是否已经在屏幕上显示 if(fish->isRunning()){ CCRect fishCollisionArea = fish->getCollisionArea(); bool isCollision = fishCollisionArea.containsPoint(bulletCollision); if(isCollision){ weapon->end(); return true; } } } return false; } <3>小强写的碰撞检測。“矩形和点的碰撞检測” void GameLayer::shoot_callback(CCObject* pSender) { CCLog("shoot_callback"); CCObject* obj = NULL; CCARRAY_FOREACH(enemyManager->getEnemyArray(),obj) { Enemy* enemy = (Enemy*)obj; CCPoint aimPoint = getChildByTag(100)->getPosition(); if(enemy->boundingBox().containsPoint(aimPoint)) //矩形碰撞检測。boundingBox()这个函数返回容纳这个精灵的矩形。从而结合 { enemy->setHpBar(((Hero*)getChildByTag(101))->damage); return; } } } <4>简单的“矩形与矩形的碰撞检測”。 bool Rectbong::init() { if(!CCLayer::init()) return false; CCSize mysize = CCDirector::sharedDirector()->getWinSize(); CCSprite* sp1 = CCSprite::create("A.png"); sp1->setPosition(ccp(100, mysize.height/2)); this->addChild(sp1, 0,1); //精灵名字,Z 轴位置,Tag值 CCSprite* sp2 = CCSprite::create("B.png"); sp2->setPosition(ccp(mysize.width-300, mysize.height/2)); this->addChild(sp2, 0,2); //在做个显示 CCLabelTTF * ttf=CCLabelTTF::create("none","Arial",20); ttf->setPosition(ccp(mysize.width/2,mysize.height-50)); this->addChild(ttf,0,3); //做个移动 sp1->runAction(CCMoveTo::create(5,ccp(mysize.width-190,mysize.height/2))); //开启更新(在每一帧都会调用update方法,来检測是否碰撞) scheduleUpdate(); return true; } void Rectbong::update(float dt) { CCSprite * sp1=(CCSprite *)this->getChildByTag(1); //通过getChildByTag(...)获取精灵,我感觉比較好用。而不是每次把精灵当做数据成员来用。
CCSprite * sp2=(CCSprite *)this->getChildByTag(2); //这样在addChild(...)时,只须要设置下setTag属性,就能够easy找到精灵,从而尽量用局部变量。 CCLabelTTF * ttf=(CCLabelTTF *)this->getChildByTag(3); // CCRect rect1 = sp1->boundingBox(); CCRect rect2 = sp2->boundingBox(); if(rect1.intersectsRect(rect2)) //矩形碰撞检測。boundingBox()这个函数返回容纳这个精灵的矩形。从而结合intersectsRect进行矩形碰撞检測。 { //我认为当两个物体接近矩形时利用矩形碰撞检測更合适。 ttf->setString("bong!!!!"); }else { ttf->setString("none"); } }