首先,跟踪怪物和子弹是必需的。 在游戏中,我们为这两种精灵加以不同的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)spriteMoveFinishedid)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)updateccTime)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 scheduleselector(update]; 编译并运行项目,尽情地发射子弹吧,这时:啊哈,怪物都一个接着一个地被干掉了。 |