The Basics of Creating a Turn Based Battle System
Author: | Xhunterko
|
Submitted: | 19th December, 2004
|
Views: | 6980
| Rated: |
|
|
Part 1: Getting Started
Step One: Bad Guy Fry
Many people when they go about making an RPG seem to have the most trouble is the battle system. They kinda know what its supposed to look like so they set it all up and put the stuff where they want it. Then they sit there on their hands and try to hash it out. The first question that people ask is: how do I make them take turns? This is simple, give the player and the enemy their own groups. If first hit is decided by speed, then the fastest group takes their turn first. Again, really simple. This can be determined by comparing the players speed (taken from stored data) to the enemies speed (based on a random number). Lets say your pitting a bounty hunter against two pirates. The hunters speed is 24, and the pirates speed is calculated to be 12. To code this, simply follow the following:
CONDITIONS
Start of Frame and
Players Speed(Alt Val B) is > Enemies Speed(Random X) then
EVENTS
Activate group BountyHuntersTurn
END
Without speed:
CONDITIONS
Start of Frame
EVENTS
Activate group BountyHuntersTurn
END
Again, the reverse would occur if the Pirates speed was higher then the Hunters speed. Okay, now you have two groups, what do you do with them? The groups control how both sides attack each other. Let's do the player first. Lets call these two groups the "BountyHuntersTurn" and the "PiratesTurn" groups. In the Hunters group, create an event where a player presses your firing key. Control sounds nice so lets use that. Now, on press control, lets shoot something. How about that nice fireball attack that you made. To make it go in front of the player, lets make it shoot only to the right (or to the left if you have the player on the opposite side). So, our code now says:
CONDITIONS
Upon pressing "Control"
EVENTS
Shoot fireball towards the right at speed 100
END
Congratulations! Your crimson circle flies across the screen straight past the bad guy and out of play. Normally, if this was a real game, the enemy would smile at you, laugh, then blow you away with his rifle. Now that we have an "attack", we need to control it. An "attack" is anything that is meant to hurt the bad guy. So, below that code, make a comment that says, hit the bad guy. Now, beneath that, add this collision code:
CONDITIONS
Collision between fireball and Pirate, then
EVENTS
Destroy the fireball
Destroy the Pirate
END
Now whenever you shoot the ball of fire at the pirate, he disappears, or plays out his death animation if you gave him one. Now there is no bad guy to kill, and you'd have to restart to see the the pirate wink out of existence again. Obviously, we need to fine tune this system a little more. To have the enemy reappear, we need to create a new one each time the old one is destroyed exactly in the same place. This is relatively simple. Create an active object and either leave it as the diamond or make a simple decoration for it. The player won't be seeing this so it doesn't matter what it looks like. While in the picture editor for the object, leave the hot spot in the upper left but put the action spot in the top center. Now, back in the event editor in the hunters group.
In order to create more, we have to make sure there are no more left. So, under the collision code for the fireball, make a comment that says 'enemy re-growth'. Create a new condition that compares the number of pirates to something. Select the pick or count option from the menu and then click on the 'compare to the number of "enemy" left' option. Have it test for whether or not the enemy count is less then or equal to 0. Return to the frame editor now and give your pirates the enemy qualifier. Now, under the comparison test, make a new condition to test whether or not the last enemy was destroyed. If you have only one pirate, the code would be true if that pirate was destroyed. To keep things simple, lets use only one enemy. The code should now look like this:
CONDITIONS
Number of pirates is <= 0 and
Last qualified enemy has been destroyed
EVENTS
//Now what happens? We create a new enemy from the center of the regenerator.
Create pirate at (0,0) from regenerator
END
And there's your new enemy!
Step Two: Which One, Which One?
Looking at your interface, you have your attacks listed in the corner somewhere with numbers by them. And you also should have a box surrounding one of the attack names indicating its selected. This is where the article gets a little boring, so I'll try to sum up the main code as best I can. Your indicator box should have 4 animations. Think of it as a bookshelf, the spaces are the exact width and height and are right above and below each other. Make the first animation the top shelf, then the second animation the second shelf, and so on. Oh, the reason I said 4 animations is that for simplicity, we are only using four attacks for this example. Now you have your book shelf ready and you start the engine. What happens; the bookshelf keeps selecting its shelves on its own. To fix this, do the following:
CONDITIONS
Start of Frame (for future reference, this will be known as SoF)
EVENTS
Indicator:
Stop Animation
Reappear
Fore Animation Frame to 1
Set SkillPosition to 1
END
First, we need to freeze it so we can use it later, we need to be able to see it, we make it stop at the start, and we tell it what number skill is selected (in this case, one). The SkillPosition is a value that tells the engine what attack is selected, whether or not its the first or fourth. But, seeing the battle is just started, we make it stop at attack one. Now, obviously the player is going to learn some new attacks so we don't want it stuck on the first attack all the time. To fix this, lets have it so when the player presses the numbers (not on the numerical keypad) the indicator forces itself to the prescribed frame. So, input:
CONDITIONS
Upon Pressing "1"
Upon Pressing "2"
Upon Pressing "3"
Upon Pressing "4
EVENTS
Indicator: Change animation to "Shelf1"
Set SkillPosition to 1
Indicator: Change animation to "Shelf2"
Set SkillPosition to 2
Indicator: Change animation to "Shelf3"
Set SkillPosition to 3
Indicator: Change animation to "Shelf4"
Set SkillPosition to 4
END
Now the player can choose which of the four attacks that he has to use. The value SkillPosition is not added for other reasons to be explained later. Okay, now, whenever you run the engine and you select attack number 2, lets call it the omega-bolt, and you press control, he still shoots the fireball attack. 'How do I stop this' you say, well, you need a few flags, and a Strategy Object. What the...? The Strategy Object is a nifty little tool made by Tigerworks that lets you decide a number of things about attacking. Like the best attack, the last attack, and whether or not an enemy is in frantic mode. The only thing we are concerned with, however, are the commands dealing with attacks.
Lets call our Strategy Object "Player Skills". Now, add to the above code the EVENT underneath the Upon pressing "1" condition: Negate the fact that an Attack is in progress. To do this, right click underneath the Upon "1" condition and select insert. Find the Player Skills object and right click. From the menu, click the condition "Is attack in progress?". When it appears under the code, right click it and select negate from the options. This tells us that when the player is shooting the fireball or omega-bolt, the player can't pick another move.
The code should now read:
CONDITIONS
Upon pressing "1" +
X: Attack in progress (X stands for negate)
etc.
EVENTS
etc.
END
Now, on to flags. See, I told you this was the boring part . All right, lets say the player has four attacks. We have two: fireball and omega-bolt. Lets add wind tunnel and bubbly. So, you select one of your other attacks and the Hunter still shoots the fireball. Lets go back to the Upon pressing "control" code. Under it, right click, select insert. Then, from the menu, find your fireball graphic. Select from the menu alterable values. Then select flags and click the condition "Is a flag on?". Use the value 0 and click okay. Now, go back to the frame editor and right click your fireball graphic. Select properties and click the option Alterable Values. Name value 0 SkillPos and set its value to 1. We do this because its the first attack the player knows. Set omega-bolt's SkillPos to 2, wind tunnel's to 3, and bubbly's to 4. If you have other graphics, leave their values to zero but name the first value SkillPos. Lets make six other attacks now. Lets call them: ground gulp, crystal spike, seedlings, matter bend, power drain, and dark crusher. Use your imagination on what they should look like.
Now, why are we doing this? Well, the player will have to learn some new moves as the game progresses and they can only do that by leveling up. We'll worry about that later. Now, under the firing code, create a condition that checks for the fireballs flag 0 to be on. After that, check to see if the Indicator's SkillPos is equal to the fireball's SkillPos. This is critical because if the player would want a new move more powerful then the fireball, they would replace the fireball with the new attack. Lets say the player wants to learn bubbly. The player would select the fireball and would replace it with bubbly. The text box would say bubbly instead of fireball. Fireball's SkillPos would be set to 0 and Bubbly's would be set to 1. If we did not set the SkillPos values, every time the player would want to shoot bubbly, they would shoot the fireball instead. Now we make sure that each SkillPos is unique and the player shoots what they want. The new code should read:
CONDITIONS
Upon pressing "Control" and
Fireballs internal flag 0 is on and
Indicator's SkillPos = Fireballs
EVENTS
Shoot fireball towards the right at speed 100
END
Step Three: Add the Strategy
Okay, now we have our basic code for the player's attacks. The player can select between four attacks, but they can only use one. To let the player use the four starting attacks, use the same code structure for the other graphics. What we have here is basically a skeleton that we can fit any attack we want around it. So, the omega-bolt's code would read:
CONDITIONS
Upon pressing "Control" and
Omega-bolt's internal flag 0 is on and
Indicator's SkillPos = Omega-bolt's
EVENTS
Shoot omega-bolt towards the right at speed 100
END
The same can be done for wind tunnel, bubbly, and the other six attacks that we made. Now would be a good time to program those. Since they are all shots, they should be quite easy to mimic the code completely. All right, in most RPGs, each attack costs a certain amount of energy. Whether its from a central pool or a set number of times you can use the attack, energy is deducted from the total amount. For our example here, lets have one pool of energy. Create a counter and call it 'energy pool' or 'energy'. You can leave it as numbers or make it a horizontal or vertical bar. I use a horizontal bar so it's easier to see how much you have left.
If you already have a health counter, put it underneath that. If not, make one, set its initial and maximum value to 100, and place it to the top right from your attacks. Then place the energy counter under it. Now, in the frame editor, select your hunter graphic and select the alterable values option. Name value 0 "Health" and value 1 "Energy". Set each of those to 100. Back in the event editor, we have to decide how much energy the fireball is going to cost. Lets say about 25 points of energy. Now when the attack is used, we need to make sure the player has that much energy left so they can use the attack. Then, we need to subtract that amount from the total energy. This is quite easy. Simply make the code look like this:
CONDITIONS
Upon pressing "Control" and
Fireballs internal flag 0 is on and
Energy of Bounty Hunter >= 25 and
Indicator's SkillPos = Fireballs SkillPos
EVENTS
Shoot fireball towards the right at speed 100
Bounty Hunter: Sub 25 to Energy
END
As you may be wondering, no, this is not the complete code. At least a couple more lines are still missing. Now, mimic that for the other attacks. Once that is finished, we need to tell the computer that an attack is taking place. Return to the piece of code that shoots the fireball. In the events column, right click under the strategy object called "Player Skills" and select the "Attack" option from the menu. In "Attack"s sub menu, click begin attack. Remember the indicator code where we added the phrase "X:Attack in progress"? Well, this tells us that an attack is in progress. Our code should now read:
EVENTS
Shoot fireball towards the right at speed 100
StrObj:"PlayerSkills": Begin Attack
Bounty Hunter: Sub 25 to Energy
END
Now mimic that for all the other attacks. Not every attack now, should not have the same energy requirements. Make up whatever you think is best. Dividing up the energy costs is not easy. To recap, if you have followed the steps up to this point, you should have a group that looks something like this:
CONDITIONS
Start of Frame
EVENTS
Indicator:
Stop Animation
Reappear
Fore Animation Frame to 1
Set SkillPosition to 1
END
;;The player picks the attack
CONDITIONS
Upon Pressing "1"
X:Attack is in progress
Upon Pressing "2"
X:Attack is in progress
Upon Pressing "3"
X:Attack is in progress
Upon Pressing "4"
X:Attack is in progress
EVENTS
Indicator: Change animation to "Shelf1"
Set SkillPosition to 1
Indicator: Change animation to "Shelf2"
Set SkillPosition to 2
Indicator: Change animation to "Shelf3"
Set SkillPosition to 3
Indicator: Change animation to "Shelf4"
Set SkillPosition to 4
END
;;The player shoots an attack
;;or bad guy fry
CONDITIONS
Upon pressing "Control" and
Fireballs internal flag 0 is on and
Energy of Bounty Hunter >= 25 and
Indicator's SkillPos = Fireballs
EVENTS
Shoot fireball towards the right at speed 100
StrObj:"PlayerSkills": Begin Attack
Bounty Hunter: Sub 25 to Energy
END
;;The other attacks should appear below these lines
;;If you added the collision code, it should appear below the attacks
CONDITIONS
Collision between fireball and Pirate, then
EVENTS
Destroy the fireball
Destroy the Pirate
END
;;The re-growth code should appear below this
CONDITIONS
Number of pirates is <= 0 and
Last qualified enemy has been destroyed
EVENTS
Create pirate at (0,0) from regenerator
END
Before we move on to part two, we need to add a few more things to get prepared for new code. First of all, I may have told you to add the alterable values "Health" and "Energy" to the Hunter graphic. Lets add a few more. Value number 2 should be given the name "New Skill" and its value set to 4. We need this so that every time the players level matches this number, the player learns a new move. We'll put that code in later. Sometimes, you may want to give the player more health and energy as the game gets more difficult. To do this, we simply add two new values. Lets call them "MaxHealth" and "MaxEnergy". During play, the "Health" value can never be higher then the "MaxHealth" value. The counter always reflects the "Health" value. Next, we need to add the level up values. These values are "Level", "Experience", and "ExperienceMax". Create their respective counters and place them under the health and energy counters. The counter display should look something like this:
Lv.5 Hlth******** Nxt: Lv.12
Enrg-----------
Exp 19/100 ExpMax
The text indicators for the health and energy bars and the new skill aren't necessary. They are just there for this article. Now of course, we have to keep track of these new values. So we get to make some new code. Create an event below the enemy regeneration code from the special selection and choose "Always". Now, we need to make sure that the counters show what's really going on. We need to set the health counter to the health value. The energy counter to the energy value. Do the same for the other values as well. Okay, we're almost ready for part 2! But first, we have to individualize the attacks. Every time that the fireball hits the pirate he gets destroyed. But the other attacks do nothing. How boring! So, lets fix this. First, if I've not already told you to do so, give the Pirate graphic a health value. Lets call it "PiratesHealth".
In the frame editor, create a counter above the Pirate and call it, "PirateHealth". Lets set his health value to, say, 75 or 100. Just pick one. In the event editor under the re-growth code make an event that always sets the pirate health counter to the pirate health value. Now lets take a look at that fireball collision code. For now, the fireball is free to use and destroys the enemy in one hit. That's not fair or fun. So, instead of having the fireball vaporize the pirate on contact, lets subtract from his health. Replace the destroy the pirate code with this: Sub 5 to "PiratesHealth". Now the pirate loses five health each time the fireball hits him. It's really easy to mimic this for the other attacks. Lets use these numbers for damage:
Fireball: Dmg =5
Omega-Bolt: Dmg = 10
Wind Tunnel: Dmg = 15
Bubbly: Dmg = 25
Ground Gulp: Dmg = 50
Crystal Spike: Dmg = 15
Seedlings: Dmg = 50
Matter Bend: Dmg = 75
Power Drain: Dmg = +25 Health*
Dark Crusher: Dmg = 75
*Whoops!
Power Drain should be really easy to program. In my file, I only use five attacks instead of six. So lets just go with only five attacks. Dmg is equal to the amount of damage the attack causes. I shouldn't have to walk you through all of them but I'll do one and you can probably figure the rest out. So, for example, the Omega-Bolt's code would read like this:
CONDITION
Collision between Omega-Bolt and Pirate
EVENT
Destroy Omega-Bolt
Sub 10 to "PiratesHealth"
END
I'll let you figure the other attacks code. In this section, you have completed two things. The player can pick four attacks and the attacks do different things when they hit the pirate. The next set of coding covers leveling up, an enemy that hits back and regenerates, and the player and the enemy take turns hitting each other. Part B will also prepare the engine for part two. Which, will cover learning new attacks and a more advanced enemy. Questions, comments, bugs, or something you think I forgot? Post it here. I hope you found this useful and explanatory. Part B is coming next!
Step Four: Almost Done
Okay, we need to set up for what we're going to do next. We have to make the player level up. We have to give the enemy a chance to attack. We also need to give the player the opportunity to learn new attacks. These are all very easy to do. Well, except for the attack learning. (That's for part two!) We can get that ready now but program it in part two. Leveling up the player is quite easy. This is where the "Experience" and "ExperienceMax" values come in to play. You should already know how this is going to turn out. But since you can't read my mind I'll help you along. Return to the line of code that keeps track of all the player stats. Now, under that, make a comment that says something like 'level up' or something. Make a condition that compares the players "Experience" value to the "ExperienceMax" value. Test to check to see if its lower then or equal to the "ExperienceMax" value. If it is, then we need to first increase the experience max value.
We want it to increase incrementally but randomly as well. From the hunter, set his Experience Max value to his "ExperienceMax" value +100 + Random(50). The player knows their going to level up every 100 points or so. What they don't know is exactly when their going to level up. That's why we add the random 50 points. After we increase the experience max, we increase the level. Just add one to the level value after the experience is increased. This is what the code should look like:
CONDITION
"ExperienceMax" of Hunter <= "Experience" of Hunter
EVENTS
Hunter: Set "ExperienceMax" to "ExperienceMax" of Hunter +100 + Random(50)
Hunter: Add 1 to "Level"
END
Lets return to the enemy regeneration code for a moment. Lets move it underneath this code and reform it a little bit. You've been probably wondering how the player gains experience. And if we create a new enemy after the old one dies, when does the player get a break. If we'd keep going on like this playing with an enemy that hits back, the player would probably die about the third or fourth enemy. Maybe the fifth if the last one was stupid. After moving the code, we need to give the player a little refresher and some experience. So, before we create a new enemy, lets set the hunter's health and energy back to 100. Then, lets give the player 50 experience points plus a random 10 extra. The new code should look like this
;The re-growth code should appear below this
CONDITIONS
Number of pirates is <= 0 and
Last qualified enemy has been destroyed
EVENTS
Hunter: Set "Health" to 100
Hunter: Set "Energy" to 100
Hunter: Add 50 + Random(10) to "Experience"
Create pirate at (0,0) from regenerator
END
Now lets give the enemy a chance to attack and take away the players rapid fire. If you're the debugging sort you may have realized that you can shoot as many times as you want to. This is not good! We need to fix this so pay attention. Underneath the code you just wrote, lets make a new condition. If you've not already done so, qualify all your attack graphics into one group. I used the qualifier for arms so lets use that. (It's the gun icon dummies.) First, we need to check to see whether or not any attack has hit the enemy. I've done this already! You think, but this time it's different. We're not testing to see whether or not a single attack hits the pirate, but whether any attack hits the pirate. That is why we need the qualified group. Doing this is relatively simple. Just check if any group arms collide with group enemy. Then, destroy the group arms and tell the PlayerSkills object to end the attack. The following code should look like this:
CONDITIONS
Collision between "Group Arms" and "Group Enemies"
EVENTS
"Group Arms": Destroy
"PlayerSkills": End Attack
END
We're not done yet. After the player attacks, we need to switch to the enemies turn. Again, this is really simple. Check to see if the "PlayerSkills" object has finished an attack, then, deactivate the Hunters group. Activate the pirates group, and set the pirates flag 0 on. We also need to take away the rapid fire. Check the "PlayerSkills" object to see if an attack is in progress. Then, ignore player ones control. The above code should look like this:
CONDITIONS
"PlayerSkills": Attack just finished
EVENTS
Special: Deactivate group "Hunter"
Special: Activate group "Pirate"
Pirate: Set internal flag 0 on
CONDITIONS
"PlayerSkills": Attack in progress?
EVENTS
Player 1: Ignore Control
END
When we ignore the players control, we prevent rapid fire. When the attack hits the enemy, we switch to the Pirates group. Control is restored automatically when we switch back to the Hunters group. For the last pieces to prepare for part two, we need only a couple more things. We need to check the players health to see if it goes down to zero. If it does, then we need to kill the player, give them a message, and restart the battle. Then, we need to keep track of the players experience and give them the chance to learn a new move. We also need to set up the attack tracking system for the level up system. We will do one part first and do the rest later. Lets get started. We're already keeping track of the players health with a counter. Now, we need to test for the value of the players health.
If you're wondering if this is a little out of place, you're probably right. So, lets let the player be able to die. This is quite easy. Merely write in the following code:
CONDITIONS
Health of Hunter <= 0
EVENTS
Hunter: Destroy
CONDITIONS
Every 2"-00 and
Last Hunter has been destroyed
EVENTS
InfoString: Set alterable string to "You Lose!"*
Storyboard Controls: Restart current frame
*Optional if you have one.
END
If you want to move it somewhere to where you think it should be, go right ahead. Now its time for some candy. What's candy you say? Just something I put in to make you excited. So, now that the player gains experience, we need to do something with it. We wanted to give the player the chance to learn some new moves so lets plug that in. You probably remember the value "NewSkill" right? This represents the level that the player learns a new move at. The starting value is four (I told you to set it to that right?). Lets make it so that every time the players level matches the new skill value, it goes up by 8 and the player learns a new move. The Level Up system requires two groups. One called "Level UP!" and another called "Level UP Yes". Make these two groups now. While your scratching your head wondering what these could mean, I'll give you a little briefing.
The first group asks the player whether or not they want to learn a new move. This is done with a text box and the number keys. If the player says yes, the first group jumps to the second group. If the player says no, play is resumed as normal and the game continues. The second group starts the Activation Deactivation system. The attacks are picked by numbers corresponding to a move already known. If the player wants to learn the move water hose, for instance, and they already have four moves. They want to forget wiggle bomb and it is in slot number 3. The player merely presses the number 3 and wiggle bomb is replaced with water hose. You're probably thinking this is complex, and you're right. EVERY slot must be accounted for the new move and the first four moves must be checked for in EVERY slot for EVERY new attack. Don't think, 'Aww, this is simple' either. Don't worry, you'll get to do all this in part two.
What we have here now, is part of a larger system designed to be interactive with the enemies. But, there's one more thing we need to do with the player before we do anything else. At the start of the frame, the player begins at level four. We need to set the first four moves and get them set up. First, check if the Hunter's value Level is equal to four. Then, using the fireball as an example, set its skillPos to 1, set its internal flag 0 on, set the string relevant to the first attack to the text "Fireball". The following code includes the other attacks:
CONDITIONS
Level of Hunter = 4
EVENTS
Fireball: Set SkillPos to 1
Omega-Bolt: Set SkillPos to 2
Wind Tunnel: Set SkillPos to 3
Bubbly: Set SkillPos to 4
Fireball: Set internal flag 0 on
Omega-Bolt: Set internal flag 0 on
Wind Tunnel: Set internal flag 0 on
Bubbly: Set internal flag 0 on
String(AttackSlot1): Set alterable string to "Fireball"
String(AttackSlot2): Set alterable string to "Omega-Bolt"
String(AttackSlot3): "" to "Wind Tunnel"
String(AttackSlot4): "" to "Bubbly"
END
Now, don't let me lose you on this part. The strings, positions, and flags are all set here because the players level eventually changes. I've debugged mine and if I didn't have this in there, it wouldn't work. The flag 0 means this attack is learned. In the Level UP Yes group, this flag is the one that gets turned off or on. The attack slot strings should already be in place. If you called them (or I told you already) to call them something else, then the strings would be the four text boxes where the attacks names appear in the upper left hand corner of the screen. That is the last amount of code for part 1 for the Hunter's group. You almost have a battle system working, but lets let the pirate hit back so it's finished. You should have four groups by now. They should be called "Hunters Group", "Level UP", "Level UP Yes", and the "Pirates" group. Lets program the enemy now.
Part Five: Finishing Up
The enemy for part one is not very advanced. For instance, it can only shoot the Fireball and it can't level up or heal. The attack structure is different then the players as well. The enemy has to choose a random attack to use against the player. The structure for enemy tactics is fairly based on the same code as the player tactics. You may also notice that some code is repeated or may be there for debug purposes but it is like that because I know it works that way . You probably have an idea of how the enemy code should look like so lets get started. First we need to clock in the enemies group. In the group, check to see if its activated.
Then, set the pirates flag 0 on and the hunters flag 0 off. I told you earlier to have two Strategy Objects. One for the player and one for the enemy. The enemy and player use the same attacks. Since the enemy only gets to use one for this example, we only need to tell the enemy strategy object to use 0 attacks. We use 0 instead of one because the Strategy Object counts 0, 1, 2, 3 e.t.c., instead of 1, 2, 3. If I told you to call the enemy Strategy Object something else before, call it "EnemyTactics" now. (You did put in two Strategy Objects right?) Okay, now, the above code should look like this:
CONDITIONS
Group Pirates Turn is activated
EVENTS
Pirate: Set internal flag 0 on
Hunter: Set internal flag 0 off
"EnemyTactics": Use 0 tactics
END
To tell the Strategy Objects how many tactics to use, simply right click under the Strategy Object in the event row and pick the option that says "Set number of tactics" and punch in the value 0 and click okay or hit enter. Now we need to check whether or not the pirate is ready for an attack. To do this, we need to check for a flag, we need to check if the enemy is not attacking already, and we need to check the enemies health. If everything checks out, then we need to tell the enemy strategy object to pick a random tactic and begin the attack. As some of you may have figured out, this is quite easy to do. The code should look like this:
CONDITIONS
Pirate: Internal flag 0 is on
Negate "EnemyTactics": Attack in progress
PiratesHealth of Pirate > 0
EVENTS
"EnemyTactics": Choose random tactic.
"EnemyTactics": Begin attack.
END
Yay! Now the enemy is ready to hit back! Since the pirate is only using one attack, we needed to test for only one value. But, the player has ten attacks, you whine. Well, since this is just the starter kit for a battle system you'll have to wait for part two for more advanced stuff. (Or, you can try and program the other attacks on your own, its not that hard.) Now, to get the enemy to shoot, we need to check for his turn flag. This is flag 0. Always check for the flag before attacking so the pirate doesn't continue to rain fire on our hero during the players turn. Now we have to tell the strategy object to check for which attack is being used. We tell the strategy object to pick a random number because each attacks number is unique and it would be boring if the pirate shot the fireball all the time. But, since we only have one attack, it only picks that one attack. After the tactic is chosen, however, we need to make sure it only happens once. We do this by making it have only one action when the event loops. After all this, only then does the pirate shoot the fireball towards the hunter. The code should look like this:
CONDITIONS
Pirate: Internal flag 0 is on
"EnemyTactics": Current tactic is #0
Special; Limit Conditions: Only one action when event loops
EVENTS
Pirate: Shoot Fireball in direction(LEFT) at speed 100
END
That's pretty good! Now, after the player hits the enemy, the enemy shoots a fireball towards the player. However, like the code for the player, the fireball just flies by the hunters head and misses completely. Also, the pirate keeps shooting and the player never gets another turn. We can't have a missing enemy or a player who only gets one turn. So, to end the pirates turn, we do things a little differently. Since the player is able to learn attacks, the attacks are set off by a flag. But since the pirate only gets one, the strategy object must check for the tactics number being used. Also, we need to check which graphic is being used as well.
By graphic, I mean the part of the attack that actually touches the player, not the debris particles plugged in to make it look fancy. So, we also check for the tactic number and the graphic so we can see how much damage is done and whether or not the attack is over. A few things need to happen after the fireball collides with the player: first, destroy the fireball, then, set the pirates internal flag 0 off, subtract the damage done from the players health, and finally tell the "EnemyTactics" object to end the attack. The code should look like this:
CONDITIONS
"EnemyTactics": Current tactic is #0
Collision between fireball and Hunter.
EVENTS
Fireball: Destroy
Pirate: Set internal flag 0 off
Hunter: Sub 5 to Health
"EnemyTactics": End Attack.
END
Now we can control the pirate attack a little, but as you may have noticed, the player still does not get to attack again. This is because we did not go back to the players group after the attack is over! This is quite simple. We need to check if an attack has just finished for the "EnemyTactics". Then, we need to FIRST activate the Hunters group THEN deactivate the Pirates group AND set the Pirates internal flag 0 OFF. The code MUST be in that order or it won't work. Because if not, the pirate will never shoot again and the player won't be able to either. It just freezes. Trust me, I've tried it. The coding should look like this:
CONDITIONS
"EnemyTactics": Attack just finished
EVENTS
Special: Activate group Hunters Turn
Special: Deactivate group Pirates Turn
Pirate: Set internal flag 0 off
END
The Pirates code is not finished yet. If you would try to play it you may notice a few things that aren't working right or aren't getting updated. We are going to fix these problems by adding a little more code. First of all, we need to make sure the Pirates group knows which counter represents the Pirates health and have it always equal to the value. We need to restart the engine if the player gets killed. Also, if the pirate has no more health left we need to go back to the players turn to let it regenerate. This is, again, quite easy to do. The code should appear as this:
CONDITION
;;Keeping the enemy health constant
Always
EVENTS
Counter "PiratesHealth": Set counter to PirateHealth of Pirate
;;Restarting the engine. In my code, I have a text box message but it doesn't show.
CONDITION
Last Hunter has been destroyed
EVENTS
Frame: Restart the application
;;Returning health less
CONDITION
PirateHealth of Pirate <= 0
EVENTS
Pirate: Destroy
Special: Deactivate Pirates turn
Special: Activate Hunters turn
END
As you can see, its quite easy to do. I'm not putting the complete code list below this because this article would be far to large. I'm also including a list of objects that you need for the interface and a crude example of what it should look like. So, here's the object list and relevant values that they need:
Graphic Values
Hunter graphic: Health = 100, Energy=100, NewSkill = 4,
Experience = 0, ExperienceMax = 100,
MaxHealth = 100, MaxEnergy = 100
Pirate graphic: Health = 100
Fireball: SkillPosition = 1
Omega-Bolt: SkillPosition = 2
Wind Tunnel: SkillPosition = 3
Bubbly: SkillPosition = 4
Enemy Regenerator: (This is where the enemy comes from.)
Position Indicator: (This is the box around the attack text that the player uses to pick) (which attack they wan to use.)
(The other attacks should have their SkillPosition values set to 0.)
Counter Values
Health = 100
Energy = 100
Level = (Start at 5)
Next Level = 12
Experience = 0
ExperienceMax = 100
(These are the initial values of the counters. The values will later be changed by the code.)
A few other things have to happen that weren't mentioned in the text that occurs at the start of frame line. Here's what else is supposed to happen.
CONDITIONS
Start of Frame
EVENTS
Pirate: Set internal flag 0 off
Pirate: Set EnemyHealth to 100
Hunter: Set Experience to 0
Hunter: Set Level to 4
Hunter: Set ExperienceMax to 100
StringSlot1: Set alterable string to "Fireball"
StringSlot2: Set alterable string to "Omega-Bolt"
StringSlot3: Set alterable string to "Wind Tunnel"
StringSlot4: Set alterable string to "Bubbly"
Indicator: Stop Animation, Reappear, Force Animation Frame to 1,
Set SkillPosition to 1
Fireball: Set SkillPosition to 1
Omega-Bolt: Set SkillPosition to 2
Wind Tunnel: Set SkillPosition to 3
Bubbly: Set SkillPosition to 4
Ground Gulp: Set SkillPosition to 0
Crystal Spike: Set SkillPosition to 0
Seedlings: Set SkillPosition to 0
Matter Bend: Set SkillPosition to 0
Dark Crusher: Set SkillPosition to 0
END
To recap, here is what the interface should look like to the user when playing the game.
1. Fireball Lv.5 ******** Nxt*: Lv*.12
2. Omega-Bolt -----------
3. Wind Tunnel 19/100
4.Bubbly
(*The text indicators for the next level aren't necessary. But the numbers behind the attack strings are. Also, the * dots represent the health, and the - dots represent the energy. The value 19 is only an example number and is the Experience counter. The 100 represents the ExperienceMax number.)
This is just a simple version of the complete battle system without learning moves and a more advanced enemy. The only extension I used was the Strategy Object and I did not use the mouse. You may also notice a repetitive nature in the code. This is because after testing, things wouldn't get updated or they'd show the wrong values and such. Also, because if one group kept track of a value, then when the engine switched to the other group the value was "lost" somehow or it failed to update. Don't ask me for a better explanation, it just works this way. Also, this is not the exact code I have in my engine either. All I did with it was replace a couple names and make the code neater in some places. More like a template code if you will. Don't worry, it should still work since I wrote this code while looking directly at mine. I hope everyone finds this useful and if they find an easier way to do things other then this then please share it with the community. Questions, comments, bugs, or something you think I forgot? Post it here. Don't worry, I won't leave you hanging, Part Two is coming soon!
|
|
|