Gw Temp

Menu

Tutorial - 'ABS Tutorial Part 4 - Projectiles' by AzureFenrir

An item about RPGMaker 2000 posted on

Blurb

The fourth installment of AzureFenrir's ABS tutorials. This tutorial shows you how to add many different projectile spells (such as firebolt or charged bolts) to an ABS.

Download the accompanying demo project for Part 3, 4, and 5 here: http://staff.whahay.net/AzureFenrir/Tutorial/ABSDemo.zip

Body

ABS Tutorial Part 4 - Projectiles

The fourth tutorial already? I have no life at all...:(

This tutorial coves how you can implement many different types of spells and spell targets. Since this is an advanced tutorial, I will use a bit of pseudocode instead of actual RM2K code and won't explain the coding step-by-step (and sometimes I might not show coding at all). Therefore, you should at least have experience with coordinate manipulation (Part 1) before you read this.

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:

Serious experience with and Knowledge of RM2K Commands
Using and Manipulating Switches
Using and Manipulating Variables
Fork Statements
Cycles and Loops
Experience with using/manipulating 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:

6 Variables - "HeroX", "HeroY", "WatchX", "WatchY", "SpellX", "SpellY"
Additional switches and variables may vary by spell type.


Finally, this tutorial includes a demo project to help you understand code placement, events, etc. The sample project can be found here: http://staff.whahay.net/AzureFenrir/Tutorial/ABSDemo.zip



The Basics of Projectiles

Projectile Spells, or spells that move (FireBolts, Bullets, etc.), usually requires another event to function correctly. That event usually serves as the "bullet" or "spell," and will move in a certain path, damaging enemies that it comes in contact with.

Making the projectile move is as simple as a call to "Move Event" with "Repeat Action" checked. However, detecting whether the spell collided with the enemy is a different matter. Usually, you have to make the bullet "parallel process," and have it continuously check if the spell's coordinates are the same as an enemy's coordinates. In addition, you also have to check whether the projectile collides with a wall and...well, you get the idea.



Straight-Path Projectiles (Normal Projectiles)



Most projectile spells move in a straight path in one direction. These spells are usually the simplest projectile spells to implement, as there aren't any fancy additional code that you need to add.

Before you work on the projectile, you need an event that triggers the projectile to fire. To do that, you'll need to make a new parallel event (I called it "Spellgiver" :P). Inside the parallel event, add a "Enter Password" event, have it wait until key hit, and have it detect the "Decision (5)" key. This will pause the projectile firing until the player pressed Enter.

Now, initialize two variables, HeroX and HeroY, to the Hero's X and Y coordinates:

RPG Maker 2000 Code:

<>Variable Ch:[0001:HeroX] Set, Hero X pos
<>Variable Ch:[0002:HeroY] Set, Hero Y pos


Now, for the projectile movement. There are four directions that the projectile can travel: up, down, left, and right (we won't worry about 8 Direction Movement in this tutorial). As a result, you'll need four FORK statements for when the hero is facing each of the four directions.

RPG Maker 2000 Code:

<>FORK Optn:Hero - Up Face Direct
: END Case
<>FORK Optn:Hero - Down Face Direct
: END Case
<>FORK Optn:Hero - Left Face Direct
: END Case
<>FORK Optn:Hero - Right Face Direct
: END Case


Now, inside the Hero Face UP FORK statement block, we need to add the events necessary for the projectile to move. But before we do that, we need a new projectile event! So...go back to your map and add a new event called Projectile. NOW we are ready to add the code for spell movement.

Before we can move the spell, we need to put the projectile event on the hero so it looks like the Hero casted the spell, not some invisible entity. So...use a Set Event Place to place the event on the hero (usig the HeroX and HeoY variables that we initialized earlier):

RPG Maker 2000 Code:

<>Setup Event Place: Projectile, (V[0001:HeroX],V[0002:HeroY])


Now, we need to make sure that the projectile is activated. To do this, add another variable, call it "PrjtStraightON," and use "Change Variable" to turn the variable ON. After that, use "Move Event" to move the projectile up:

RPG Maker 2000 Code:

<>Change Switch: [0003:PrjtStraightON]-ON Set
<>Move Event: Projectile, Strt SlipTro, Up, StopSlipTrou (Repeat Action)


You may have noticed the SlipThrough that surrounds the projectile event. This will ensure that the spell will actually cross the enemy and not get stuck in front of him/her.

Here's (my) full code for the Spellgiver event:

RPG Maker 2000 Code:




Now, let's work on the projectile collision code. In the new projectile event that you created just a while ago, create a new page and leave the first page blank (after all, you don't want your projectile to keep on running even if you didn't fire it).

On the new second page, check the "Switch" condition and have the page activate when "PrjtStraightON," the new switch that you've created, is ON. Set the start condition to "Parallel Process" - this page will contain the code that detects enemy collision and spell.

The enemy detection code is actually quite simple. It basically stores the projectile's coordinates in two variables, SpellX and SpellY. Then, just compare these coodinates with the enemy coordinates, and if they are equal, then damage the enemy:

RPG Maker 2000 Code:

<>Variable Ch:[0007:SpellX] Set, Projectile X pos
<>Variable Ch:[0008:SpellY] Set, Projectile Y pos

<>Variable Ch:[0003:WatchX] Set, Enemy1 X pos
<>Variable Ch:[0004:WatchY] Set, Enemy1 Y pos

<>FORK Optn:Varbl[0007:SpellX]-V[0003:WatchX] Equivl
    <>FORK Optn:Varbl[0008:SpellY]-V[0004:WatchY] Equivl
        <>Damage Enemy: Enemy1
        <>Play Sound Effect: Damage2
        <>Change Switch:[0003:PrjtStraightON]-OFF Set
        <>
    : END Case
    <>
: END Case

<>Note:Repeat for every enemy on the map.


Did you notice the Change Switch event? It stops the projecile and turns it OFF when it hits the enemy. After all, the spell isn't supposed to pierce right through the enemy, right? Righto.

Of course, we need to reset the spell when it reaches the edges of the map, right? So...let's add something that detects if the spell is near one of the map's edges:

RPG Maker 2000 Code:

<>FORK Optn:Varbl[0007:SpellX]-0
    <>Change Switch:[0003:PrjtStraightON]-OFF Set
    <>
: END Case
<>FORK Optn:Varbl[0007:SpellX]-19
    <>Change Switch:[0003:PrjtStraightON]-OFF Set
    <>
: END Case
<>FORK Optn:Varbl[0007:SpellY]-0
    <>Change Switch:[0003:PrjtStraightON]-OFF Set
    <>
: END Case
<>FORK Optn:Varbl[0007:SpellY]-14
    <>Change Switch:[0003:PrjtStraightON]-OFF Set
    <>
: END Case


So, the full code (for the projectile collision) would look something like:

RPG Maker 2000 Code:




It might seem kind of long, but quite a bit of this could be copied and pasted. And besides, this is one of the reasons why these tutorials took so long to write :P.



Projectiles: The Piercing Effect



Phew! That projectile code could warrant its own tutorial!

Anyway, the piercing effect works exactly as the name implies. The projectile basically damages and flies right through any enemy that it reaches, damaging every enemy in its path.

Add a piercing effect is actually very easy. Just make a projectile spell and remove the "Change Switch" from the damage enemy code so that the projectile doesn't stop when it hits an enemy, but goes right through him/her and continues along its path:

RPG Maker 2000 Code:

<>Variable Ch:[0007:SpellX] Set, Projectile X pos
<>Variable Ch:[0008:SpellY] Set, Projectile Y pos

<>Variable Ch:[0003:WatchX] Set, Enemy1 X pos
<>Variable Ch:[0004:WatchY] Set, Enemy1 Y pos

<>FORK Optn:Varbl[0007:SpellX]-V[0003:WatchX] Equivl
    <>FORK Optn:Varbl[0008:SpellY]-V[0004:WatchY] Equivl
        <>Damage Enemy: Enemy1
        <>Play Sound Effect: Damage2
        <>Change Switch:[0003:PrjtStraightON]-OFF Set
        <>
    : END Case
    <>
: END Case

<>Note:Repeat for every enemy on the map.


I'll recap kust in case if you didn't understand. The "Change Switch:[0003:PrjtStraightON] - OFF Set" turns off PrjtStraightON. Since the projectile code only runs when that switch is on (remember how we set the second page's condition to "Switch [0003:PrjtStraightON] - ON"?), turning the switch off would disable and deactivate the projectile, and turning the switch off in the enemy collision code means that you turn off the projectile when nit hits the enemy.

If you remove that "change switch" statement, the spell will not "turn off" when it reaches the enemy. Thus, it will still do damage, but will otherwise pass right through the enemy, which is what we wanted. Mission accomplished. Yay.



Projectiles: Splash Damage



Splash damage occurs when a volatile projectile hits an impenetrable object (like when a fireball hits and enemy). When the spell hits an object, it explodes in a wondeous yellow flame, damaging all nearby enemies.

The basic projectile code is quite similar to the regular straight projectile code. However, before the projectile resets, it needs to show a "splash damage" animation and execute the radial damage code. So...we'll need to put this code in the "collision with enemy" FORK statements:

RPG Maker 2000 Code:

<>Variable Ch:[0007:SpellX] Set, Projectile X pos
<>Variable Ch:[0008:SpellY] Set, Projectile Y pos

<>Variable Ch:[0003:WatchX] Set, Enemy1 X pos
<>Variable Ch:[0004:WatchY] Set, Enemy1 Y pos

<>FORK Optn:Varbl[0007:SpellX]-V[0003:WatchX] Equivl
    <>FORK Optn:Varbl[0008:SpellY]-V[0004:WatchY] Equivl
        <>Damage Enemy: Enemy1
        <>Play Sound Effect: Damage2

        <>Show Battle Animation: Flare, Projectile(W)
        <>Variable Ch:[0003:WatchX] Set, Enemy1 X pos
        <>Variable Ch:[0004:WatchY] Set, Enemy1 Y pos

        <>Variable Ch:[0009:TempX] Set, Var.[0001:HeroX] val.
        <>Variable Ch:[0009:TempX] -, Var.[0003:WatchX] val.
        <>FORK Optn:Varbl[0009:TempX]-0 less than
            <>Variable Ch:[0009:TempX] *, -1
            <>
        : END Case

        <>Variable Ch:[0010:TempY] Set, Var.[0002:HeroY] val.
        <>Variable Ch:[0010:TempY] -, Var.[0004:WatchY] val.
        <>FORK Optn:Varbl[0010:TempY]-0 less than
            <>Variable Ch:[0010:TempY] *, -1
            <>
        : END Case

        <>Variable Ch:[0009:TempX] +, Var.[0010:TempY] val.
        <>FORK Optn:Varbl[0009:TempX]-5 less than
            <>Damage Enemy: Enemy1
        : END Case
        <>Note: Repeat for every enemy.

        <>
    : END Case
    <>
: END Case

<>Note:Repeat for every enemy on the map.


Of course, what if the spell collided with the walls on the screen edges? Then, it should still explode, right? So, let's add the splash damage code to this:

RPG Maker 2000 Code:

<>FORK Optn:Varbl[0007:SpellX]-0
    <>Change Switch:[0003:PrjtStraightON]-OFF Set
    <>Add the previous splash damage code (in Bold) here.
    <>
: END Case
<>FORK Optn:Varbl[0007:SpellX]-19
    <>Change Switch:[0003:PrjtStraightON]-OFF Set
    <>Add the previous splash damage code (in Bold) here.
    <>
: END Case
<>FORK Optn:Varbl[0007:SpellY]-0
    <>Change Switch:[0003:PrjtStraightON]-OFF Set
    <>Add the previous splash damage code (in Bold) here.
    <>
: END Case
<>FORK Optn:Varbl[0007:SpellY]-14
    <>Change Switch:[0003:PrjtStraightON]-OFF Set
    <>Add the previous splash damage code (in Bold) here.
    <>
: END Case


Now, we have an exploding spell! MWAHAHAHAHA! BLOW UP THE WORLD!!! Sorry...



Projectiles: Scattering on Contact



Spells that scatter on contact are just like regular projectiles. However, whenever they hit a wall or an enemy, they break into smaller projectiles, which shoot off in different directions and may damage even more enemies.

Before you create this effect, you need additional events, one for every "smaller" projectile that you want to make. Now, since the projectile scatters on contact with an enemy or wall, the scattering code should be placed in the collision with enemy FORK statements as well as the collision with wall FORK statements.

First of all, we need to use "Set Event Place" to move the mini-projectiles to where the projectile currently is. This makes sure that the smaller projectiles will start where the projectile event scattered and not arbitrarily in random places on the map:

RPG Maker 2000 Code:

<>Setup Event's Place: Splatter, (V[0007],V[0008])
<>Setup Event's Place: Splatter2, (V[0007],V[0008])
<>Setup Event's Place: Splatter3, (V[0007],V[0008])
<>Setup Event's Place: Splatter4, (V[0007],V[0008])


Now, we need to move the projectiles in their respective directions ONCE to make sure that they don't start ON the enemy. Why is that, you ask? Well, the projectiles will damage any enemy that they hit. if you make them start on the enemy that the original projectile hit, then the projectiles will damage that enemy instead of flying off like they are supposed to do:

RPG Maker 2000 Code:

<>Move Event...: Splatter, Start SlipTro, Right-Up, Stop SlipTrou, Switch-ON
<>Move Event...: Splatter2, Start SlipTro, Right-Down, Stop SlipTrou, Switch-ON
<>Move Event...: Splatter3, Start SlipTro, Left-Down, Stop SlipTrou, Switch-ON
<>Move Event...: Splatter4, Start SlipTro, Left-Up, Stop SlipTrou, Switch-ON
<>Wait: 0.1s.


Did you notice the "Switch-ON" at the end of every event? Well, they correspond to four new switches (which I called "PrjtStraightSplitIM1-4") that will determine whether each of the four scattered projectiles are still active. We turn the switch on AT THE END OF THE MOVE EVENT because we need to make sure that the spell has moved out of the enemy's square before turning on its collision code. Otherwise, if the player's computer lagged a bit, we might have a timing error, and the projectile will end up damaging thatenemy instead of firing.

Finally, we can let the projectiles go off in their respective directions using a repeated Move Event. I don't think I need to explain this:

RPG Maker 2000 Code:

<>Move Event...: Splatter, Start SlipTro, Right-Up, Stop SlipTrou (Repeat Action)
<>Move Event...: Splatter2, Start SlipTro, Right-Down, Stop SlipTrou (Repeat Action)
<>Move Event...: Splatter3, Start SlipTro, Left-Down, Stop SlipTrou (Repeat Action)
<>Move Event...: Splatter4, Start SlipTro, Left-Up, Stop SlipTrou (Repeat Action)
<>Wait: 0.1s.


Now, each of the mini-projectiles need their own collision detection code, right? Well, you could basically used the normal projectile-collision code. Just make sure to change the "Change Variable" events on the top and the "Switch Operations" respectively.



Projectiles: Eight-Direction Fire



Eight-Direction Fire means that when the player casts your spell, 8 projectiles are fired off in eight different directions and can thus strike eight enemies at the same time.

Eight-Direction Fire is actually VERY easy to implement. You just need eight projectiles similar to the ones used for the scatter effect. In addition, you need to use a total of 8 switches, one to control each separate projectile.

Now, the firing "Spellgiver" event will be somewhat different:

RPG Maker 2000 Code:

<>Setup Event Place: Projectile, (V[0001:HeroX],V[0002:HeroY])
<>Setup Event Place: Projectile2, (V[0001:HeroX],V[0002:HeroY])
<>Setup Event Place: Projectile3, (V[0001:HeroX],V[0002:HeroY])
<>Setup Event Place: Projectile4, (V[0001:HeroX],V[0002:HeroY])
<>Setup Event Place: Projectile5, (V[0001:HeroX],V[0002:HeroY])
<>Setup Event Place: Projectile6, (V[0001:HeroX],V[0002:HeroY])
<>Setup Event Place: Projectile7, (V[0001:HeroX],V[0002:HeroY])
<>Setup Event Place: Projectile8, (V[0001:HeroX],V[0002:HeroY])

<>Note:You can just use a "Change Switch: Range 0021-0028" to change all of these in one line of code
<>Change Switch: [0021:PrjtDirect1ON]-ON Set
<>Change Switch: [0022:PrjtDirect2ON]-ON Set
<>Change Switch: [0023:PrjtDirect3ON]-ON Set
<>Change Switch: [0024:PrjtDirect4ON]-ON Set
<>Change Switch: [0025:PrjtDirect5ON]-ON Set
<>Change Switch: [0026:PrjtDirect6ON]-ON Set
<>Change Switch: [0027:PrjtDirect7ON]-ON Set
<>Change Switch: [0028:PrjtDirect8ON]-ON Set

<>Move Event: Projectile, Strt SlipTro, Up, StopSlipTrou (Repeat Action)
<>Move Event: Projectile2, Strt SlipTro, Down, StopSlipTrou (Repeat Action)
<>Move Event: Projectile3, Strt SlipTro, Left, StopSlipTrou (Repeat Action)
<>Move Event: Projectile4, Strt SlipTro, Right, StopSlipTrou (Repeat Action)
<>Move Event: Projectile5, Strt SlipTro, Left-Up, StopSlipTrou (Repeat Action)
<>Move Event: Projectile6, Strt SlipTro, Left-Down, StopSlipTrou (Repeat Action)
<>Move Event: Projectile7, Strt SlipTro, Right-Up, StopSlipTrou (Repeat Action)
<>Move Event: Projectile8, Strt SlipTro, Right-Down, StopSlipTrou (Repeat Action)


Thre's really nothing to it...it's just repeating the events for each projectile that will be fired :).




Projectiles: Random Movement



Random Movement projectiles are interesting projectiles that do not travel in a straight path, but sometimes wobbles to the left and right. If you've ever played Diablo, it's similar to the Charge Bolt spell, which travels in random directions and is thus not very reliable.

You might be thinking, "Oh, that's easy, just set the 'Move Event' to Random Movement!" Actually, it's not that easy. "Random Movement" can create some really weird spells that just wobbles in random directions, doubles back on itself, and...well...looks ridiculus.

Basically, we still need it to travel in the direction that the hero fired it. It just needs to wobble left and right occasionally.

First of all, you need to use the straight projectile code. However, leave out the "Move Event, repeat action" completely - we will move the projectile artificially. Instead, store the hero's direction in a new "SpellDir" variable. We will use this variable to determine the projectile's approximate path.

Now, the spell's collision code is the same as that of a straight projectile. However, add the following at the beginning of the event, before the collision code:

RPG Maker 2000 Code:




As you can see, we used a random number to determine whether the projectile will travel straight in that direction or wobble to one of the sides. This ensures that the projectile at least travels forward, even though it does go in a random path.



Projectiles: User-Controlled Path (Guided Missle)



Guided Missles are projectiles that do not move in a straight path, but do in whatever direction the player wants. The missle can change directions in mid-flight with a touch of a key, and is geneally better for hitting enemies that move a lot.

Guided missles uses the EXACT SAME collision code and trigger code as a regular straight projectile. The only difference is the presence of another Parallel Process/Auto Start event that detects user key input and moves the projectile appropriately. I would recommend that you use the numeric pad for the projectile so that the player can move the hero (if needed). However, if you are using RM2K, then the arrow keys will usually work just as well.

The code is actually quite simple - an Enter Password, and code to change the spell direction:

RPG Maker 2000 Code:

<>Enter Password:[0006:Temp]
<>FORK Optn:Varbl[0006:Temp]-4
    <>Move Event...: Projectile, Start SlipTro, Up, Stop SlipTrou
: END Case
<>FORK Optn:Varbl[0006:Temp]-1
    <>Move Event...: Projectile, Start SlipTro, Down, Stop SlipTrou
: END Case
<>FORK Optn:Varbl[0006:Temp]-2
    <>Move Event...: Projectile, Start SlipTro, Left, Stop SlipTrou
: END Case
<>FORK Optn:Varbl[0006:Temp]-3
    <>Move Event...: Projectile, Start SlipTro, Right, Stop SlipTrou
: END Case


You can make this an Auto Start event if you don't want the enemy to move while the user is guiding the projectile. Otherwise, you can make this a parallel event, and add a label so that the Hero won't move with the spell.


Don't forget that you can download the accompanying demo to this tutorial (and the one before and after it) here: http://staff.whahay.net/AzureFenrir/Tutorial/ABSDemo.zip!

Well, that's all for projectiles (and one moving spell *sigh*). In my next ABS tutorial, I shall reveal to you the secrets of enemy targetting, as well as bestow upon thou the ancient knowledge of targetting! YES! Teh world sahel soen bi mien!

*AzureFenrir is assassinated again by GW Members*