A hero can now launch a bullet, but it's just a decoration. How can we kill a monster? This effect will be achieved based on collision detection. 1. cache monsters and bullets first, tracking monsters and bullets is required. In the game, we use different tags for the two genie to differentiate them. When tag = 1, it indicates this is a monster, and when tag = 2, it indicates this is a bullet. Because m_nTag is a member variable in CCNode and the setTag and getTag methods are available, CCSprite inherits these methods and can be used. In HelloWorldScene. h, add the following two member variables to HelloWorld. These two member variables are used to cache existing monsters and bullets: protected: cocos2d: Array * _ targets; cocos2d :: array * _ projectiles; In HelloWorldScene. h, declare the constructor and destructor: HelloWorld ();~ HelloWorld (); then, you need to initialize the two Array variables in init :... this-> _ targets = Array: create (); this-> _ projectiles = Array: create ();... then, initialize the two variables in the constructor and release them in the destructor. HelloWorld: HelloWorld () {_ targets = NULL; _ projectiles = NULL;} HelloWorld ::~ HelloWorld () {CC_SAFE_RELEASE_NULL (_ targets); CC_SAFE_RELEASE_NULL (_ projectiles);} Now you can modify addTarget (), add the new target to the target array, and set its tag to 1, and remove the corresponding logic in lambda :... finiteTimeAction * actionMoveDone = CallFuncN: create ([this] (Node * sender)-> void {// std: cout <"remove target" <std: endl; <span style = "color: # ff6600;"> this-> removeChild (sender); _ targets-> removeObject (sender); </span> }); target-> runAction (Sequence :: Create (actionMove, actionMoveDone, NULL); <span style = "color: # ff6600;"> target-> setTag (1); _ targets-> addObject (target ); </span> <br>... modify onTouchesEnded (), add the new bullet to the bullet array, and set its tag to 2 :... projectile-> runAction (Sequence: create (MoveTo: create (realDuration, realDest), [this] (Node * sender) {<span style = "color: # ff6600; "> this-> removeChild (sender); _ projectiles-> removeObject (sender); </span >}, NULL); <span Style = "color: # ff6600;"> projectile-> setTag (2); _ projectiles-> addObject (projectile); </span> 2, the update () function below the Collision Detection in each frame is used to detect the collision of each frame, and delete the bullets and monsters in the collision from the game. Please go to HelloWorldScene. h declares in HelloWorldScene. definition in cpp: void update (float delta );... void HelloWorld: update (float delta) {cocos2d: Array * projectilesToDelete = Array: create (); Object * obj1 = NULL; Object * obj2 = NULL; CCARRAY_FOREACH (_ projectiles, obj1) {Sprite * projectile = (Sprite *) obj1; Array * targetsToDelete = Array: create (); CCARRAY_FOREACH (_ targets, obj2) {Sprite * target = (Sprite *) obj2; if (pro Jectile-> getBoundingBox (). intersectsRect (target-> getBoundingBox () {targetsToDelete-> addObject (target) ;}} CCARRAY_FOREACH (targetsToDelete, obj2) {Sprite * target = (Sprite *) obj2; _ targets-> removeObject (target); this-> removeChild (target);} if (targetsToDelete-> count ()> 0) {projectilesToDelete-> addObject (projectile ); this-> removeChild (projectile);} targetsToDelete-> release ();} CCARRAY_FOREA CH (projectilesToDelete, obj2) {Sprite * projectile = (Sprite *) obj2; this-> removeChild (projectile); _ projectiles-> removeObject (projectile );} projectilesToDelete-> release ();} the code is loose, so there are two for loops. In turn, getBoundingBox and intersectsRect are used to detect collision. Last thing, before init return, we need to add update () to schedule so that each frame can be called. This-> scheduleUpdate (); 3. The Code reports an error. Where to compile and run the error? The program reports an error: _ projectiles variable is NULL. In cocos2d-x 3.0, variables created using Array: create are automatically added to the Auto Release pool, see its source code: Array: create: Array * Array: create () {Array * pArray = new Array (); if (pArray & pArray-> init () {pArray-> autorelease ();} else {CC_SAFE_DELETE (pArray );} return pArray;} // --------- Object * Object: autorelease (void) {PoolManager: sharedPoolManager ()-> addObject (this); return this;} The answer is here, the _ projectiles and _ targets variables are automatically released by the manager before they are used. The solution is to explicitly call the retain method after initialization, in init :... this-> _ targets = Array: create (); _ targets-> retain (); this-> _ projectiles = Array: create (); _ projectiles-> retain ();...