Game Development-skill Design of combat systems

Source: Internet
Author: User

Currently, I am working on two projects: the Combat System and the peripheral system except the combat system. What I have been developing is the peripheral system, at least no combat system was triggered before the graduation reply in February. A long time after the reply was returned, it was also a peripheral system bug fix. However, due to various reasons, the project could not catch up with the so-called progress, last Friday, the supervisor asked me and another colleague who was mainly responsible for peripheral system development who was busier. I said that I had nothing to do. The supervisor said that the combat system's active skills would allow me to do it. On Monday, the Meeting owner threw down a paper Task Arrangement, which stated that xx colleagues completed active skill development and related system bug fixing this week, and said xxx was not completed, XX characters are omitted here.

Let me talk about my current situation: I did not graduate from a computer-related major. I learned C ++ for two months last year and cocos2dx for one month. Then I joined the current company in March, therefore, the skill level is... Now I have worked on two projects with the project to be cut down. With the enthusiasm and powerful Internet resources, the tasks assigned by the project team have been completed on time so far. So it can be said that it is a slightly qualified game development practitioner.

Let's go back to the question. First, I want to understand the skills in the game. In a turn-based game, the process of active skills is roughly: Release the skills, get the skill impact value (the buff called by the project team every day), and determine the skill target, skill detection + impact value added to skill objects. The active skill design follows this idea. Therefore, this article can be roughly divided into three parts: Skill release and buff generation (not added to objects ), skill detection section. (The skill of this project is relatively simple. The skill release does not consider the magic value, the buff generation does not consider other influencing factors, and the skill test does not involve the hit rate)


Battle:

A card game is equivalent to a card game.


I. Release skills

In this project, the release process is roughly as follows: in the combat scenario (battlescene), the currently controlled players reach the skill CD time, and the players take the initiative to execute an operation to release the skills of the current combat players. The released skill may be a combination skill or a single skill.

Here we need to control: Skill information (Impact Value, skill Releaser, skill owner, skill impact round), skill Management (triggering detection, generating skill impact, and clearing impact ). Therefore, I first thought of generating a skill manager in this scenario to handle the skill control.

I wrote a skill management class: skill_command (known as the skill Controller), which has the following members:

