第五章——如何检测碰撞

我们的英雄现在可以发射子弹了,但仅仅只是装饰而已,如何才能杀掉怪物呢?

http://cn.cocos2d-x.org/resource/show?nid=68

我们的英雄现在可以发射子弹了,但仅仅只是装饰而已,如何才能杀掉怪物呢?

在这一章,我们将介绍碰撞检测来实现这一效果。

首先,跟踪怪物和子弹是必需的。

在游戏中,我们为这两种精灵加以不同的tag来区分它们。当tag=1时,表示这是怪物,而tag=2时,则表示这为子弹。由于在CCNode里面有m_nTag这个成员变量,并且有setTag和getTag方法,因此CCSprite就继承了这些方法,我们可以利用之。

在HelloWorldScene.h中,把以下两个成员变量加入到HelloWorld下,这两个成员变量用于缓存现有的怪物和子弹。

1// cpp with cocos2d-x
2protected:
3 cocos2d::CCMutableArray<cocos2d::CCSprite*> *_targets;
4 cocos2d::CCMutableArray<cocos2d::CCSprite*> *_projectiles;
1// objc with cocos2d-iphone
2 NSMutableArray *_targets;
3 NSMutableArray *_projectiles;

在cocos2d-x里,CCMutableArray相当于iOS SDK中的NSMutableArray,该数组里的成员可以是NSObject或者他们的子类。但不同的是,你必须告诉它里面要放的是哪种具体的类型。

之后构造函数中初始化这两个变量,在init()中new 它们,并在析构函数中release 它们。

1// cpp with cocos2d-x
2
3// in init()
4// Initialize arrays
5_targets = new CCMutableArray<CCSprite*>;
6_projectiles = new CCMutableArray<CCSprite*>;
7
8HelloWorld::~HelloWorld()
9{
10 if (_targets)
11 {
12 _targets->release();
13 _targets = NULL;
14 }
15
16 if (_projectiles)
17 {
18 _projectiles->release();
19 _projectiles = NULL;
20 }
21
22 // cpp don't need to call super dealloc
23 // virtual destructor will do this
24}
25
26HelloWorld::HelloWorld()
27:_targets(NULL)
28,_projectiles(NULL)
29{
30}
1// objc with cocos2d-iphone
2// in init()
3// Initialize arrays
4_targets = [[NSMutableArray alloc] init];
5_projectiles = [[NSMutableArray alloc] init];
6
7- (void) dealloc
8{
9 [_targets release];
10 _targets = nil;
11
12 [_projectiles release];
13 _projectiles = nil;
14
15 // don't forget to call "super dealloc"
16 [super dealloc];
17}

现在可以修改addTarget(),把新目标添加到目标数组中,并设置其tag为1。
1// cpp with cocos2d-x
2// Add to targets array
3target->setTag(1);
4_targets->addObject(target);
1// objc with cocos2d-iphone
2// Add to targets array
3target.tag = 1;
4[_targets addObject:target];

修改ccTouchesEnded(),把新子弹加入到子弹数组中,并设置其tag为2。
1// cpp with cocos2d-x
2// Add to projectiles array
3projectile->setTag(2);
4_projectiles->addObject(projectile);
1// objc with cocos2d-iphone
2// Add to projectiles array
3projectile.tag = 2;
4[_projectiles addObject: projectile];

之后,按下面修改spriteMoveFinished()。这里根据标记的不同,在对应的数组中移除精灵

1// cpp with cocos2d-x
2void HelloWorld::spriteMoveFinished(CCNode* sender)
3{
4 CCSprite *sprite = (CCSprite *)sender;
5 this->removeChild(sprite, true);
6
7 if (sprite->getTag() == 1) // target
8 {
9 _targets->removeObject(sprite);
10 }
11 else if (sprite->getTag() == 2) // projectile
12 {
13 _projectiles->removeObject(sprite);
14 }
15}
1// objc with cocos2d-iphone
2-(void)spriteMoveFinished:(id)sender
3{
4 CCSprite *sprite = (CCSprite *)sender;
5 [self removeChild:sprite cleanup:YES];
6
7 if (sprite.tag == 1) // target
8 {
9 [_targets removeObject:sprite];
10 }
11 else if (sprite.tag == 2) // projectile
12 {
13 [_projectiles removeObject:sprite];
14 }
15}

