The Hero Class Technical ModelAs general development, this is not too hard of a task. The problem here is that a lot of times, the end-product is not reusable, it's not flexible and it's not generic. Here is a typical problem, when someone is making a design of this nature - more inexperienced developers tend to develop three separate classes - a Warrior class, a Mage class and an Archer class. And that's it. Just these three classes. Don't get me wrong, this will work. However, it's problem prone. What's not good about this concept? Here is a list of some of the biggest problems:
- You have to re-write basic stuff that all of these classes have in common.
- If you have to change a basic concept of the characters, you have to make the change in all of these classes.
- If a consistent bug pops up, you are going to have to implement fixes in all of the classes.
- Many other things that may trip you up.
Developing the Technical DesignWe will start off from the ground. Here is how our hierarchy is going to look.
Character InterfaceFirst off, we will create the character interface. For this article, let's simply name it ICharacter. Now let's start thinking. What do all of these characters have in common? Well, they can all attack, move, trigger actions and die. Of course, each of them will have its own interpretation of these traits later on. So, the interface will have these methods:
Character ClassNow that we have the Interface up and ready, we should create a basic class that is going to implement it. For this article, we will call the class CharacterBase. So how will it work? When we implement the interface, we will craft out the most basic logic that is going to be initiated for all characters in this. Each method will contain just the very basic amount of logic.
- onMove() - In this method we are going to handle the character's movement patterns. We will also trigger the movement animation.
- onAttack() - since each of the character classes has a specific attack type, the only thing we will do here is handle the animation trigger and also make sure (in terms of game design, this step may vary) that we have the needed setup for the attack to commence. Calculate the damage to the target as well.
- onActionTrigger() - this should basically just trigger an animation whenever we want to interact with something. However, the three character types may have a different way in interacting with objects.
- onCharacterDeath() - this will trigger the death animation, save statistics or whatever is needed to be saved in order for the game to go further with its logic.
Warrior ClassWe have the basics down. So let's create the Warrior class. We will call it WarriorCharacter. It will extend CharacterBase and basically override all of its methods. This is how the methods should be customized to fit the WarriorCharacter class:
- onMove() - Here we will need to add a specific move pattern to the character. Since we have a warrior, he needs to move in a slow yet stable fashion. We will slow down his movement speed. After we've handled that, we will call the basic logic from CharacterBase by using super.onMove(). When the time comes to analyze the movement pattern, we will have already changed it, so now it initiates what we want. It will also trigger the warrior animation for movemet.
- onAttack() - the method should firstly check the distance from the Warrior's transform position in regards to its target. If we are in range - that is up close and personal, we will call the CharacterBase onAttack() method logic by using super.onAttack() or whatever technique your programming language supports in order to do so.
- onActionTrigger() - Our warrior has to be able to interact with breakable objects and well ... break them. This we will do by setting up a trigger in this method that will allow a breaking action for that specific object. How you can actually do that is something that should be designed on the object base, not the character. So, initially we will call the basic logic from CharacterBase and then expand on that by allowing the warrior to break stuff.
- onCharacterDeath() - To build upon the death animation logic, when a Warrior dies, we would want to implement a specific death effect, like dropping your weapon. After we call the original logic, we can add that as well.
super.onAttack()or the method you actually want to call.
Mage ClassNow to implement the mage logic. We will call this class MageCharacter. It will extend CharacterBase and things will work much like with the WarriorCharacter class. Here, the distance of your attack is going to be vastly different from that of the warrior and gradually, the damage is going to be different as well. We are also going to have a missile effect to the attack. Again, when you put extra logic in your methods, make sure you are calling the original ones from the CharacterBase as well. If you don't do that, their basic functionality will not be executed and then nothing useful will come out of this. So this is how our basic methods are going to look for the mage character:
- onMove() - Here the character pattern should be pretty normal. The movement speed as well. In physical terms, the mage is a normal guy so he should move around like the average people. However, we can use magic here. Let's way we use some sort of a skill (again, as said above, we will not go in-depth on the skill thing) that makes our mage fly. In this method we need to check if this skill is on. If it is, we change the movement pattern, the speed and even the animations for the mage.
- onAttack() - As with the Warrior, after we've found our range, the mage should be able to fire. This range however should be bigger then the warrior's range. At that point we should trigger a missile effect. It can be implemented through additional logic in the mages class that is out of scope for this article.
- onActionTrigger() - The magge has to be able to interact with objects through magic. That's to say that we should be able to use skills or our attack even on some objects, like spellbooks for example.
- onCharacterDeath() - Here we should implement a time-span for our mage to be able to ressurect himself if he has such a skill at his disposal. Then we can trigger the standard logic.