Enemy running from character on map

UnknownQED

Villager
Member
Joined
Jan 15, 2019
Messages
10
Reaction score
1
First Language
English
Primarily Uses
RMMV
I want to make a dungeon/puzzle where there are a series of rooms with a door on all four sides and the boss is in the center of one of the rooms. When you enter the room, if the boss is there, he then runs from the player, exiting the opposite door. Additionally, these rooms are not adjacent on the map (I'm doing some weird perspective messing stuff) so when the boss reaches a door, I need to do a transfer event to place him in the correct room.

Obviously, none of this is too complicated. What I'm wondering is: is there a simple way to do this? My thought right now is have four common events: one for the boss moving in each direction. Then, have a common event for each room to transfer the boss to that room. On all of my transfer events between rooms, I can check if the player and boss end up in the same room. If they do, call the appropriate common events to move the boss and transfer him to the right room. This...seems a little ugly, but with copy and pasting is doable.

I'm also wondering if there's a way to do this with an autorunning event and regions. I imagine it would being if player region = boss region but the body gets gross fast (four conditionals to determine how the boss runs from the player, plus boss direction and region being used to determine where to transfer the boss).

I'm still new, so I'm betting there's a clever solution using tools I haven't thought of.

Thanks!
 

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,342
Reaction score
564
First Language
Italian
Primarily Uses
RMVXA
If I am not mistaken there is an option to let the event run away from the player regardless of his/her direction. Instead of using all those events having just the boss event as a parallel process that checks which region the player is on and then handle everything else (boss running and event transfer) looks like a much better option.

You could set each room entrance to have the same region ID and check if the player is standing on a tile with that ragion ID. If that's the case you let the boss run in the opposite direction (run away from player) then transfer the event once the event itself is standing on a region with said id (marking the entrance/exit to the room).
 

Pyrathas

Veteran
Veteran
Joined
Jul 8, 2018
Messages
91
Reaction score
29
First Language
English
Primarily Uses
RMMV
Yanfly's Region events might help too.
 

UnknownQED

Villager
Member
Joined
Jan 15, 2019
Messages
10
Reaction score
1
First Language
English
Primarily Uses
RMMV
Heirukichi: that's a great idea! But there's one complication I see. How do I handle which room the boss moves to? It should depend on what room he's currently in and what doorway he reached, but I can't think of a simple way to encode that in what you outlined. Worst case I can do a brute force (if boss location is x, y then move here. Else if boss location is x', y' then move there, etc), but I'm hoping to find something a little smoother and easier.

Pyrathas: Thanks. I looked at it, but this is my first project, so I'm trying to restrict myself to no plugins or outside tile sets. Basically, learn the tool and what's there first. This might be a dumb restriction :)
 

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,342
Reaction score
564
First Language
Italian
Primarily Uses
RMVXA
In my opinion it is not a dumb restriction if you do not know what the engine has to offer yet. However HOW to move him is something that really depends on your map structure. For example there might be some sort of relation between one room and the next one (16 tiles in the direction you are facing and 3 tiles on the right for example). If that is the case new coordinates can be obtained using just simple math.

If you are not able to find a formula that keeps direction and new coordinates into account then you have to go the hard way and set the final destination using conditional branches.

However a definitive answer is not possible without looking at the map itself.
 

UnknownQED

Villager
Member
Joined
Jan 15, 2019
Messages
10
Reaction score
1
First Language
English
Primarily Uses
RMMV
The map is six square rooms that actually form the faces of a cube. Because of this, there's never going to be a consistent "move n spaces over" kind of rule. But, I did realize a good solution! When I do the transfer events, I don't put the player at the door, but rather one square away. This means I can set that square to have region "7". Then, I can set the region at the door to be 1-6, indicating where the boss moves to. So, the boss's process would look like:

if (player in region 7):
move away from player n times
if (boss in region 1):
move to face 1​
if (boss in region 2):
move to face 2
Etc. This way I only need six conditional statements.

The overall goal will be to push the boss to a specific face (say, 6), then go to the opposite face (1) and drop pillars, trapping him. The player drops down a hole, and now since the boss can't flee he fights you. This unfortunately means that the boss transfer to face 6 (and possibly 1) will be more complicated since I need to deal with if the pillars are there or not, but I that should just be a couple more conditionals. Annoying, but doable (if the pillars are there, I'll probably just move the boss to a random face or something).

Thanks for the help!
 

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,342
Reaction score
564
First Language
Italian
Primarily Uses
RMVXA
If you want to do something even better you could try the script call way. When using Control Variable use the "script" option to put something like this:
Code:
[[x1, y1], [x2, y2], [x3, y3], [x4, y4], [x5, y5], [x6, y6]]
Instead of x1, y1, x2, y2, etc you have to place your X and Y coordinates for face 1, face 2, face 3, and so on.
This way once you store player region ID in a variable you can use the Script command in the 3rd page of your events to transfer directly to the right face without having to use any if statement at all.

