Skip to content

cocos2d x 3.3 019 碰撞检测1 矩形区域是否相交

cheyiliu edited this page Feb 5, 2015 · 1 revision

原理

  • Cocos里面的每个Node都有一个和它对应的矩形区域,通过api getBoundingBox()得到。碰撞监测就是判断两个物体的矩形区域是否有交叠,相应的API是intersectsRect。有交叠则认为是碰撞了。

Demo及源码

Demo解读

  • 每隔5s生成: 两架飞机,并从右往左飞行; 两颗子弹,从左向右飞。
  • 每一帧里面作碰撞检测,若有碰撞,则播放相应的动画。
  • 为了追踪所有的子弹和飞机,得有对应的辅助数据结构,这里采用Vector。

主要代码

  • 开启相关timer
		scheduleUpdate();
		schedule(schedule_selector(HelloWorld::updateCustom), 5.0f,
				kRepeatForever, 0);
  • 生成子弹或者飞机并放到对应的辅助数据结构来跟踪
void HelloWorld::buildBullet(int startX, int endX, int actualY) {
	log("buildBullet");

	std::string name = "bullet1.png";
	auto sp = Sprite::createWithSpriteFrameName(name);

	Point startPos = Point(startX, actualY);
	Point endPos = Point(endX, actualY);

	sp->setPosition(startPos);
	sp->runAction(
			Sequence::create(MoveTo::create(3.0, endPos),
					CallFuncN::create(this,
							callfuncN_selector(HelloWorld::spriteDone)), NULL));
	sp->setRotation(-90);
	sp->setTag(TAG_BULLET);
	mBullets.pushBack(sp);//放入数组
	this->addChild(sp);
}
  • 每一帧里作碰撞监测,这里简单demo了下。 更复杂的逻辑处理见扩展阅读
void HelloWorld::update(float dt) {
//    log("update, %d", mPlanes.size());
//    log("update, %d", mBullets.size());
	//碰撞检测
	Vector<Sprite*> bulletsToBeRemoved;
	Vector<Sprite*> planeToBeRemoved;
	for (auto bullet : mBullets) {
		for (auto plane : mPlanes) {
			if (bullet->boundingBox().intersectsRect(plane->getBoundingBox())) {
				log("碰撞了。。。。。。。。");
				bulletsToBeRemoved.pushBack(bullet);
				planeToBeRemoved.pushBack(plane);
			}
		}
	}

	// do remove
	for (auto bullet : bulletsToBeRemoved) {
		mBullets.eraseObject(bullet);
		log("removeChild(bullet)");
		this->removeChild(bullet);
	}
	bulletsToBeRemoved.clear();

	for (auto plane : planeToBeRemoved) {
		mPlanes.eraseObject(plane);
		planeBlowup(plane);
	}
	planeToBeRemoved.clear();
}

优缺点

  • 优点: 对于简单需求,使用起来简单
  • 缺点: 要费力的维护几个数组,当需求复杂时不易扩充和复用

效果图

CollisionDetection-way1-use-intersectsRect.gif

扩展阅读

Clone this wiki locally