Event Vision-A Tutorial by madriel222
Ever interested in creating a mini-game in which your hero has to move around, in stealth, to accomplish your goal? Do you want your battle system to be more than enemy's "Move Toward Hero" as their only AI? In this tutorial, I will be demonstrating how to create, then implement, partial radial vision into your RPG Maker project.
Before we begin, make sure to put down all the "seeing" events on your map. Doing this will make sure that we aren't referencing events that do not exist, resulting in a fatal error.
I. Why Partial Radial?Partial Radial vision is, in my experience, the most realistic mode of vision available to us on RPG Maker 2000/2003 (with scripts, you can get even more precise, but oh well). With it, we can include a periphery, a cone of vision, and a horizon. Unlike linear vision, which most RPG Maker projects use, partial radial has the advantage of being able to "see" objects that are not on the same X or Y coordinate.
The graphic above illustrates the sort of vision we will be creating, with the black box representing the event we'll be giving eyes to. We will also be making the system facing dependent, meaning that your events will not be able to see things behind them. The entire system takes three events to create, including the event that will "see." For each additional event that you wish to give the gift of sight, you need only to include the final event I present in this tutorial.
II. Variables and SwitchesFor the system I am about to lay forth, we will need two variables for the hero, two variables for each "seeing" event, and two additional variables for each "seeing" event that will act as a numerical operator. To avoid confusion, this tutorial uses the following variables and switches:
Variables:
"HeroX": Used to record the Hero's X coordinate at all times.
"HeroY:" Used to record the Hero's Y coordinate at all times.
"MonsterX": Used to record the "seeing" event's X coordinate at all times.
"MonsterY": Used to record the "seeing" event's Y coordinate at all times.
"DifferenceX": Will determine the difference between HeroX and MonsterX
"DifferenceY": Will determine the difference between Hero Y and Monster Y.
Switches:
"CAUGHT": Switch triggered if the Hero is in the Monster's line of sight.
III. The Tracking EventThe tracking event continually checks where all relevant objects are on the map. The other two events refer to this one in order to make their calculations.
First, make a new event on your map (I put this one in the corner, generally, away from the player) and drag the "Trigger Condition" menu to "Parallel Process." For those of you unacquainted with this mechanic, a Parallel Process is an event that runs simultaneously with all other events on your map. Anyway, for this example, you only need four lines of code. Go into your event commands and select "Variable Operation." From here, select "HeroX" as your variable to change. Toward the bottom of this same window, you should see an option for "Sprite." Change the leftmost box to "Hero" and the box next to it to "X Coordinate." Make sure you are not using the "Screen Relative" version, as this uses pixels as the measurement, not tiles. Repeat this process with "HeroY," "MonsterX," and "MonsterY," selecting the options accordingly (i.e. using Y coordinates on the ones labeled as such, using the Monster sprite for the last two). When all is said and done, your event looks like this:
Parallel Process/Below Hero
<>Variable Oper: [0001:HeroX] Set, Hero X Coord.
<>Variable Oper: [0002:HeroY] Set, Hero Y Coord
<>Variable Oper: [0003:MonsterX] Set, Monster X Coord
<>Variable Oper: [0004:MonsterY] Set, Monster Y Coord
That's all for this event, nothing too hard, right?
IV. Number CrunchingI'm not a math person, and if you aren't either then you'll be happy to know that you don't actually have to make any heavy calculations for yourself. Bear with me as I throw some terms out there you might not be familiar with as I go over the theory of this event.
We are going to make a new event that takes the absolute value of the differences between the Hero and Monster's coordinates and throws the result into a new variables. Why the absolute value? While RPG Maker actually handles negative numbers surprisingly well, taking the absolute value allows us to make the last event's code that much simpler, and replicable. Also, some commands related to the vision system can be buggy when using negative values. Why the difference? We are subtracting values in order to place the Hero, mathematically, in relation to the "seeing" event. If I take their X coordinates and subtract them, for example, I know how many tiles left or right the hero is in relation to the "seeing" event. That's enough theory, though, let's show the code!
Begin by making a new event that is also a Parallel Process. Now, make a "Conditional Branch" (third page of the command list). Check the option for "Variable" and select our "HeroX" variable. Underneath that option, indented, you'll see "Variable Reference," check that option and select "MonsterX" as your variable. Lastly, underneath that option, select "Greater Than" from the list. This will tell us if the Hero is on the left or right side of the Event. This branch requires a custom Else Handler, so make sure that option is checked as well.
Within this conditional branch, set a new variable, "DifferenceX" equal to "HeroX" using the "Value of Variable" operand. Immediately after this command, make another variable operation that subtracts "MonsterX" FROM "DifferenceX" (i.e. DifferenceX-MonsterX). This new total represents how many tiles away from the Event the Hero actually is. In the Else Handler of this conditional branch, simply reverse the process. Set "DifferenceX" equal to "MonsterX" and subtract "HeroX" FROM "DifferenceX". We do this because if "MonsterX" is greater than "HeroX," we want a positive number out of it. Repeat this entire procedure starting from the new conditional branch, for the Y coordinates as well. The final code for this event will look like this:
Parallel Process/ Below Hero
<>Branch if Var [0001:HeroX] is V[0003] Greater
<>Variable Oper: [0005:DifferenceX] Set, Var [0001]'s Value
<>Variable Oper: [0005:DifferenceX] -, Var [0003]'s Value
<>
: Else Handler
<>Variable Oper: [0005:DifferenceX] Set, Var [0003]'s Value
<>Variable Oper: [0005:DifferenceX] -, Var [0001]'s Value
:End
<>Branch if Var [0002:HeroY] is V[0004] Greater
<>Variable Oper: [0006:DifferenceY] Set, Var [0002]'s Value
<>Variable Oper: [0006:DifferenceY] -, Var [0004]'s Value
<>
: Else Handler
<>Variable Oper: [0006:DifferenceY] Set, Var [0004]'s Value
<>Variable Oper: [0006:DifferenceY] -, Var [0002]'s Value
:End
V. Putting It All TogetherFor this last event, I generally like to put my code into the actual "seeing" event. This might not be your taste, especially if you want that object to be interactive via the action key as well. If that is the case, then you can just slap this next bit into a new parallel process, but if you're like me, we'll be putting this straight into our Monster event.
Begin by switching our "seeing" event's trigger to "Parallel Process." For your Hero to be "caught," two things need to be happening. First, the Monster has to be facing the right direction. Second, the Hero has to fall within the Monster's field of vision. To accomplish this, we'll be using four conditional branches. Sounds excessive, but stay with me.
(The following conditional branches do not require Else Handlers!)
Create a new conditional branch that checks if the Monster sprite is facing...let's say left (this is on the second page in the "Conditional Branch" command). Follow that up with a conditional branch directly inside that checks if "DifferenceY" is less than "DifferenceX." Why is this a condition? If "DifferenceY" is greater than "DifferenceX," the Hero will fall outside of this left-facing circle we're creating, outside the Monster's periphery. Inside of this conditional branch, make another that checks if "HeroX" is less than "MonsterX," as this code makes sure that the Hero is on the left side of our left facing event. Within this new branch, add "DifferenceX" and "DifferenceY" together using a variable operation. Then, make a new conditional branch that checks if "DifferenceX" is UNDER a certain value. I'll use 5 in this example, as that is how it's drawn in my illustration, but it can be literally any number you want. The number you put here determines how far out your event can "see" at its farthest point, the diameter of your circle. If all of those conditions are true, you can then execute your "CAUGHT" handler by, for example, turning a switch on, teleporting the Hero, or zapping him with lightning. It's really up to you!
For each of the other facings, we will more or less repeat the above steps, but with a few changes. To make things easier on your eyes, I'll just tell you what needs to be changed for facing Up, Down, and Right.
Facing Right:
*Checks if "DifferenceY" is less than "DifferenceX" (same)
*Checks if "MonsterX" is less than "HeroX" (flipped)
*Still adds "DifferenceX" and "DifferenceY" together (same)
Facing Up:
*Checks if "DifferenceX" is less than "DifferenceY" (flipped)
*Checks if "HeroY" is less than "MonsterY" (changed variables)
*Still adds "DifferenceX" and "DifferenceY" together (same)
Facing Down:
*Checks if "DifferenceX" is less than "DifferenceY" (flipped)
*Checks if "MonsterY" is less than "HeroY" (changed variables, flipped)
*Still adds "DifferenceX" and "DifferenceY" together (same)
Phew! Got all that? Here's the code for reference:
Parallel Process/Same Layer As Hero
<>Branch if This Event Left Facing
<>Branch if Var [0006:DifferenceY] is V[0005] Less
<>Branch if Var [0001:HeroX] is V[0003] Less
<>Variable Oper: [0006:DifferenceY] +, Var [0005]'s Value
<>Branch if Var [0006:DifferenceY] is 5 Less/Equal
<>Switch Operation: [0001: CAUGHT!] ON
<>
:End
<>
:End
<>
:End
<>
:End
<>Branch if This Event Right Facing
<>Branch if Var [0006:DifferenceY] is V[0005] Less
<>Branch if Var [0003:MonsterX] is V[0001] Less
<>Variable Oper: [0006:DifferenceY] +, Var [0005]'s Value
<>Branch if Var [0006:DifferenceY] is 5 Less/Equal
<>Switch Operation: [0001: CAUGHT!] ON
<>
:End
<>
:End
<>
:End
<>
:End
<>Branch if This Event Up Facing
<>Branch if Var [0005:DifferenceX] is V[0006] Less
<>Branch if Var [0002:HeroY] is V[0004] Less
<>Variable Oper: [0006:DifferenceY] +, Var [0005]'s Value
<>Branch if Var [0006:DifferenceY] is 5 Less/Equal
<>Switch Operation: [0001: CAUGHT!] ON
<>
:End
<>
:End
<>
:End
<>
:End
<>Branch if This Event Down Facing
<>Branch if Var [0005:DifferenceX] is V[0006] Less
<>Branch if Var [0004:MonsterY] is V[0002] Less
<>Variable Oper: [0006:DifferenceY] +, Var [0005]'s Value
<>Branch if Var [0006:DifferenceY] is 5 Less/Equal
<>Switch Operation: [0001: CAUGHT!] ON
<>
:End
<>
:End
<>
:End
<>
:End
Well that's about it! With these three events, you have now incorporated partial radial vision into your RPG Maker project! To add more events with eyes, it's just a matter of repeating the above steps. Hopefully, you can take something away from this tutorial. Thanks for reading!