Charas-Project

Game Creation => Requests => Tutorials => Topic started by: Sephiroth rocks on April 13, 2006, 09:05:04 PM

Title: Making interactive caves and dungeons
Post by: Sephiroth rocks on April 13, 2006, 09:05:04 PM
When making caves and dungeons good map making is of course very important, but something as important but often overlooked is the cave's interaction with the user. A cave where you as the player won't have to do anything to get through other than fighting creatures quickly bores the player yet many make their caves like this. Interaction with the player makes the cave more challeging and exciting. Interaction with the player means that he/she has to do something other than walking and fighting, like avoiding traps or jumping over pits. In this tut I'll show an example of making pitfalls/spikes and jumping where the player has to bash the action key in order to jump over a pit.

Pitfalls/spikes
Pitfalls and spikes are pretty similar to make so I've put them under the same category. In this tut I've we'll be making one event for each trap and one parallel process event controlling them. Before you decide to make traps in a cave remember to have a good reason to why there should be traps. If it's an often-used passage it wouldn't make sense to place traps, but if it's a secret hideout then it'd add to the flavor.
First if you want to make the player aware of the traps you could place many traps but show them like holes where the spikes come up from or different colored tiles indicating a pitfall. This works best with spikes since you shouldn't be able to avoid them anyway (not nessecarily meaning that you get hit by them). Now for the coding:

1. Make an event. Leave the first page blank and add a new page. Make a new switch called 'Traps On' and set the precondition as "Switch Traps On is on". Set the event trigger as 'Touched by Hero' and the event graphic as the trap as you want it to look when activated.

2. Code the consequenses for activating the trap. If it's a spiketrap your characters should lose HP. That's done like this:
Flash the hero sprite to red for one second halting other processes. Then make a new variable called 'Random HP loss' and set it to a random value. Since this variable represents the characters's HP loss due to the spikes it should be set to a low value if the cave is at the beginning of the game and to a high value if it's at the end of the game and your characters has more HP. Then decrease all characters's HP by the value of the variable.
If the trap's a pitfall it should teleport the heroes to another map that map being the pit they fall into. In the pit you could place anything; a hungry monster or a treasure chest. And of course make sure that the player can reach the cave again from the pit. This consequence is done like this:
Make some events (four or five). Set their precondition as "switch 'Traps On' is on" and their layer as above hero. The graphic should be the same as the tiles used for the floor. Then back at the trap's event play a fall SFX, increase the hero's speed with four or five times and move the hero down the same amount of steps as you've placed of the foreamentioned events so that it looks as though the hero is falling down. Remeber to slow down the hero's movement speed aswell. Then teleport the hero to the map of the pit.
This will make sure that the hero suffers the consequences of the trap if he walks on it while it's activated.

3. Make a parallel process event. Set label 1 at the top of its coding. Then set a wait. Since this wait represents the interval between the traps's activation you could either set it short and have few traps or set it long and have many traps. Then play an SFX that sounds like a handle is toggled or something similar that sounds as the traps are supposed to sound when they trigger.  Then turn switch 'Traps On' on and memorize the hero's location using variables 'HeroMapID', 'HeroPosX' and 'HeroPosY'. Now make a branch for each horizontal tile where there are traps. Set the branches's trigger conditions as "If 'Hero Pos X' is equal to X" where X is the current horizontal tile where there are traps. Then place branches inside of the other branches, one for each trap with the current horizontal position. Inside these branches make the same consequenses as in the trap events.
At the end of the event turn switch 'Traps On' off and jump to label 1.
This activates the traps and makes sure that the hero suffers the consequences of the trap if he's already standing on it when it activates.

In coding it should look like this:

Trap events:
Page 1
Precondition: None
Trigger: Action Key
Graphic: None
Coding:
<>