下面的update()函数用于检测每帧的碰撞,并从游戏中删除碰撞中的子弹和怪物。
请在HelloWorldScene.h中声明,在HelloWorldScene.cpp中定义。
1// cpp with cocos2d-x
2void HelloWorld::update(ccTime dt)
3{
4 CCMutableArray<CCSprite*> *projectilesToDelete =
5 new CCMutableArray<CCSprite*>;
6 CCMutableArray<CCSprite*>::CCMutableArrayIterator it, jt;
7
8 for (it = _projectiles->begin(); it != _projectiles->end(); it++)
9 {
10 CCSprite *projectile =*it;
11 CCRect projectileRect = CCRectMake(
12 projectile->getPosition().x
13 - (projectile->getContentSize().width/2),
14 projectile->getPosition().y
15 - (projectile->getContentSize().height/2),
16 projectile->getContentSize().width,
17 projectile->getContentSize().height);
18
19 CCMutableArray<CCSprite*>*targetsToDelete
20 = new CCMutableArray<CCSprite*>;
21
22 for (jt = _targets->begin(); jt != _targets->end(); jt++)
23 {
24 CCSprite *target =*jt;
25 CCRect targetRect = CCRectMake(
26 target->getPosition().x - (target->getContentSize().width/2),
27 target->getPosition().y - (target->getContentSize().height/2),
28 target->getContentSize().width,
29 target->getContentSize().height);
30
31 if (CCRect::CCRectIntersectsRect(projectileRect, targetRect))
32 {
33 targetsToDelete->addObject(target);
34 }
35 }
36
37 for (jt = targetsToDelete->begin();
38 jt != targetsToDelete->end();
39 jt++)
40 {
41 CCSprite *target =*jt;
42 _targets->removeObject(target);
43 this->removeChild(target, true);
44 }
45
46 if (targetsToDelete->count() >0)
47 {
48 projectilesToDelete->addObject(projectile);
49 }
50 targetsToDelete->release();
51 }
52
53 for (it = projectilesToDelete->begin();
54 it != projectilesToDelete->end();
55 it++)
56 {
57 CCSprite* projectile =*it;
58 _projectiles->removeObject(projectile);
59 this->removeChild(projectile, true);
60 }
61 projectilesToDelete->release();
62}
1// objc with cocos2d-iphone
2- (void)update:(ccTime)dt
3{
4 NSMutableArray *projectilesToDelete
5 = [[NSMutableArray alloc] init];
6
7 for (CCSprite *projectile in _projectiles)
8 {
9
10 CGRect projectileRect = CGRectMake(
11 projectile.position.x - (projectile.contentSize.width/2),
12 projectile.position.y - (projectile.contentSize.height/2),
13 projectile.contentSize.width,
14 projectile.contentSize.height);
15
16 NSMutableArray *targetsToDelete
17 = [[NSMutableArray alloc] init];
18
19 for (CCSprite *target in _targets)
20 {
21
22 CGRect targetRect = CGRectMake(
23 target.position.x - (target.contentSize.width/2),
24 target.position.y - (target.contentSize.height/2),
25 target.contentSize.width,
26 target.contentSize.height);
27
28 if (CGRectIntersectsRect(projectileRect, targetRect))
29 {
30 [targetsToDelete addObject:target];
31 }
32 }
33
34 for (CCSprite *target in targetsToDelete)
35 {
36
37 [_targets removeObject:target];
38 [self removeChild:target cleanup:YES];
39 }
40
41 if (targetsToDelete.count >0)
42 {
43 [projectilesToDelete addObject:projectile];
44 }
45 [targetsToDelete release];
46 }
47
48 for (CCSprite *projectile in projectilesToDelete)
49 {
50
51 [_projectiles removeObject:projectile];
52 [self removeChild:projectile cleanup:YES];
53 }
54 [projectilesToDelete release];
55}

好了,最后一件事,我们要把update()加入到schedule里让它每帧都能被调用。
1// cpp with cocos2d-x
2this->schedule( schedule_selector(HelloWorld::update) );
1// objc with cocos2d-iphone
2[self schedule:@selector(update:)];

编译并运行项目,尽情地发射子弹吧,这时:啊哈,怪物都一个接着一个地被干掉了。
http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Chapter_5_-_How_to_Detect_the_Collisions

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值