[Wood Cocos2d-x 011] Game instance-"Run" production tutorial (Article 3) -- let the protagonist run

Source: Internet
Author: User

Cocos2d-x game instance-"Run" production tutorial (Article 3) -- let the protagonist run

 

What do you mean? Flowers? No, it's your heart ~

Reprinted please note, original address: http://blog.csdn.net/musicvs/article/details/8189386

 

Body:

 

Note: Please download the resources used in this article: http://download.csdn.net/detail/musicvs/4769412

 

 

Finally, we entered the topic of our game-run!

Come on, let's start running the main character ~

 

1. Modify the bad code.

We want to add an animation to the main character to continuously play the running action. Let's open the familiar toll1_scene. cpp file. Sorry, I found that the init function of this file is a bit large.

So I made a difficult decision to move the work of creating a player genie to the init function of the player class:

// Player. hfile # ifndef _ player_h __# DEFINE _ player_h __# include "entity. H "class player: public entity {public: bool initwithtiledmap (cctmxtiledmap * map); static player * createwithtiledmap (cctmxtiledmap * map);}; # endif


 

// Player. CPP file # include "player. H "player * player: createwithtiledmap (cctmxtiledmap * map) {player * mplayer = new player (); If (mplayer & mplayer-> initwithtiledmap (MAP )) {} else {cc_safe_delete (mplayer);} return mplayer;} bool PLAYER: initwithtiledmap (cctmxtiledmap * map) {/* load object Layer */cctmxobjectgroup * objgroup = map-> objectgroupnamed ("objects "); /* load the player coordinate object */ccdictionary * playerpointdic = objgroup-> objectnamed ("playerpoint"); float playerx = playerpointdic-> valueforkey ("X")-> floatvalue (); float playery = playerpointdic-> valueforkey ("Y")-> floatvalue ();/* -------------- load players --------------- */ccsize visiblesize = ccdirector: shareddire () -> getvisiblesize (); ccsprite * playersprite = ccsprite: Create ("Sprite/player1.png"); playersprite-> setposition (CCP (playerx, playery )); /* Add the genie to the map */Map-> addchild (playersprite);/* bind the genie object */setsprite (playersprite); Return true ;}

 

 

The player class has been changed a bit. A parameter is added to the created and initialized functions: map object. In this way, you can add the genie object to the map directly in the player init function.

Now the init function of toll1_scene. cpp is much better:

Bool toll1_scene: Init () {/* load map */cctmxtiledmap * map = cctmxtiledmap: Create ("map/level01.tmx"); this-> addchild (MAP ); /* Create a player */player * mplayer = PLAYER: createwithtiledmap (MAP); Return true ;}

 

 

2. Main Character Animation

Now we are adding an animation to the main character. We will add a function to the player class:

void Player::run(){    CCArray* framesList = CCArray::create();    framesList->addObject(CCSpriteFrame::create("sprite/player1.png", CCRectMake(0, 0, 77, 134)));    framesList->addObject(CCSpriteFrame::create("sprite/player2.png", CCRectMake(0, 0, 66, 129)));    framesList->addObject(CCSpriteFrame::create("sprite/player3.png", CCRectMake(0, 0, 99, 132)));    framesList->addObject(CCSpriteFrame::create("sprite/player4.png", CCRectMake(0, 0, 111, 135)));    framesList->addObject(CCSpriteFrame::create("sprite/player5.png", CCRectMake(0, 0, 94, 132)));    framesList->addObject(CCSpriteFrame::create("sprite/player6.png", CCRectMake(0, 0, 64, 128)));    framesList->addObject(CCSpriteFrame::create("sprite/player7.png", CCRectMake(0, 0, 96, 133)));    framesList->addObject(CCSpriteFrame::create("sprite/player8.png", CCRectMake(0, 0, 103, 138)));        CCAnimation* animation = CCAnimation::createWithSpriteFrames(framesList, 0.2f);    animation->setLoops(-1);    mSprite->runAction(CCAnimate::create(animation));}

 

 

To minimize the amount of code in the tutorial and make the materials as simple as possible, I create ccspriteframe objects in the most direct way. If you do not like them, you can use the ccspriteframecache method to create one. I have learned about how to create an animation by default.

Well, let's just put it down. First, create a ccspriteframe object, and then create a ccanimation object with this set of objects. This object cannot be used to form an animation, and a ccanimate object must also be created, then, the genie class uses the runaction method to execute the animation. Setloops (-1) is used to play the animation cyclically.

Then, open the init function of toll1_scene. cpp, and add the following code:

OK. Compile and run. The Wizard is running! Of course, it's just the same run.

/* Create a player */player * mplayer = PLAYER: createwithtiledmap (MAP);/* run the player */mplayer-> Run ();

 

There will be a lot of new code coming soon.

3. Controller

To let the main character run forward, I want to use a combination to implement this function. The main character only needs to add a member variable (the class to run forward) as a function to write it into a separate class ), to achieve the forward action. This class is the controller.

Considering more than one controller, we can write a few more lines of code for future extension. First, implement the parent class of the Controller (create the controller. h and controller. cpp files in the object folder ):

// Controller. hfile # ifndef _ controller_h __# DEFINE _ controller_h __# include "cocos2d. H "# include" controllerlistener. H "using namespace cocos2d; Class Controller: Public ccnode {public:/* set the listener object */void setcontrollerlistener (controllerlistener * listener); protected: controllerlistener * mcontrollerlistener;}; # endif


 

// Controller. cpp file # include "Controller. H" Void Controller: setcontrollerlistener (controllerlistener * mcontrollerlistener) {This-> mcontrollerlistener = mcontrollerlistener ;}

 

 

A very simple class has only one variable and one method. Let's take a look at what controllerlistener is. Controllerlistener is the object to be controlled. For example, if the main character inherits the controllerlistener interface, it can be controlled by the Controller. Very convenient ~ Programming the interface makes the code slightly less terrible.

Let's look at the controllerlistener code:

// Controllerlistener. hfile # ifndef _ controller_listener_h __# DEFINE _ controller_listener_h __# include "cocos2d. H "using namespace cocos2d; Class controllerlistener {public: Virtual void setsimpleposition (int x, int y) = 0; virtual ccpoint getcurposition () = 0 ;}; # endif

 

It is also very simple. Only the header file defines two virtual functions to set and obtain the coordinates of the controlled object. I don't like C ++ coding very much. It's a little complicated. I am very familiar with Java. Hey, it's much easier to define an interface for Java ~

4. Simple mobile Controller

Let's implement our first controller. Let's take a look at the Code:

// Simplemovecontroller. hfile # ifndef _ simple_move_controll_h __# DEFINE _ simple_move_controll_h __# include "cocos2d. H "# include" controller. H "using namespace cocos2d; Class simplemovecontroll: Public controller {public: create_func (simplemovecontroll); Virtual bool Init (); Virtual void Update (float DT ); /* set the moving speed */void setispeed (INT ispeed); Private: int ispeed;}; # endif

 

// Simplemovecontroll. CPP file # include "simplemovecontroll. H "bool simplemovecontroll: Init () {This-> ispeed = 0;/* The UPDATE function must be called for each frame, so set */This-> scheduleupdate (); Return true;} void simplemovecontroll: Update (float DT) {If (mcontrollerlistener = NULL) {return ;} ccpoint Pos = mcontrollerlistener-> getcurposition (); POS. X + = ispeed; mcontrollerlistener-> setsimpleposition (POS. x, POS. y);} void simplemovecontroll: setispeed (INT ispeed) {This-> ispeed = ispeed ;}

 

Simplermovecontroller inherits the Controller class, which is also very simple. It has a member variable ispeed, which is used to set the moving speed.

Here is a brief introduction to the update (float DT) function. The update function is a function of the ccnode node. What is the purpose? Very powerful. As we all know, the game screen is a frame-by-frame rendering to form a rich and colorful world. The program only needs to execute operations in each frame to draw images.

The update function provides an entry for us to execute what we want to do in every frame of the game. Yes, even if you just put a fart in it, it is acceptable (you won't take it seriously? = ).

However, it is impossible for each ccnode object to execute an update function? (Not everyone needs update, does it ?), Therefore, the update function is not called by default. You need to use the scheduleupdate method to register the called permission.

Then what is the float DT parameter? We all know that CPU is a very busy child (although it is very intelligent), the CPU can not allow all update functions to be executed at the same time, but only one by one, so there is always someone to call first, float
The dt parameter records the number of milliseconds from the last call to the call of an update function. So what's the purpose? Useful, but we don't care about it first ~

Then, simplemovecontroller did a great thing in the update function, that is, it changed the X coordinate of the controller, so that the controller moved a distance forward.

 

5. Bind a controller to the main character.

After so much code, the main character hasn't run yet. It's so tired that I won't write it! Ah, that's strange. Write it now. Write it now ~

There is an unfortunate message that we need to slightly change the entity class (well, don't hate me, the code is always optimized gradually t ^ t ):

// Entity. hfile # ifndef _ entity_h __# DEFINE _ entity_h __# include "cocos2d. H "# include" controller. H "# include" controllerlistener. H "using namespace cocos2d; class entity: Public ccnode, public controllerlistener {public: void setsprite (ccsprite * msprite); void setcontroller (Controller * Controller ); /* method for implementing the simplemovelistener interface */virtual void setsimpleposition (int x, int y); Virtual ccpoint getcurposition (); protected: ccsprite * msprite; Controller * mcontroller;}; # endif

 

We added a parent class to entity, that is, controllerlistener. Everyone knows why, because our role needs to be treated as an object controlled by the Controller. After the controllerlistener is inherited, you must implement its method.

In addition, I also added a method for entity, that is, setcontroller. Of course, because we need to bind a controller.

The three methods are implemented as follows:

 

// Entity. void entity: setcontroller (Controller * Controller) {This-> mcontroller = Controller; controller-> setcontrollerlistener (this);} void entity: setsimpleposition (int x, int y) {If (msprite) {msprite-> setposition (CCP (x, y) ;}} cocos2d: ccpoint entity: getcurposition () {If (msprite) {return msprite-> getposition ();} return ccpoint: ccpoint (0, 0 );}

 

Okay, okay. At last, let's stick to it. Let's open the init function of toll1_scene. cpp. Let's start running La ~ Add the following at the end of the init function:

/* ------------ Create a simple mobile controller for players -------------- */simplemovecontroll * msmovecontroll = simplemovecontroll: Create (); msmovecontroll-> setispeed (1 ); /* the controller must be added to the scene to obtain the update event */This-> addchild (msmovecontroll); mplayer-> setcontroller (msmovecontroll );

 

 

A Brief Description: Create a mobile controller, set the Mobile speed to 1, and then add the Controller to the scene (so that it can obtain the call of the update function ), add the Controller to the main character.

Come on, compile and run the program. Let's see the main character go crazy!

It's so handsome. It's just a rogue who is running towards the good people ~ =

 

In the next article, we will make the map work too much. Isn't it a waste of time ~

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.