Code:
var character = $gameMap.event(id) // put your boss event id instead of id
var coordinates = $gameVariables(coordinates_var_id)[$gameVariables(region_var_id)]
// change coordinates_var_id to be the id of the variable you used to store coordinates
// change region_var_id to be the id of the variable used to store player region id
character.setPosition(coordinates[0], coordinates[1])
// coordinates[0] refers to x, coordinates[y] refers to y
In the following example I will be using variable 3 to store region ID and event 1 as my boss event. Those coordinates will then be stored in variable 4.
Code:
var character = $game_map.events[1] // <- my boss event id
var coordinates = $gameVariables(4)[$gameVariables(3)]
character.setPosition(coordinates[0], coordinates[1])
As you can see the finished code is much shorted than the one I used to explain. You can even remove the part "// <- my boss event id" since that one is a comment and it is only meant to explain things. It will not run when the string is evaluated so feel free to remove it if you find it disturbing.

If you put this in your event then you don't need an if-else statement at all.

This can be done without using Control Variable at all and just using the Script command in the 3rd page of your event. However this is a better option to learn how to use RM tools in my opinion.

EDIT 1:
Another possible solution might be using 12 different subsequent variables to store your coordinates when setting up your map using an Autorun event.

The most important part here is that you remember the 1st variable ID since all of them come right after that.

If, for example, your first variable is variable 6 then the other ones will be 7, 8, 9, 10, 11, ... , 16, 17.

Then those with an even ID can store your X coordinates and those with an odd ID can store your Y coordinates.

The way to access those coordinates is quite simple. X coordinate for each face will be (1st_variable_id + 2 * (face_id - 1)). In my example, since my 1st variable was 6, my X coordinate for face 3 would be (6 + 2*(3-1)) = 10.

This means I can check my variable[10] to get that X coordinate. Y coordinates are even easier to obtain once you have your X coordinate because the variable right after the one storing X coordinates is its relative Y coordinate.

Its formula would be something like this: (1st_variable_id + 2(face_id - 1) + 1).

I admit that it might look easier to use (2nd_variable_id + 2(face_id - 1)) but in reality it is not.

Once you set your variables this way you can use a script command in your event to move the boss.
Code:
var character = $gameMap.event(your_boss_event_id) // change this with the boss real id
var faceXyId = $gameVariables(the_one_where_you_stored_region_id) // change this to be the id of your real variable
var var1Id = yout_1st_coordinates_variable_id // change this to be your real id (in my case it was 6)
var varX = var1Id + 2*(faceXyId - 1)
character.setPosition($gameVariables(varX), $gameVariables(varX + 1))[/SPOILER]
Let's assume your boss event is event 1 and the variable used to store region id is variable 3. Using the variables in the previous example to store coordinates my code would look like this:
Code:
var character = $gameMap.event(1) // <- this is my boss event id
var faceXyId = $gameVariables(3) // <- the one storing my region id
var var1Id = 6 // <- 1st variable used to store coordinates
var varX = var1Id + 2*(faceXyId - 1)
character.setPosition($gameVariables(varX), $gameVariables(varX + 1))

EDIT 2:
Just to let you know the option of storing everything in an array variable (the very 1st one in this post) is slightly more efficient. However having only 6 places where the boss can be moved it does not really make any noticeable difference.

EDIT 3:
This unfortunately means that the boss transfer to face 6 (and possibly 1) will be more complicated since I need to deal with if the pillars are there or not, but I that should just be a couple more conditionals. Annoying, but doable (if the pillars are there, I'll probably just move the boss to a random face or something).
This is not true. You can use the same system you used to move the boss to move those pillars. You place the event in a place the player cannot reach and then move it only when the player meets those conditions.
Using the method listed above you could even create a set of coordinates for those pillars and then use a random generated number to determine which face of your cube is the right one. This makes the dungeon itself different each time the player starts a new game.

P.S. Using a different region ID for each different face of your cube was a very smart choice.
 
Last edited:

UnknownQED

Villager
Member
Joined
Jan 15, 2019
Messages
10
Reaction score
1
First Language
English
Primarily Uses
RMMV
Thank you! That's a great solution with the script. I knew I was missing something like that, which is why I came here. Really straightforward and simple answer. Also, I'm not afraid of coding since that's my day job :) Though, awkwardly, I've never used JavaScript before.

For the pillars, my real concern is if they're currently raised and you chase the enemy into the room, I can't place the enemy in the middle of the room: he'd be trapped in the pillars (logically, he couldn't get in, and in practice it would make the puzzle too easy). So then it's a question of where to place the enemy if not the middle of that face. I see this as more of a "brainstorming game system" then implementation issue. Unless I'm mistaken by what you're suggesting, which is very possible!
 

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,342
Reaction score
564
First Language
Italian
Primarily Uses
RMVXA
@UnknownQED I made a mistake when writing that script call and I wrote it in ruby instead of JavaScrpt. I'll correct it using JavaScript code right now. Be sure to check the new updated version before using it. Unfortunately if you put the ruby one in your MV event it is not going to work at all.

However there is something I do not understand. Did you not say that pillars are used to trap the boss by chasing him in the right room and then moving to another room? How can they be there before you activate them?

EDIT:
I changed the code to be in JavaScript. Be aware of the fact that I might have missed something so you would better check it when using it or write it using mine as reference instead of copy/pasting. Unfortunately when correcting something like this mistakes can still slip through your guard. Not to mention the fact that I have a strong conflict between different languages so it is very hard for me to find mistakes if they are written in a way that works for at least one of those languages...my brain somehow sees them as "correct".

I am sorry for that mistake but I completely forgot this was a(n) MV thread as I was reading other Ace threads and instinctively wrote the code in ruby.
 
Last edited:

UnknownQED

Villager
Member
Joined
Jan 15, 2019
Messages
10
Reaction score
1
First Language
English
Primarily Uses
RMMV
Thanks for the heads up! I really appreciate all the help. I've been busy the last couple days, but I'm hoping to try out the code tomorrow night.

My thought for the pillars is you chase the boss to room 6 (say, but entering room 5 from the correct direction). The boss is now in the middle of room six. You then go to room 1 which has a circle of pillars sticking out. You flip a switch, and the pillars drop into the floor. At the same time, pillars rise in room six (think of it as longer pieces in a cube; if you make them flush with one face they stick out the other side). You can then drop through a hole in room 1 to fall "through" the cube into room 6. Now, both you and the boss are surrounded by the pillars so he can't flee from you, and then the fight starts. My thought is the pillars are just going to be events with two pages; one page is the pillar, and the other is a blank through event, and the page is determined by a global switch.

Does that all make sense?
 

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,342
Reaction score
564
First Language
Italian
Primarily Uses
RMVXA
Yes, it does. And you were crystal clear in your explanation giving me a very good image of how your rooms are. Unfortunately I am afraid you will have to handle this exception as...an exception. Unless you want to code your whole movement using regions you have to move your boss around those pillars. While there might be a fast solution when you enter the room from the left or right door (from the boss point of view) and entering from the front requires no exception handling at all, entering from the door behind the boss means the boss will no longer be able to move having his path blocked by pillars.

If you do not want to write multiple conditional branches you can just go with something like this:
Code:
> check player coordinates and event coordinates
> if at least one coordinate is the same means that you are in the front/behind situation.
  > compare the difference between the coordinate that does not match with half the room width
  > if the difference is smaller than half your room size then you are behind the boss (worst possible exception)
    > move the boss half way around the pillars (e.g. if your square of pillars is 5x5 that would be 3 times left and 3 times up)
  > endif (coming from the front door is not an exception so no else branch)
> endif (now your boss is in a "side" position)
> if both coordinates are different it means that you are in a "side" position (left/right)
  > move the boss half way around the pillars
  > move X steps in the same direction the player is facing (in my example that means 3)
  > move toward the center of the room (in my example that means another 3 steps)
> endif (now your boss is on the other side of the pillars and free to move)
> move away from player as usual
Important Note: if the boss is right in the middle of the room and at least one coordinate is the same it just ignores everything above the last move route so it is fine to run this in all rooms.

The only annoying part is that you have to move using a direction that is directly related to your player direction so you have to use a bit of JavaScript if you want to avoid using too many conditional branches.

I used pseudocode here because you can do everything but the relative movement with both event commands and JavaScript lines so it is up to you which one you want to use.

Code:
$gamePlayer.direction() // this is how you access your player direction
var character = $gameMap.event(boss_event_id)
character.moveStraight(your_direction_goes_here) // this is how you move your event given a certain direction
character.setWaitMode('route') // if I am not wrong this is how you set the "wait" option for the move route
I only listed the script calls you absolutely have to use. Everything else is just a bunch of flow control elements and simple calculations, I am sure you do not need my help for those.
 
Last edited:

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

I really need to stop thinking there are new freebies just because someone made a new post in the freebies subforum lol.
AND just like that..... I got STEAM DLC up and working! YES!
Game making is like a marathon, except the last 1/4 is more like sprint... a very long and intense sprint.
Finally got to finish the demo for my project!
Another week has gone by. Maybe you made changes to your project/s. Maybe you didn't. Nonetheless, THAT IS NO EXCUSE TO NOT BACK THEM UP O_O!

Forum statistics

Threads
93,441
Messages
912,445
Members
122,968
Latest member
Paitshens
Top