cocos2dx3.2 development RPG "Flighting" (eight) Start fighting

Source: Internet
Author: User

First, preface

We have basically learned how to make a character walk and also do a lot of optimization. Here's the time to start fighting. However, do not worry, we will not introduce heroes and monsters of the two classes (after all, as long as the role can fight, even if the hero hit Heroes)


Second, the text

Let's talk about the whole idea first:

1. Select the character and you can pull out a navigation line (previously done)

2. Determine the end of the navigation line, if the end point is just on a role, then. Hehe just hit him.

3. Move the character to the target side

4. Role play attack animation

5. Played by the person playing the animation

1.2 have basically done before two steps, here only need to make a little change.

void flightlayer::ontouchended (touch* touch,event* Event) {if (M_cur_control) {m_cur_control->ontouchended (Touch, event); Point TP = Director::getinstance ()->converttogl (Touch->getlocationinview ()); if (!m_cur_control-> Getboundingbox (). Containspoint (TP)) {M_cur_control->setdespoint (M_cur_control->getendpoint ());} Role_ptr temp = M_cur_control->getattacktarget ();//original attack target for (auto it = M_rolesarray.begin (); it!=m_rolesarray.end (); ++it) {if ((**it)->getboundingbox (). Containspoint (TP)) {     //attack the original person if (**it = M_cur_control) {    <span Style= "White-space:pre" ></span>//if you want to attack yourself, to attack the person who is already attacking M_cur_control->setattacktarget (temp); break;} <pre name= "code" class= "CPP" ><span style= "White-space:pre" ></span>m_cur_control-> Setattacktarget ((*it));
}else{m_cur_control->setattacktarget (nullptr);}}}


And once again, use M_rolesarray to find out who to attack. and assigned to M_attacktarget. No, you should be able to read it.

Note that the judgment here is performed in Flightlayer rather than in role, after all, Flightlayer is one dimension higher than role, and a role object cannot handle other role objects, which are handed to flightlayer.


3. Move the character to the target side

right now there is another m_attacktargetptr role** two-level pointer in the Role class (Role_ptr), and a m_attacktarget role*, about level two pointers You can go back and look at the front if you are blindfolded.

The member variable of protected:/*role */role* m_attacktarget; role** m_attacktargetptr;//Attack Target

void Role::setattacktarget (role** targetptr) {m_attacktargetptr = Targetptr;if (targetptr) {m_attacktarget = *m_ Attacktargetptr;} Else{m_attacktarget = nullptr;}}

Just Flightlayer has set an attack target for us (m_attacktarget), and then we just need to move the hands and feet in the role's update function.

void Role::update_attacktarget () {if (m_attacktargetptr) {m_attacktarget = *m_attacktargetptr;} Else{m_attacktarget = nullptr;}}
Update_attacktarget guarantee the correctness of our attack target pointers


Below is the Update_pos function with attack target, we have given a simplified version when we talk about simple motion control.

