Cocos2d-x 3.0 game instance learning notes "parkour" sixth step -- physical collision detection (1), cocos2d-x "parkour"
(Here is the reference: Xiaofeng residual month predecessors blog, he is the teiran network of the parkour tutorial, with the cocos2d-x 2.X version of rewriting, I am learning cocos2d-X3.0 so I will use cocos2d-X 3.0 rewrite, take notes
So this step, we are not in a rush to the protagonist and gold coin rock collision detection, I here to cocos2d-x 3.0 physical collision detection separately extracted, before reading the cocos official website, there is a tutorial: using the new physical engine to perform collision detection is a collision detection between a car and a cat. When a car hits a cat, the cat disappears. I tried it myself before. But the code in that tutorial seems to be incomplete and cannot be run... So I used the example tutorial of dumb to complete this simple collision detection.
The detection is as follows: there is a ball 1 affected by gravity, it will fall, and then there is a static rigid body ball 2 below, without the impact of gravity is fixed at the bottom of the ball 1. Then ball 1 hits ball 2 and ball 2 disappears. In addition, during the collision, ball 1 won't be blocked by ball 2. In fact, this is to detect the collision between the protagonist and the gold coin. This is just for the sake of simplicity. Here we will separate the collision detection.
Complete the following steps:
Create a new project: Modify the HelloWorld. h &. cpp file as follows:
# Ifndef _ HELLOWORLD_SCENE_H __# define _ HELLOWORLD_SCENE_H __# include "cocos2d. h "class HelloWorld: public cocos2d: Layer {public: static cocos2d: Scene * createScene (); virtual bool init (); CREATE_FUNC (HelloWorld); cocos2d :: physicsWorld * m_world; void setPhyWorld (cocos2d: PhysicsWorld * world) {m_world = world ;}; // The following content is used for physical collision detection. cocos2d: EventDispatcher * dispatcher; void onEnter (); void onExit (); bool onContactBegin (cocos2d: PhysicsContact & contact) ;};/**/# endif // _ HELLOWORLD_SCENE_H __-------------------. cpp ----------------------- # include "HelloWorldScene. h "USING_NS_CC; Scene * HelloWorld: createScene () {// create a physical sceneauto scene = Scene: createWithPhysics (); // enable scene-> getPhysicsWorld () -> setDebugDrawMask (PhysicsWorld: DEBUGDRAW_ALL); auto layer = HelloWorld: create (); layer-> setPhyWorld (scene-> getPhysicsWorld ()); scene-> addChild (layer); return scene;} // on "init" you need to initialize your instancebool HelloWorld: init () {auto ball_1 = Sprite :: create ("11.png"); // create a rigid body auto body1 = PhysicsBody: createBox (ball_1-> getContentSize ()); // The physical collision body1-> setCategoryBitmask (1); body1-> setCollisionBitmask (1); body1-> setContactTestBitmask (1 ); // bind ball_1-> setPhysicsBody (body1); ball_1-> setPosition (205,300); // set the tag to determine ball_1-> setTag (1) for the collision ); this-> addChild (ball_1); // same as auto ball_2 = Sprite: create ("22.png"); auto body2 = PhysicsBody: createEdgeBox (ball_2-> getContentSize ()); body2-> setCategoryBitmask (1); body2-> histogram (1); body2-> setContactTestBitmask (1); ball_2-> setPhysicsBody (body2); ball_2-> setPosition (205,150 ); ball_2-> setTag (2); this-> addChild (ball_2); return true;} void HelloWorld: onEnter () {Layer: onEnter (); auto contactListenner = EventListenerPhysicsContact:: create (); // ---- 1 ----- it seems that both methods can be used // contactListenner-> onContactBegin = CC_CALLBACK_1 (HelloWorld: onContactBegin, this ); // ---- 2 ----- contactListenner-> onContactPreSolve = CC_CALLBACK_1 (HelloWorld: onContactBegin, this); // event dispatching mechanism dispatcher = Director: getInstance ()-> getEventDispatcher (); dispatcher-> cancel (contactListenner, this);} void HelloWorld: onExit () {Layer: onExit (); // cancel the event dispatch mechanism dispatcher-> removeAllEventListeners ();} bool HelloWorld: onContactBegin (PhysicsContact & contact) {auto B _1 = (Sprite *) contact. getShapeA ()-> getBody ()-> getNode (); auto B _2 = (Sprite *) contact. getShapeB ()-> getBody ()-> getNode (); CCLOG ("ssssss"); if (B _1-> getTag () = 2) {B _1-> setVisible (false);} if (B _2-> getTag () = 2) {B _2-> setVisible (false );} // if false is returned, the physical world ignores the speed change caused by this collision and returns false for bounce ;}
In the init function, we got two balls, respectively bound to the rigid body according to the above description, and in order to make the new physical fitness detected by collision, we should add three statements:
setCategoryBitmask(1);
setCollisionBitmask(1);
setContactTestBitmask(1);
You can view the source code comments, which are not explained here.
About Collision Detection:
Here the onEnter and onExit functions are used. The process is as follows:
OnEnter:
Get a collision event to listen to contactListenner. Then the collision listener should set its callback function-call it when a collision occurs.
In this case, all event management in section 3.0 is handed over to the event dispatch mechanism. We also need a dispatcher to hand over the event listener contactListenner to it for management;
The collision callback function has a parameter PhysicsContact and contact to obtain the two collision nodes .... Handle
Then the onExit function should cancel the event dispatch listener... (In fact, I cannot tell you where to call this function.) Well, you can do it here. Run the test as follows:
The falling ball passes through the static ball. For this collision, we just make the following ball invisible. This is related to the previous step, because in order to avoid repeated create coins, whether it is the gold coins that the main character has eaten or the gold coins that cannot be seen outside the screen, we set them to invisible and then re-appear.
OK, here we will use the following game to make the gold coins and rocks collide with the protagonist. The next step is the last step ....
Oh, I almost forgot. This part of code and the resources of the two balls have been uploaded, and 0 points are downloaded:Collision Detection example
We create a new project, copy the Code directly, and add the two balls to the Resource file to run and see the results.
Personal ignorance. Please correct and discuss it!
How to Implement collision detection (cocos2d-x)
The collision detection code is cumbersome and cannot be listed in detail by me
The idea is:
Traverse all the sprite in update, and then judge whether each sprite and other sprite (also need to traverse again, clear yourself) are collided. In this way, the number of queries is the square of the number of sprite instances, and the efficiency is very low. So you need to optimize it. For example, you need to change the logic of "other sprite (you need to traverse it again)" to "nearby sprite ".
The collision detection of two sprite instances is very simple. If it is just a rectangular judgment, many tutorials will have
If (CCRect: CCRectIntersectsRect (a-> boundingBox (), B-> boundingBox ()))
You can Baidu search cocos2d-x collision detection view detailed code, if you have any questions and then raise detailed questions.
Cocos2d-x Collision Detection
1. Why should I use an anchor as the anchor?
2. Are you separate the two codes? The following section should be in update
3. I don't know what action you are running. Are you sure you can hit it? Increase the width and height to see if the output is yes.
4. This yes may be output under the tool or in a black box in the background. Have you read it?
5. How good is box2d for collision detection ~ Simple call and precise determination