Cocos2d-x3.0 C ++ instance running novice entry
In this step, we mainly add the main character to the game scenario and let it run. Here, we actually execute a set of animations to make it look like it is running, the relative position of the screen will not change.
We will define a main character class: runner. This step requires the creation and use of Frame Animation and other knowledge points.
For runner, my design philosophy is as follows:
1. The main character has a set of actions, including running, jumping up, And squatting. There are different frame animations, so here we will refer to the method of Xiao Feng's predecessors to package and name the frame animation, and then execute the action according to the Action name.
2. the protagonist needs to bind a rigid body, and the size of the rigid body varies with the action.
3. When we set a status for the main character, we can know the execution action and the rigid body according to the status.
In this step, we mainly look
Mount the file: runner. h
# Ifndef _ runner _ H __# DEFINE _ runner _ H __# include "cocos2d. H "Enum runnerstate {running, jumpup, jumpdown, crouch}; Class Runner: Public cocos2d: node {public: Virtual bool Init (); create_func (runner ); // initialize the void initactionset (cocos2d: spriteframecache * framecache) of the action set; // execute the Action Void doaction (const char * actionname) based on the action name; // void initbody (); // initialize the physical Rigid Body runnerstate getstate () {return m_state ;}; // obtain the current state. cocos2d: Size getrunjumpsize () {return run_jumpsize;} is used later ;}; // obtain sizecocos2d: Size getcrouchsize () {return crouchsize ;}; void run (); Private: // a major genie is required to execute the cocos2d Action :: sprite * m_runner; // different actions require different rigid body sizes cocos2d: Size run_jumpsize; // run the same size as the hop cocos2d: Size crouchsize; // The down state m_state;};/**/# endif
The size of the rigid body here is only two, because the size of the genie is similar when running and jumping, so the size of the Rigid Body binding in these two states can be the same, the size is different when you squat.
Runner. cpp
# Include "runner. H "using_ns_cc; bool Runner: Init () {// load the image to the cache pool auto framecache = spriteframecache: getinstance (); framecache-> addspriteframeswithfile (" parkour. plist "," parkour.png "); m_runner = sprite: Runtime (" runner0.png "); run_jumpsize = m_runner-> getcontentsize (); crouchsize = sprite: Runtime (" runnercrouch0.png ") -> getcontentsize (); this-> addchild (m_runner); initactionset (framecache); // initialization action set m_state = running; initbody (); Return true;} void Runner :: initactionset (spriteframecache * framecache) {spriteframe * frame = NULL; // use vector instead of arrayvector <spriteframe *> framevector in 3.0;/* 1. ---------------- load the running animation --------------- */For (INT I = 0; I <= 7; I ++) {// load the genie from the cache pool to vectorframe = framecache-> spriteframebyname (string: createwithformat ("runner+d.png", I)-> getcstring (); framevector. pushback (FRAME);} // use the spriteframe list in the vector to create an animation and set some parameters: auto run_animation = Animation: createwithspriteframes (framevector, 0.1f,-1 ); // name the running animation as running animationcache: getinstance ()-> addanimation (run_animation, "running");} void Runner: doaction (const char * actionname) {auto animation = animationcache: getinstance ()-> animationbyname (actionname); Auto action = Animate: Create (animation); m_runner-> runaction (action);} void Runner:: initbody () {// set bodysize of different rigid bodies according to different States; if (m_state = Crouch) {bodysize = crouchsize;} else {bodysize = run_jumpsize ;} // create the runner's rigid body auto runerbody = physicsbody: createbox (bodysize, physicsbody_material_default); // bind the rigid body this-> setphysicsbody (runerbody);} void Runner: Run () {m_state = running; initbody (); doaction ("running ");}
InInitIn the function, we have done some things:
1. First load the image to the cache pool, initialize the Master Genie, and two sizes, as well as the current status
The image here is actually a collection of many small images. Different images have different textures, so the textures in the same image are the same, so the images with the same texture, we can reduce the number of rendering batches. The rendering in 3.0 seems to be automatically processed. I read an article saying that the spritebachnode is not recommended and it is also abstract, I do not explain it here. I suggest you if you have a good tutorial. Thank you.
2. We initialized the action set. In this step, we only initialize the animation of the running frame.
InInitactionsetIn the function, I have detailed comments.
DoactionIn the function, we can execute an action based on the input parameter action name, that is, the name of the action in initactionset.
InitbodyIn the function, depending on the status, we will bind a rigid body of different sizes to the main character. You may have questions about repeated setphysicsbody. There is a rigid body, And the status is changed, can I set another rigid body? The answer is yes. We can check the source code.
Void node: setphysicsbody (physicsbody * Body) {/* omitted */If (_ physicsbody! = Nullptr) {physicsworld * World = _ physicsbody-> getworld (); _ physicsbody-> removefromworld (); _ physicsbody-> _ node = nullptr; _ physicsbody-> release (); If (World! = Nullptr & Body! = Nullptr) {world-> addbody (body) ;}}_ physicsbody = body; If (body! = Nullptr) {node * parent = getparent (); point Pos = parent! = Nullptr? Parent-> converttoworldspace (getposition (): getposition (); _ physicsbody-> setposition (POS); _ physicsbody-> setrotation (getrotation ());}}
Here we can see that it will judge whether _ physicsbody (that is, the node's rigid body) is empty. If an existing rigid body exists, it will be deleted first and then re-bound.
Now, the main character class and preliminary settings are complete. We add a member variable runner * m_runner to playscene. h;
Then initialize m_runner In the init function of playscene. cpp:
m_runner = Runner::create();m_runner->setPosition(runner_posX,ground_hight+m_runner->getRunJumpSize().height/2);m_runner->Run();this->addChild(m_runner);
The runner_posx here is a macro defined in ground_hight, that is, the X coordinate position of the main character. Here I define 80
OK run the test
If you put all those resources under the resouce file, you can also hear background music.
Here I also have a problem, that is, some people can insert dynamic images to better demonstrate the running results. QQ does not seem to be able to capture dynamic images on this screen.
Next we will add the background of playscene and the infinite scrolling of the map to make the protagonist look more like a running event. At the same time, we will also prepare for the jump and crouch squatting actions of the protagonist.
Personal ignorance. Thank you for your correction and discussion.