Cocos2d-x Study Notes 05 -- MySpaceWar1.0

Source: Internet
Author: User

We recommend that you read two excellent articles about airplane games:

 

The idea of alternative inheritance in the combination design in the above two articles is very exciting. Although it may be difficult to implement it at the beginning, it will become increasingly simple in the later stage. what is needed and what to assemble. Although the sparrow is small, the five dirty files are complete, do not underestimate these designs. This is a good test of object-oriented capabilities. A good design won't let you walk and you can't move any more. It took just a week to write a MySpaceWar1.0, which is also a flying game. This is the first android game to be written. You can play your own game after class. It's awesome, haha.

My class diagram is basically like this:

 

There is no interface class in C ++. You can use an abstract class to simulate the class. Use PowerDesigner to draw a class chart.

 

My initial design of MySpaceWar1.0 was based on the idea of the previous two articles. I tried to modify it multiple times, but I had to change it back because I didn't think much about it, finally, we found that it could not be changed. It can only overlap with the author step by step. However, I still think their design on the bullet manager is too complicated. It is very complicated to add the bullet manager to all monsters by setting listening methods for each other. It is not only necessary to consider data encapsulation, but also the rationality of the interface. It is difficult to install the bullet manager for the monster without disrupting the parameters of the design method, so that the monster can have the ability to launch bullets. Therefore, we must give up some of the original design to break the deadlock, that is, restructuring is required. The reason for local refactoring is that I want to compose (combine) a bullet manager for every monster so that the monster can also launch a bullet function. The original listening mode is too complicated and can only be used to figure out the entire logic for a moment. However, after a while, I forgot the design logic. Therefore, there must be a simple and easy-to-understand design, and useless abstract classes should be deleted.

 

So I tried to design a collision manager class (CollisionManager). Now there are three management classes, the monster manager class and the bullet manager class. Of course, we should make> class colincluable {public: virtual bool isCollidedWith (colincluable * target) = 0; // This is to determine whether it is a collision with other collision objects virtual CCPoint GetPosition () = 0; // It seems inappropriate to put this function here. Any entity should have these two functions, but the implementation of the isCollidedWith function will tell you that you have to do so, otherwise, use dynamic_cast to forcibly convert to a subclass pointer and call GetPosition () and CollisionDetected (). Select either of the two. Virtual const CCSize GetContainSize () = 0; virtual void CollisionDetected () = 0; // December 24, 2013 12:37:54 add };

 

 

 

You only need to upload the file to player * and> void CollisionManager: update (float dt) // to perform Collision Detection in three cases. Will it cause the bullet to pass through the monster before it is detected, especially when the phone is compared to the card {/* 1. checks whether player and monster have collided */CCObject * obj = NULL; CCObject * obj2 = NULL; CCARRAY_FOREACH (mMonsterManager-> mMonsterArray, obj) {Monster * monster = (Monster *) obj; if (monster & monster-> getIsAlive () & monster-> isCollidedWith (mPlayer) {monster-> CollisionDetected (); mPlayer-> CollisionDetected ();}} CCARRAY_FOREACH (mMonsterManager-> mMonsterArray, obj) {Monster * monster = (Monster *) obj; CCARRAY_FOREACH (monster-> mBulletManager-> mBulletArray, obj2) {Bullet * bullet = (Bullet *) obj2; if (bullet & bullet-> getIsAlive () & mPlayer-> isCollidedWith (bullet )) {mPlayer-> CollisionDetected (); bullet-> CollisionDetected () ;}}/* 3. monster and player Bullet collision */CCARRAY_FOREACH (mPlayer-> mBulletManager-> mBulletArray, obj) {bullet * Bullet = (Bullet *) obj; if (bullet & bullet-> getIsAlive () // use if to slightly filter and reduce the number of calls {CCARRAY_FOREACH (mMonsterManager-> mMonsterArray, obj2) {Monster * monster = (Monster *) obj2; if (monster-> getIsAlive () & monster-> isCollidedWith (bullet) {monster-> CollisionDetected (); mPlayer-> mScore ++; // score + 1 mPlayer-> refreshUiValue (); // refresh the score bullet-> CollisionDetected ();}}}}

 

 

 

Because there are many types of bullet genie images, such as the player and monster bullets, how can a bullet class be able to take on the display of the player bullets, it also shows the genie of monster bullets. It may be easy to think of using two subclasses to inherit the bullet. Of course this is not the case. If there are 10 types of bullets, wouldn't it be necessary for 10 to inherit from the bullet subclass. The method I want to solve is to pass in the enumeration type in the bullet class. when constructing the bullet class, I will first determine who the bullet is and which image will be used in response. In short, enumeration can be used to achieve a class suitable for multiple situations. As follows:

 
class Bullet : public Entity { public: enum BULLET_TYPE { PLAYER_BULLET = 1, MONSTER_BULLET }; bool init(CCSpriteBatchNode* batchNode, BULLET_TYPE type); static Bullet* createWithBatchNode(CCSpriteBatchNode* batchNode, BULLET_TYPE type); virtual void CollisionDetected(); };

 

Bool Bullet: init (CCSpriteBatchNode * batchNode, BULLET_TYPE type) {bool bRet = false; do {char fileName [60] = {0}; sprintf (fileName, bullet_11602d.png, type ); // No write dead, passing an enumeration breaks the deadlock and avoids the poor maintainability of if else. // CCSprite * bulletSprite = CCSprite: createWithSpriteFrameName(bullet_01.png ); CCSprite * bulletSprite = CCSprite: createWithSpriteFrameName (fileName); CC_BREAK_IF (! BulletSprite); batchNode-> addChild (bulletSprite); this-> setVisual (bulletSprite);/* add a simple mobile controller to the bullet, make it fly */SimpleMoveController * moveController = SimpleMoveController: create (); if (type = PLAYER_BULLET) {moveController-> setYSpeed (400 );} else if (type = MONSTER_BULLET) {moveController-> setYSpeed (-200) ;}else {;} this-> setController (moveController); bRet = true ;} while (0); return bRet ;}

 

If you have more knowledge and experience in design, please try again later. The following is the game section:

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.