void Role::update_pos () {if (m_attacktarget) {m_despoint.y = M_attacktarget->getpositiony (); m_despoint.x = m_ Attacktarget->getpositionx ();} if (m_attacktarget) {if (M_attacktarget->getpositionx () > Getpositionx ()) {M_armfaceto = false;} Else{m_armfaceto = true;} if (M_armfaceto) {m_arm->setvisible (false); M_arm->setposition (m_arm_offsetx,m_arm_offsety);m_arm-> Setscalex (1.0f); m_arm->setvisible (true);} Else{m_arm->setvisible (false); M_arm->setscalex ( -1.0f); M_arm->setposition (-m_arm_offsetx,m_arm_offsety ); M_arm->setvisible (true);} if (! Rect (Getpositionx ()-m_attackdistance,getpositiony ()-m_attackdistance,2*m_attackdistance,2*m_attackdistance). Containspoint (M_despoint)) {//Is this ifthis->move (); Float distance = Ccpdistance (GetPosition (), m_despoint); float T = Distance/m_speed;float speed_x = (M_despoint.x-getpositionx ())/T;float speed_y = (M_despoint.y-getpositiony ())/t ; Setpositionx (Getpositionx () + speed_x); Setpositiony (Getpositiony () + speed_y);} Else{this->atTack ();//this->setdespoint (GetPosition ());}} Else{if (M_despoint.x > This->getposition (). x && M_armfaceto = true) {M_armfaceto = false;} if (M_despoint.x < This->getposition (). x && M_armfaceto = false) {M_armfaceto = true;} if (M_armfaceto) {m_arm->setvisible (false); M_arm->setposition (m_arm_offsetx,m_arm_offsety);m_arm-> Setscalex (1.0f); m_arm->setvisible (true);} Else{m_arm->setvisible (false); M_arm->setscalex ( -1.0f); M_arm->setposition (-m_arm_offsetx,m_arm_offsety ); M_arm->setvisible (true);} if (! Rect (m_despoint.x-m_speed/2,m_despoint.y-m_speed/2,m_speed,m_speed). Containspoint (GetPosition ())) {this->  Move (); Float distance = Ccpdistance (GetPosition (), m_despoint), float t = distance/m_speed;float speed_x = (M_despoint.x- Getpositionx ())/T;float speed_y = (M_despoint.y-getpositiony ())/T;setpositionx (Getpositionx () + speed_x); setPositio NY (Getpositiony () + speed_y);} Else{this->stand ();}}}

The logic here is not too clear so many duplicate code, please forgive me.

But when we compare the Update_pos that didn't attack the target before, we know that we just added an if to determine if there are any targets now, and if not, follow the simple moving set.

Focus on the attack target, see the code to know, if there is an attack target, the end M_despoint is set to the target coordinates. And the code that turns around is easy to read.

Let's focus on the if code.

if (! Rect (Getpositionx ()-m_attackdistance,getpositiony ()-m_attackdistance,2*m_attackdistance,2*m_attackdistance). Containspoint (M_despoint)) {this->move (); Float distance = Ccpdistance (GetPosition (), m_despoint); float T = distance /M_speed;float speed_x = (M_despoint.x-getpositionx ())/T;float speed_y = (M_despoint.y-getpositiony ())/T;setPosit Ionx (Getpositionx () + speed_x) Setpositiony (getpositiony () + speed_y);} Else{this->attack ();//this->setdespoint (GetPosition ());}

It's a long judgment, but let me explain a couple of variables, it's easy to understand.

M_attackdistance: Attack distance

2*m_attackdistance: Because my attack distance is a square area, the length of the square is equal to the attack distance on both sides.

Well, the basic meaning of the judging condition is that if (the target has not yet entered the attack range) has moved to the target

Else Attack!

4. Role play attack animation

void Role::attack () {if (m_arm && en_stat!=role_attack) {en_stat = role_attack;//during attack speed = Om_speed = 0;m_arm-> Getanimation ()->setspeedscale (m_atkspeed); M_arm->getanimation ()->play ("attack"); This->setdespoint ( GetPosition ());}}
Why is the speed of attack 0? It's simple, you can't let the character play the attack animation while panning.

And at the time of the attack (the attack animation is not finished), the attack target moved out of the scope of the attack, the update function known to call the Move function, resulting in the attack is unsuccessful. I don't like it that way, so my update function adds this judgment.

void Role::update_pos () {if (En_stat = = Role_attack) {///If the attack state position attribute does not need to change return;} Omitted from the back.}
This way, as long as the attack condition has been reached, at least play an attack action.

But after this judgment was added, the role attack was over and stood still. Because role is now at 0 speed. When did that change back to its original speed?

Very simple, the attack finished. The animation of skeletal animation gives us a good set of callback mechanisms that we can bind to do when the animation is played, what to do when the animation finishes, and even what frame we're going to do when the animation is played.

First, add a statement that initializes the binding callback function in Role::init

M_arm->getanimation ()->setmovementeventcallfunc (Cc_callback_3 (role::onbondanimationfinish,this));

Let's see what onbondanimationfinish is like.

void Role::onbondanimationfinish (armature* arm,movementeventtype type,const std::string& name) {if (type = = Complete) {if (name = = "Attack") {Cclog ("attack complete");//recovery Speed m_speed = M_initspeed;this->stand ();}}}
Look at the code and you should know what it is. Type is commonly used to have complete and start respectively playing out and ready to start playing


Well, if there is no accident, now, our character can attack each other. The attacked person plays the injured animation this I'm going to later combine bullets and bullets effect there will be. Let's skip it for a moment.


My csdn Address: http://blog.csdn.net/hezijian22

Email address: [Email protected]

If you have any questions or advice, please feel free to contact me.







cocos2dx3.2 development RPG "Flighting" (eight) Start fighting

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.