On this next entry, I’ll talk about some visual enhancements like adding the tilemap and the battle background. I’ll also be discussing the Battle Menu Window and the Player Status Window. Finally, I’ll implement the attack and escape commands in their proper format.
Since I don’t need a fully functional tilemap what I did was build it using Unity’s UI system. Our focus is on making the battle system, so in this case, this approach is fine.
All we have to do is add a GridLayout to the map and each of the lines and set the cell size as 16x16 (our title size).
For the battle background, I extracted it from a screenshot I had. It’s not the most perfect, but as with the tilemap it serves its purpose.
Battle Menu Window
The battle menu window was already placed but it wasn’t doing anything. I made an arrow asset based on the original one. Then I placed it as a child of one of the menu items. The idea is to switch the arrow’s parent and it will snap to the right position. The trick here is that each menu command has a grid layout with a left offset defined.
For that to work, we need to write some code for the menu commands. The Battle Menu Window needs to get notified when each of the menu commands gets focused. You can do this through Unity’s inspector, but let’s look at how to expand the Button script class with what we need.
The idea is to have the buttons fire an event when they get focused. I also added an Id so we can tell each menu command apart. On the Battle Menu Window we listen to these events and set the arrow.
Attack and Run Commands
With the introduction of the escape command, we can see that the structure made before won’t be enough. We need a more versatile one that lays the ground for new commands to come. Let’s consider that every time a player chooses a command, we add it to a list. We also consider the enemy as “choosing” a command, and we also place that in the same list.
Now, instead of manually executing the commands as before, we’ll make it more abstract. Let’s add a coroutine so we can pause the execution to display messages and wait for animations in the future. Both attack and run commands have the same core structure. They execute some code, they have a use message (eg. “Player uses…”) and a result message.
The basic sequence is: Execute the command, show the use message, show the result message.
At first glance it might seem like a lot to digest so let’s take this step by step:
1. We get the first command of the list and then remove it from the list as well.
2. We execute the command and show it’s use message.
3. We wait for its use message to display fully.
4. On the next line, we check if the command was successful (in case of an attack, if it did hit) and if it’s set to do a screenshake effect. If it’s set for that we’ll do a screenshake and wait for it to end. For now, this is how it’s set up for when the enemy attacks. More on that code for this ahead.
5. We display the result message and wait for it to be on screen.
6. We check if the battle ended, meaning if the enemy or player died. If so then quit the execution.
7. If the command executed was an Escape command we check if it was successful. If so then we quit the execution.
8. We update the player’s HP in case it receives any damage or healed itself.
9. If there’s another command after that we go back to step one, if not then we ask the player for a new command and quit execution.
Let’s take a look at the WaitMessage and the ScreenShake functions:
On the WaitMessage, every 0.1 seconds we check to see if the WindowBattleLog is idle. It will be considered idle once there’s no more text to consume for display.
The ScreenShake will take the WindowBattleLog’s parent, which is an empty game object that holds all windows in the game. Then, it will tween it’s X and Y position back and forth a few times. This creates the desired shake feel and the randomness makes things less tedious.
Now, let’s change the attack command to use the proper Dragon Quest I RPG formula. Before that, we need some other parameters on our character class. At this point, we see that enemies will have specific parameters. So let’s also create another class that inherits from character.
Enemies have other particular parameters that we’ll add later on. For now, all we need is the ID and the group factor function. In the original Dragon Quest, that’s how it’s set up. Based on the enemy ID they consider him a part of a given group. This affects the enemy’s defense.
Now, for both the attack command and the run command we run a formula to calculate how much damage / if the escape was successful.
Let’s go over the attack command execution. We get the target’s defense, which is considered to be half it’s agility, then we set the min and max damage possible. We then random between these two values to get the final damage.
In case it’s the player attacking if the damage is lower then 1 there’s a 50% chance the damage will be 1 instead. When the enemy is attacking if his strength is lower than the player’s defense we use another formula to calculate the damage.
With the escape command, we simply run the formula. Note that there’s a call to the group factor function mentioned before and also a call to a RandomNum function. In the original DQ they get a random number from 0 to 255, this function does that for me.
The final result can be seen ahead:
On the next and final part, I’ll be adding the audio and player attack animations. We’ll also take a look at the item and spell options.
- Dragon Warrior Formula Guide: Useful if you want to check the formulas and parameters involved.
- Unity’s UI Git: Useful if you want to write your own UI scripts with specific functionality.
Originally published at https://www.tumblr.com on December 14, 2016.