Gw Temp

Menu

Tutorial - 'ABS Tutorial Part 2 - Enemies That Can See' by AzureFenrir

An item about RPGMaker 2000 posted on

Blurb

Part 2 of AzureFenrir's ABS Series which shows how to implement different vision systems.

Body

ABS Tutorial Part 2 - Enemies That Can See


I'm back again, with the second installment of my ABS Tutorials. In my previous tutorial, I showed you how to implement basic ABS attack algoithms. However, an ABS would be very boring/difficult if all enemies simply walked randomly/towards the hero all the time, won't it? In this tutorial, I'll show you how to solve this problem and allow guards to "see" the hero and react appropriately.

So, without further ado, let's get started. Here's what you need to know before you read this tutorial:

THINGS THAT YOU NEED TO KNOW:

Experience With and Knowledge of RM2K Commands
Using and Manipulating Switches
Using and Manipulating Variables
Fork Statements
Understanding of the RM2K Coordinate System



Let's start off with a few switches and variables. You can reuse the HeroX...WatchY and Temp variables from the last tutorial if you want:

SWITCHES AND VARIABLES:

1 Switch - "Blocked" (Used Only for Linear Vision)
6 Temporary Variables - "HeroX", "HeroY", "WatchX", "WatchY", "Temp", "Temp2"


Before you read any further, store the Hero's X and Y coordinates in the HeroX and HeroY variables. Do the same for the enemy's coordinates.


Radial Vision



There are many different "vision" systems that you can use in your game. The simplest of these "systems" is probably radial vision, where enemies will respond if the hero gets too close to him/her (the direction doesn't matter). The implementation of radial vision is likewise very simple - you simply have to add the difference between the hero's and the enemy's X and Y coordinates. If the sum is smaller than, say, 7, then viola!

Add another common event to the map from the previous tutorial - all of our code will go in it (or, as an alternative, you can add this to the bottom of the existing common event). We first have to find the absolute value of the difference between the hero's X and the enemy's X coordinate. To do this, we must take the larger variable from the smaller one, like:

<>FORK Optn:Varbl[0001:HeroX]-V[0003] more than
  <>Variable Ch:[0005:Temp] Set, Var.[0001:HeroX]val.
  <>Variable Ch:[0005:Temp] -, Var.[0003:WatchX]val.
: ELSE Case
  <>Variable Ch:[0005:Temp] Set, Var.[0003:WatchX]val.
  <>Variable Ch:[0005:Temp] -, Var.[0001:HeroX]val.
:END Case

Do the same for the Y Coordinates, except use your Temp2 Variable instead of your Temp variable.

OK, since we want to know if the hero is X squares away from the enemy, we must first add Temp and Temp2 together to find the distance between the enemy and the hero:

<>Variable Ch:[0005:Temp] +, Var.[0006:Temp2]val.

Now, if the result is smaller than X, the hero is within the enemy's sight range, and the enemy should act accordingly:

<>FORK Optn:Varbl[0005:Temp]-[i]X[/i] less than
  <>Note: Do Something
:END Case

Replace X with the enem's actual sight range.


Linear Vision



Linear Vision basically means that theenemy will be able to see everything in front of him - nothing more, nothing less. IT involves comparing the X and Y coordinates of the hero and enemy to determine whether the hero is directly in front of the enemy's line of sight. It's somewhat tougher to implement than Radial vision, but implementing vision barriers in this system is much easier than in a Radial system.

I have already explained the coding for Linear Vision in my tutorial, "A Hide-and-Seek Game Where You Hide," but I will recap it here:


SNIPPLET FROM PREVIOUS TUTORIAL: ABS LINEAR VISION

Let's begin by adding a fork statement for when the guard FACES UP.

<>FORN Optn:thisEvent-Up Face Direct

Since the guard can only see in a straight line, the hero's X coordinate must be equal to the Guard's X coordinate for the guard to see him:



Notice the same X Coordinates? OK, so add another fork statement that executes when "HeroX" is equal to "WatchX." Make sure that this fork statement is inside the FaceUp FORK statement!

If the guard is facing up, then he can't see what's below him, right? That means that the Hero's Y coordinate must be smakker than the guard's Y coordinate (remember that Y becomes smaller as you go up). Therefore, let's add another fork statement that detects if the "HeroY" variable is less than "GuardY".

Now, inside all those supa-dupa FORK statements, add the "stuff"(tm) that you want to execute when the guard sees you. For example:

Anyway, do the same for when the guard is facing Left, Right, and Down. Just remember:

FACE DOWN: HeroX must equal WatchX, HeroY must be greater than WatchY
FACE LEFT: HeroX must be less than WatchX, HeroY must equal WatchY
FACE LEFT: HeroX must be greater than WatchX, HeroY must equal WatchY

Now, try this program. It should work...except for one little thing: You can't hide from that blasted Sen...uh...guard! So how do you fix this? Simple! We'll need to add more code inside the fork statements!

Let us look at the mountain in the middle - the stuff that you are supposed to hide behind. It starts at (9,5) and ends at (12,10). Hmm...maybe we could add more fork statements inside the existing fork statements that detect if the watcher's vision is blocked by the mountains...it just might work, right?

Let's go back to the "Facing Up" code, inside the three nested FORK statements. If the watcher's vision is blocked by the mountains, then his Y coordinate should be greater than 10 (meaning that he's below the mountains), and the hero's Y coordinate should be below 5 (meaning that the heor is above the mountains). Let's add two fork statements to express this:

<>FORN Optn:Varbl[0002:HeroY]-5less
<>FORN Optn:Varbl[0004:WatchY]-10abov

The watcher's X coordinate (and the Hero's) should also be between 9 and 12, the X coordinates for the beginning and end of the mountain. Let's add another two FORK statements for this condition (remember that inside this look, the hero's X coordinats is equal to the Guard's X coordinate. Thus, you only need to compare one of them.)

I'll wait...Done? Good! Now, remember our good old switch, "Blocked"? Turn the switch ON inside the nested fork statements, which will tell us that Sen...uh...the guard cannot see the hero - his vision is blocked by the mountains.

After these four inner FORK statements, add another FORK statement that activates when the "Blocked" switch is OFF. Put the [guard battle code/stuff that you want to do when the guard sees the hero] in here.

Repeat this procedure for the other three directions. Just make sure to adjust the FORK statements appropriately.



Partial Radial Vision



Partial Radial vision is a more difficult, but probably more realistic vision system. This system is similar to Radial Vision, except the enemy can only see what's in front of him, not what's behind him or to his sides. In effect, it's similar to a flashlight, where the enemy can only see the areas that the flashlight is illuminating.

PR Vision Systems require a bit of extra coding in addition to the Radial vision code. Let us assume that the enemy is facing right. If the hero is in the enemy's sight range, then Temp2 (the difference between the Hero's and the Enemy's Y coordinates) must be smaller than Temp (same, except it's the difference between their X Coordinates). If you don't believe me, check the diagram on top!

