|
|
51CTO旗下网站
|
|
移动端

cocos2d-x如何检测碰撞

我们的英雄现在可以发射子弹了,但仅仅只是装饰而已,如何才能杀掉怪物呢?在这一章,我们将介绍碰撞检测来实现这一效果。

作者:佚名来源:cocos2d-x|2012-04-17 12:44

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

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

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

1// cpp with cocos2d-x

2protected:

3 cocos2d::CCMutableArray *_targets;

4 cocos2d::CCMutableArray *_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;

6_projectiles = new CCMutableArray;

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 *projectilesToDelete =

5 new CCMutableArray;

6 CCMutableArray::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*targetsToDelete

20 = new CCMutableArray;

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:)];

编译并运行项目,尽情地发射子弹吧,这时:啊哈,怪物都一个接着一个地被干掉了。

【责任编辑:立方 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

活学活用 Ubuntu Server

活学活用 Ubuntu Server

实战直通车
共35章 | UbuntuServer

228人订阅学习

Java EE速成指南

Java EE速成指南

掌握Java核心
共30章 | 51CTO王波

87人订阅学习

Mysql DBA修炼之路

Mysql DBA修炼之路

MySQL入门到高阶
共24章 | 51CTO叶老师

483人订阅学习

读 书 +更多

精通ASP+XML+CSS网络开发混合编程

《精通ASP+XML+CSS网络开发混合编程》介绍当前网络开发的主流平台与技术之一的ASP+CSS+XML的知识与应用,全书各知识点均配以实例,按照基础...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO播客