Class skill_command {public:/*** the return value of this member function is used to determine whether the skill is in immediate effect **/bool Init (); Private: skill_info _ INFO; // skill information role * _ User; // skill User Role * _ OBJ; // skill owner}

Because the skill is released in battlescene and requires a series of tests in this scenario, my idea is to use skill management as a member in this scenario, execute the skill management class detection function in this scenario. Considering that the skill may be a combination skill, in the scenario class, I manage objects with a vector storage skill.

class BattleScene{private:vector<skill_command*> vecSkillCmd;}

After such a design, each operator releases a skill and first breaks down the skill combination to generate a skill information. Then, a new pointer is stored in vecskillcmd:

VEC = analyze (skill) for (// do a loop) {auto skill_cmd = new skill_command (); skill_cmd-> Init (); // you also need to set vecskillcmd for skill information and target objects. push_back (skill_cmd )}

To do this, consider releasing a skill, breaking down the combined skill into separate control, and simplifying it. Also, I have obtained the information required to generate a skill (which records the skill information, the skill owner, and the user ), therefore, in the skill role and detection phase, I do not need to provide users with additional information such as skill objects. I only need to provide detection conditions in the scenario, once the condition is met, the skill impact can be achieved directly within skill_command. I thought that I was also involved in the maintenance of the combat system in the previous project. One thing I did was to optimize the performance of my skills. The biggest trouble I encountered at the beginning was that it was difficult to determine the target of my skills, so at that time, it was hard to find a skill target. So this time, my idea is that whatever skill, the first thing I need to do is to split it up and determine its users and users separately, in this way, I can find the target each time I perform a skill test and produce the skill effect.

As mentioned in the design case, skills can be divided into instant effects and delayed effects. It refers to some skills that will produce results (such as bullets and laser shots) upon use, and some that need to meet certain conditions (such as colliding with enemy players) to produce results. Therefore, in the process of breaking down skill information and generating skill controllers, I will separate these two skills. The specific method is to add another member in the battlescene scenario to specifically store the instant effect skills:

class BattleScene{private:vector<skill_command*> vecSkillCmd;    vectpr<skill_command*> vecInstanceSkillCmd;}

After this process, the skill controller is stored separately to different management containers based on the skill effective type in the Generation skill controller phase. In the detection phase, we only need to cyclically detect different container content in different condition stages to achieve our design goal. For skills that take effect immediately, I only need to check the members of vecinstanceskillcmd after the skills are released. Of course, it would be okay to directly put vecskillcmd here for detection? This is how I consider the skill_command storage of a skill manager.

As mentioned above, skill controllers are stored in vecskillcmd and vecinstanceskillcmd Based on the Role type of the skill. Here I have considered the time of its role, and I have also considered its functional conditions. Some skills play an immediate and unconditional role, while others have immediate and conditional effects. Even if it works unconditionally, this skill immediately and unconditionally, so I don't need to manage it after it is released, so I didn't store it in Vec. The instant conditional function is stored in VEC for later detection. Here we use an idiom function releaseskill to indicate the skill release action:

Void battlescene: releaseskill () {VEC = analyze (skill); For (// create a loop) {auto skill_cmd = new skill_command (); // generate a skill controller skill_cmd-> Init (); // here you also need to set the skill information and the target object if (// if it does not take effect immediately) {vecskillcmd. push_back (skill_cmd);} else // takes effect immediately {If (// unconditionally triggered) // execution trigger effect {skill_cmd-> triggerskill (); cc_safe_delete (_ cmd ); // Delete the pointer} else {vecinstanceskillcmd. push_back (skill_cmd );}}}}

In this step, the release of skills is almost the same. The release of my skills in the project is also such an operation.


Ii. Buff generation

As a matter of fact, when I arranged my skills last Friday, I first thought about how to generate a buff. Colleagues also mentioned the need to write a general interface that can be used to process items (such as blood adding and acceleration), saving time and effort. So the first task is to do buff, and of course there is no way to do it, because at that time I did not plan to follow up on how to do my skills, until this Wednesday, the solution was taken, XX characters are omitted here.

Because we already have a role class, I think that buff is not added to the role, so my design scheme is like writing a skill controller before, add a member to the role class as the buff controller. It is also based on simplicity. A buff generates a controller. The buff controller also contains buff information, owner and user information:

Class buff_command {PRIVATE: buff_info_info; // buff information buff_user_user; // buff user buff_obj_obj; // buff owner}

Each time a buff is generated, a controller is generated, similar to the design concept of the skill Controller: the controllers are managed by containers in the role class, each time you get a buff by using a skill or item, a buff is generated and stored in the container for subsequent skill detection and buff effect generation:
class role{public:    void addBuff();private:    vector<buff_command*> vecBuffCmd;}

Role is a buff management member and a buff generation function. The buff generation function is called inside the initialization function of the skill controller. Its content is roughly as follows:

Void role: addbuff () {// check repeated buffcheck (); Auto buff_cmd = new buff_command (); buff_cmd-> Init (); vecbuffcmd. push_back (buff_cmd );}


Similar to the generation of the skill controller, one step here is to perform a buff repeatability test: The triggered buff deletes the buff effect, and the triggered buff deletes the Buff from the container directly.

In combination with the content in the first part, let's make a general process introduction:

1. Trigger skill usage in scenebattle:

battle_role->releaseSkill();

2. parse the skill combination to generate the skill Controller after the skill is triggered, and initialize the skill controller information:
auto skill_cmd = new skill_commant();skill_cmd->init();
3. Generate a skill Buff:
Bool skill_command: Init () {initskillinfo (); // generate the buff information skill_obj-> addbuff ();}
After the preceding three steps, a simple buff is generated.



Iii. Skill Detection

I feel a little complicated about this part, which is also a bit difficult for me. On Saturday, I tested the entire release-add-detection logic. There are no problems with the existing skills, that is, I don't know what will happen afterwards.

The skill detection design of the project is as follows: First, check the trigger conditions and then check the effective conditions. First, a skill must be triggered due to a certain condition. If your team members touch the other team or the team members touch a scene element, the skill meets the trigger condition; after the trigger condition is met, the skill takes effect. For example, the skill is released only when the Releaser encounters an opponent, or when it hits his/her teammates. Therefore, two member functions are written in skill_command:

Class skill_command {public: // used to detect the trigger condition void checktriggercondition (); // If the trigger condition is reached, the triggerskill (); Private: bool _ Bok ;}

Skill detection mainly relies on these two member functions. Of course, these two functions actually contain parameters. The function is called in the battlescene scenario:

Battlescene: // an action for (//) {auto skill_cmd = vecskillcmd [I]; // condition detection is performed each time, after the conditions are met, the bool type members in the controller are trueskill_cmd-> checktriggercondition (); // when the internal bool member is true, execute the internal action skill_cmd-> triggerskill ();}

In the previous design, the skill controller has the skill role member _ obj. In fact, the skill trigger is to call the member function of _ OBJ for implementation:

bool buff_command::triggerSkill(){if(_bOK){_obj->triggerBuff();}}

The actual action in the trigger buff function I designed is to manage the buff containers in the role class:
Void role: triggerbuff (// a parameter that can be found for this buff) {for (//) {If (// This buff) {auto buff_cmd = vecbuffcmd [I]; buff_cmd-> trigger ();}}}
This step triggers a buff. Return to the buff_command controller we mentioned earlier:
Class buff_command {public: void trigger (); Private: buff_info_info; // buff information buff_user_user; // buff user buff_obj_obj; // buff user}
The trigger of the member function is actually responsible for executing the buff settlement for the buff operator _ obj. Adjust the value of the role based on the buff type (blood and speed. In the actual design process, considering the independence of the buff information, the buff_info structure is used as the member variable of the role, the value of this Member is actually adjusted each time the buff is settled, and then the value is added to the corresponding information of the role. In this relatively independent design, on the one hand, it is suitable for intuitively displaying the impact of each skill use (of course for our developers); on the other hand, it is because it is to change others' code, in this way, the independent design of a buff information will not affect the functions implemented by the existing Code (the code is difficult to change, mainly because it is easy to deviate from the idea of the original designer ).

In this way, the buff detection + effect generation function has been implemented, and the final task is to clean up the buff.

A major feature of a turn-based game is that the one-in-one round goes on, and the buff effect also has an impact on the round. The release of skills will only be effective in the current round: that is, a skill is released, and only the effectiveness detection is performed in the current round -- vecskillcmd/vecinstancecmd executes the Member's internal detection function, however, all members should be deleted after the end of the current round (because the release action has ended, and of course the memory needs to be released ).

Skill controller control is very simple. You only need to clear the members of vecskillcmd and release the memory at the end of each round. vecinstancecmd is a real-time management skill, therefore, you need to clear and release the skills (that is, after the special effects of the skills are played.

The buff controller is a little complicated because it involves whether the buff is triggered:

1. For the triggered buff, perform a round check: When the round limit is reached, start to clear the buff-adjust the buff_info value of the role Member of the role (that is, to clear the Impact Value of the buff, if 10 points of blood is deducted, 10 points of blood will be added during cleaning ). Here, you may need to explain the effective mechanism of the Buff: If a buff with a blood deduction of 10 points is triggered, the _ hp value in the buff_info Member of the role will be adjusted to-10, indicating blood deduction. This buff value-10 is added each time the role value is settled, which is equivalent to a blood deduction function. Therefore, 10 is added when the buff is cleared, the value of _ Hp in buff_info is 0.

2. For a buff that is not triggered, clear and delete the buff directly. This is similar to the clearing Management Idea of the skill controller.

This cleanup operation is performed at the end of each round. The cleanup function is designed as a role member function of the Role type, and each role in the scenario is executed with an internally designed cleanup check function.

This is what we have done this week. Writing this blog is a summary of the work of this week, and I don't know where the design is unreasonable. It's unreasonable. There's no way. All I will do is... In fact, I still want to combine the knowledge related to the design model to sort out this week's work, but I haven't read the relevant books yet. In short, books on design patterns must be viewed. Recently, I have been reading STL source code analysis and programming in Lua 3, after reading one of them, you need to read the relevant information about the design model.


Summary:

After writing, I actually thought about some improvements: I wrote different classes for the final impact types of buff-blood, speed, attack, and magic, and then managed buff_command in a unified manner, does this meet the scalability requirements? If additional buff effects are required in the future, you only need to add additional classes to manage the buff_command class?

No matter what the design idea is, it is always a kind of exercise for yourself. After all, I have never done this before and will always do this work in the future ~ Some so-called terms, such as code coupling, code reuse, and scalability, require further understanding and more attention at work.




Game Development-skill Design of combat systems

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.