Of course, this is also the case if the enemy is facing left. Thus, you must add ANOTHER FORK statement that checks if the Hero's X coordinate is larger than or smaller than the enemy's X coordinate. If HeroX is smaller than WatchX, then the hero is to the enemy's left. If HeroX is larger, then he is to the enemy's right. If they are the same...well...your damage code is definitely not working.

So, if the enemy's facing:

LEFT: Temp2 < Temp, HeroX < WatchX
RIGHT: Temp2 < Temp, HeroX > WatchX
UP: Temp < Temp2, HeroY < WatchY
DOWN: Temp < Temp2, HeroY > WatchY

Don't worry if you do not understand this portion. Most ABSes use either Radial or Linear vision anyway. This system is for the extremely rare developer who decides that he/she wants to be different.


Enemies that Chase

Believe it or not, I've found that one of the best ways to make enemies chase after you when a flag is activated is to make TWO versions of the same enemy and have the second enemy (who follows the hero) become active when the user gets within the sight range.

You can also use "Move Event, Repeat Action" to change the guard's route...or use a parallel event to move the guard. If you use a parallel event, however, you'll have to modify my code a little bit (make the enemy "Push Key," put the hero attack code in the enemy's pages, and put the enemy collision/damage code inside a parallel event).


Allowing Enemies to Respond to Other Events (Such as Dead Guards)

This is actually very easy to do. Simply copy the code and replace HeroX/HeroY with the coordinates of the "object" and you're good to go :).


I guess that basically covers the basics of ABS Enemy Sight. In my next installment, I'll probably show you how to make long-distance and spells. Until then, I rest my fingers.