Page 2
Precondition: Switch 'Traps On' is on
Trigger: Touched by Hero
Graphic: As the trap should look while activated.
Coding:
Spikes:
<>Flash Sprite: Hero, 1.0 Sec (wait)
<>variable Operation: [####: Random HP Loss] Set, [X-Y]
<>Change HP: Entire Party, Var Random HP Loss remove
<>
Pitfall:
<>Play Sound: Fall
<>Move Event: Hero, Increase Speed, Increase Speed, Increase Speed, Down, Down, Down, Down, Decrease Speed, Decrease Speed, Decrease Speed
<>Teleport: Pit
<>

Trap Control event:
Precondition: None
Trigger: Parallel Process
Graphic: None
Coding:
<>Label 1
<>Wait X.X sec
<>Play Sound: Traps
<>Switch Operation. [####: Traps On] ON
<>Memorize Location [####: HeroMapID], [####: HeroPosX], [####: HeroPosY]
<>Branch: If var HeroPosX is X (Repeat for each horizontal tile with traps)
 <>Branch: If var HeroPosY is Y (Repeat for each vertical tile with a trap at the current horizontal position)
 <>//Consequence
 <>End
<>End
<>Wait: X.X Sec
<>Switch Operation: [####: Traps On] OFF
<>Jump to label: 1

Jumping over pits
In this tut we'll make the hero able to jump above a pit, hole, river, etc. The lenght of the jump is determined by how many times the user can press the action key in a certain amount of time. If the hero jumps too short a consequence should happen. In this tut the hero jumps to the left but of course he could be jumping to any other direction aswell. As for the coding:

1. First open the charset you use for the main hero in Idraw (or any other program but I recommend Idraw) and make a duplicate of it where you change the hero to have the same graphic for each direction using the middle pattern.

2. If the tiles the hero should be jumping above are normally inpassable, open the chipset and duplicate the tiles the hero will be jumping above not modifying anything.

3. In rm2k/3 import the charset and chipset and set the duplicated tiles at the chipset to be passable. Then make an event at the spot from where the hero should jump and make blank events on the inpassable tiles surrounding that spot. The inpassable tiles in the jump route should then be changed to their passable counterparts. Make two new switches called 'TileCluster1' and 'TileCluster2'. Then set the surrounding events's preconditions as "Switch 'TileCluster1' is on" and their layer as 'Same as Hero'. Then set the event at the jumping spot to 'Touched by Hero'. At the beginning of the event turn switch TileCluster1 and 2 off. Then set Timer 2 to the amount of time you want the player to have to bash the action key. Start the timer not showing it onscreen and set label 1. Make two new variables called 'PrevousKeyPress' and 'CurrentKeyPress' and make a key input processing. Uncheck the "Wait until key is pressed" box and check the "Decision Key (5)" box. The input reciever variable should be 'CurrentKeyPress'. Then make a branch and set the statement to "If var CurrentKeyPress is unequal to var PrevousKeyPress". Inside that branch make another branch and set its statement to "if var CurrentKeyPress is unequal to 5". Make a new variable called 'Jump Speed'. Inside that branch increase variable Jump Speed with one and set variable CurrentKeyPress to 0. The first branch ensures that the player can't simple hold down the action key and the second branch checks if the user pressed the right key.

4. Outside the branches, make a branch with statement "If timer 2 is 0 min 0 sec or less". Check the "Execute else handler if condition not met" box. Inside the branch stop timer 2 and create a new variable called 'Jump Destination' and set it equal to variable Jump Speed. Then play a jump sound effect and change the hero's sprite association to the edited edition you made so it look as though he's jumping not walking. Increase the hero's movement speed by 3 or 4 and move him up/left. Then make a branch with statement "If var jump speed is less than X" where X is the amount of tiles the hero should jump to reach the other side subtracted with two. Check the "Execute else handler..." box. Inside that branch make a loop. Inside that loop make a branch with statement "If var Jump Speed is more than 0" and check the "execute else handler..." box. Inside that branch move the hero to the left and subtract variable Jump Speed with one. At the else handler break the loop. At the else handler for the "If var jump speed is less than X" branch move the hero X tiles. Then outside the branch move the hero down/left and decrease his movement speed with 3 or 4. Then place another branch with statement "If var jump Destination is less than X" checking the "Execute else handler..." box. In that branch place the consequence for jumping too short (e.g. falling down into the pit, game over or, if it's lava or fire, lose life). Remeber to reset all variables. At the else handler show a message like "N[1]: We made it!" and change the hero's sprite association to the normal one. Reset all variables and turn switch 'TileCluster2' on.
At the long-forgotten else handler for the "If timer 2 is 0 min 0 sec or less" branch set variable PrevousKeyPress equal to variable CurrentKeyPress and jump back to label 1 in order to recieve new input.

5. If you want the hero to be able to jump back to the other side of the pit again duplicate the event changing the jumping direction. But this could be a good way to cut off the hero from the past area.

The coding as it looks in rm2k3:

<>Switch Operation: Switch [####:Tilecluster1] OFF
<>Message: Bash the acion key to jump
<>Timer 2 Operation: Set, 0 min X sec
<>Timer 2 Operation: Start
<>Label: 1
<>Key Input Processing: [####:CurrentKeyPress]
<>Branch: If var CurrentKeyPress is unequal to var PrevousKeyPress
 <>Branch if var CurrentKeyPress is unequal to 5
 <>Variable Operation: Jump Speed, +1
 :End
:End
:End
<>Branch if Timer2 is 0M 00S equal to or less
 <>Timer 2 Operation: Stop
 <>Variable Operation:Jump Destination set equal to variable Jump Speed
 <>Play Sound: Jump
 <>Change Sprite Association: Hero1, Jumping
 <>Move Event: Hero, Increase Speed, Increase Speed, Increase Speed, up/left
 <>Branch: If var Jump Speed is less than X
 <>Loop
 <>Branch if var Jump Speed is 0 or more
 <>Move Event: Hero, Left
 <>Variable Opeation: Jump Speed, -1
 :Else Handler
 <>Break Loop
 :End
 :End Loop
 :Else Handler
 <>Move Event: Hero, X times Left
 :End
 <>Move Event: Hero, Down/left, decrease speed, decrease speed, decrease speed
 <>branch: if var Jump Destination is lesser than X
 <>//Consequence
 <>Change Sprite Association: Hero1, Hero1 normal
 <>Variable Operation: CurrentKeyPress, Set 0
 <>Variable Operation: PrevousKeyPress, Set 0
 <>Variable Operation: Jump Speed, Set 0
 <>Variable Operation: Jump Destination, Set 0
 :Else Handler
 <>Message: "N[1]: We made it!"
 <>Change Sprite Association: Hero1, Hero1 normal
 <>Variable Operation: CurrentKeyPress, Set 0
 <>Variable Operation: PrevousKeyPress, Set 0
 <>Variable Operation: Jump Speed, Set 0
 <>Variable Operation: Jump Destination, Set 0
 <>Switch Operation: [####:TileCluster2] ON
 :End
:Else Handler
 <>Variable Operation: PrevousKeyPress set equal to variable CurrentKeyPress
 <>Jump to Label: 1
:End
<>
Title:
Post by: MSlash67 on April 13, 2006, 09:12:22 PM
Damn this is nice. I ought to try it. :bend: