Moving all Events on the Map

Robert-Character Creator

Waiting for Replies
Veteran
Joined
Feb 8, 2014
Messages
518
Reaction score
223
First Language
English
Primarily Uses
RMVXA
Hello, everyone. I'm working on a perspective system for my game wherein a button is pressed, switching to a rotated map and parallax, and moving the events accordingly to match their previous locations, followed by a 90 degree rotation in each event. However, I can't seem to find a way to move every event simultaneously; I could always use the Set Event Location with an X and Y variable for individual events, but there's a massive number of events on any one map. Not only is this a waste of variables, it's tedious in general.

Is there any way, eventing, scripting, or otherwise, to effect multiple, if not all, events at once?

Thank you in advance for any help you can give me with this issue.
 

bhindi1224

NOT Indian Okra
Veteran
Joined
Sep 19, 2017
Messages
295
Reaction score
168
First Language
English
Primarily Uses
RMMV
Couldn't you set event location using a formula? With a tiny bit of math you could probably determine where they are supposed to be from where they are.

Edit: I wish I knew scripting, you could probably use a for loop and set them all with just one function.
 
Last edited:

Robert-Character Creator

Waiting for Replies
Veteran
Joined
Feb 8, 2014
Messages
518
Reaction score
223
First Language
English
Primarily Uses
RMVXA
Not directly, no. You can only use Set Event Location to a specific spot, to coordinates based on variables, and by switching with another event.

I'm certain I can get around the 90 degree issue with a formula and a Script Call, but I'm not sure about performing to all events on the map. Perhaps this should be moved to script support? I'm not sure.
 

bhindi1224

NOT Indian Okra
Veteran
Joined
Sep 19, 2017
Messages
295
Reaction score
168
First Language
English
Primarily Uses
RMMV
I mean having one event run a script that polls the x and y position of each event on the map and then sets them to the new location that is determined by a formula on their current location. I thought I had seen somewhere on these forums an event that located all the other events on a map, perhaps I'm mistaken.
 

Robert-Character Creator

Waiting for Replies
Veteran
Joined
Feb 8, 2014
Messages
518
Reaction score
223
First Language
English
Primarily Uses
RMVXA
If there is something like that, I haven't seen it.

Edit: I feel I need to give some visual context, to help anyone picture what I'm asking for help with.

Third_Floor_Test_Blank_North_Concept.png

In the spoiler is a display image I made of one of my test maps, combining both the floor and the overlaying walls, as well as a rotated version of the same map, without the wall overlay. When rotating the map, any event will need to be moved to its corresponding location in the other map. These are not equidistant from one another; each event needs to be moved an independent distance. This could be covered by using a script call using a formula, I think. I'm not sure how else to do it, it cannot be done manually with any events that move, of which there are 10+ at any one time. By rotating the map, the player can see previously hidden details and items, and is integral to the game's design. I know how I can rotate the map and overlay by using parallax mapping techniques; it's the events themselves causing me issues.

Unless a miraculous eventing-based solution appears, this will almost certainly need to be moved to the script support, or request, forum.
 
Last edited:

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,421
Reaction score
596
First Language
Italian
Primarily Uses
RMVXA
For what I can see you have to set your event x as its y coordinate and your event y as x coordinate. If I got it right then you can use this:
Code:
Graphics.freeze #this freezes your screen until everything changes.
$game_map.events.each do |event|
  event.moveto(event.y, event.x)
end
Graphics.transition(1) #this  operates a fast transition to the new appearence once the
This works if the new map overwrites the previous one.
If the two maps are both part of the same map then you have to use a different method and a switch. Fill me with more details about HOW you rotate your map and I'll be able to provide more help.

EDIT: it goes in a script call.

EDIT2: if you have both maps as part of the same map then you should use a change of axis. The 1st square in your 1st map is of course the square with coordinates (0, 0) but that's relative to your x and y. Let's create a new X which origin is y = N instead of y = 0. You will have a new XOy cartesian coordinates system instead of the usual xOy. Use a switch (or a variable) to tell the engine if you are in xOy or in XOy then add or subtract N to your final event.x coordinate according to your switch value (if you use a variable you can change it to be either 1 or -1 and just multiply N for that value). This will automatically adjust your events.
 
Last edited:

Robert-Character Creator

Waiting for Replies
Veteran
Joined
Feb 8, 2014
Messages
518
Reaction score
223
First Language
English
Primarily Uses
RMVXA
Ah. My current setup involves parallax mapping, as doing it with traditional mapping techniques was nigh-impossible. I'm using http://www.rpgmakercentral.com/topic/676-dmo-liquid-parallax-script/. See, I don't actually rotate the map. I have 4 copies of the map saved in the Parallax folder, each with a different orientation. When completed (still a WIP), I'll be able to activate a common event via key-press, which will change the background image to the next clockwise rotation. When this occurs, the overlay image will also be switched to the corresponding rotated version. All events need to be moved, which is the focus here, and then all commanded to turn 90 degrees clockwise, orienting themselves with the room properly.

Third_Floor_Test_Mess.png

I don't believe that simply swapping x and y will work. In some areas it appears to work, in others, not. I'm not sure actually.

Edit: I figured out why swapping x and y will not work in this case. If you picture VX Ace to be like a quadrant plane, then maps are in Quadrant IV. Swapping x and y does work, but only around (0,0). Because VX Ace has only the one quadrant to work with, I'm rotating around a center point somewhere in the image. The formula would be to swap the distance of x and y from the center point?
 
Last edited:

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,421
Reaction score
596
First Language
Italian
Primarily Uses
RMVXA
I don't believe that simply swapping x and y will work. In some areas it appears to work, in others, not. I'm not sure actually
That's how 90 degrees rotation works. It doesn't work if those events that should be invisible due to perspective are not actually invisible but are placed in a way the player can see them instead.

Example: if a wall is 2 tiles high and there is an event behind it from the frontal view it should be invisible but it should be visible when changing to side view. If your event is not actually hidden behind your wall but, instead, you placed it on the tile at the top of that wall to make it visible the effect you get after rotating your map is that of something not working properly.

In which cases it doesn't work? Can you provide a screenshot of your map with events inside it before and after rotating it?
 

Robert-Character Creator

Waiting for Replies
Veteran
Joined
Feb 8, 2014
Messages
518
Reaction score
223
First Language
English
Primarily Uses
RMVXA
Edit: I figured out why swapping x and y will not work in this case. If you picture VX Ace to be like a quadrant plane, then maps are in Quadrant IV. Swapping x and y does work, but only around (0,0). Because VX Ace has only the one quadrant to work with, I'm rotating around a center point somewhere in the image. The formula would be to swap the distance of x and y from the center point?
Just making sure you see this.
 

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,421
Reaction score
596
First Language
Italian
Primarily Uses
RMVXA
Just making sure you see this.
You did right, I had missed it already. Anyway rotation in a different cartesian system is possible and it follows the same rules I said for the change of axis.
The 1st square in your 1st map is of course the square with coordinates (0, 0) but that's relative to your x and y. Let's create a new X which origin is y = N instead of y = 0. You will have a new XOy cartesian coordinates system instead of the usual xOy. Use a switch (or a variable) to tell the engine if you are in xOy or in XOy then add or subtract N to your final event.x coordinate according to your switch value (if you use a variable you can change it to be either 1 or -1 and just multiply N for that value). This will automatically adjust your events.

For more specific formulae I should know what point that is. For what I can see your rotated map seems to be slightly smaller (1 less row and 1 less column) than the original one. At least from your screenshot. Howevef after reading everything I realized that your parallax image is not placed in the (img_width/2, img_height/2), am I right? If that's the case you require a bit of math too but the event structure will stay the same. The only thing that you have to change is the new x and y value according to the new formula.

As I said the rotation point is absolutely required to create the required formula. Can you tell me which point that is?
 

Robert-Character Creator

Waiting for Replies
Veteran
Joined
Feb 8, 2014
Messages
518
Reaction score
223
First Language
English
Primarily Uses
RMVXA
Give me a moment. Part of the issue is that the image is not measured exactly. I'll trim off the extra pixels and give you an answer.

Edit: Here you are, the updated image. It's 1921x1921, so the center point should be (961,961).

Third_Floor_Test_Base_2.png

Third_Floor_Test_Base_West.png
 
Last edited:

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,421
Reaction score
596
First Language
Italian
Primarily Uses
RMVXA
There is just one more thing I need to know: how big is your map? (in squares) It is bigger than 60x60, isn't it?
 

Robert-Character Creator

Waiting for Replies
Veteran
Joined
Feb 8, 2014
Messages
518
Reaction score
223
First Language
English
Primarily Uses
RMVXA
Sorry for the delay; I live in America, so I had to sleep. It says you replied at 4:30 in the morning, haha.

The map should be 59x59, but I'm rounding it to 60, yes. I don't think it'll cause an issue. I don't need it any bigger than 60x60 at the moment.
 

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,421
Reaction score
596
First Language
Italian
Primarily Uses
RMVXA
Don't worry, everyone has to sleep. I'd like to stay awake my whole life bot if I stay awake for too long without sleeping I am unable to accomplish even the easiest thing so I can feel your pain.

However back to work. We were going to create our cartesian system. However it is better if the central point of your image is also the central point of a square. Having it somewhere else requires more calculations. Let's say you have your normal xOy system and you create a new sistem XNY with N = (Xn, Yn). This point (N) is the central square I am talking about. Its coordinates have to be something like this (pseudocode):
  • Xn = (ParallaxImageWidth / 64) <- division between integers always return integers.
  • Yn = (ParallaxImageHeight / 64) <- this is an integer as well.
Now you have two integers. These are grid coordinates of your N. Keep in mind that even if its grid coordinates are integers you should have your parallax image center that is the center of your square as well.

Rotating your image changes the coordinates of everything standing on it using the following formula (in the new cartesian system):
If P is your original event position and Pn is your event position after map rotation then Pn = (Yp, -Xp). The reason why N should be in the center of a square is because that way you don't have to handle exceptions due to 0 being the 1st row on the left. This way 0 means your square is part of your axes.

Since in xOy N has coordinates (Xn, Yn) then Pn - which coordinates in the XNY system are (Yp, -Xp) - Pn will be ( Xn + Yp, - (Yn + Xp) ).

Almost done, now we have to convert this thought into code lines.
Code:
xN = 30 #your central square x goes here
yN = 30 #your central square y goes here
$game_map.events.each do |event|
  evX = event.x - xN
  evY = event.y - yN
  newX = evY + xN
  newY = -evX + yN
  event.moveto(newX, newY)
end
This should do the trick (unless there are typos or errors from my part). I am quite sure about my calculations but it is late here now and I am kinda tired...everything is possible.

Inverting X and Y (as I suggested before) is a way of creating a symmetrical using y = x as symmetry axis. It is actually rotated by 90 degree but it is also a specular image of your rotated one. That's why it didn't work. I am sorry about that but I was writing in 3 different languages and my brain was going to melt. Now I am home and I can finally reflect on what I wrote. XD
 
Last edited:

Robert-Character Creator

Waiting for Replies
Veteran
Joined
Feb 8, 2014
Messages
518
Reaction score
223
First Language
English
Primarily Uses
RMVXA
Fantastic, thank you. Sorry for the late reply; I live in America, so I took a nap all day. ;) Unfortunately I cannot test it yet; I'm waiting on a modification on one of the scripts by its author, so my game is temporarily unplayable. If I have issues implementing this later on, may I send you a personal message?
 

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,421
Reaction score
596
First Language
Italian
Primarily Uses
RMVXA
Of course, feel free to send me a personal message. I'll correct my post here eventually so people who look for it in the forum are able to see the correct answer.
 

Robert-Character Creator

Waiting for Replies
Veteran
Joined
Feb 8, 2014
Messages
518
Reaction score
223
First Language
English
Primarily Uses
RMVXA
Thanks. On a side note, I attempted to implement all of this, only to realize that I wouldn't be able to use any form of tile data, such as passage or terrain tags, since tiles themselves cannot be moved in-game. I'm working around this using scripts, but this is a warning anyways to anyone attempting this.
 

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,421
Reaction score
596
First Language
Italian
Primarily Uses
RMVXA
You can actually move your passability in game using a simple trick.
EDIT:
last code update: Nov 6th, 2017
Code:
class Game_CharacterBase
  def passable?(x, y, d)
    x2 = $game_map.round_x_with_direction(x, d)
    y2 = $game_map.round_y_with_direction(y, d)
    if map_rotated?
      # xN and yN are x and y coordinates of the center of your cartesian translated system
      xnew = rotated_x(x2, y2, xN, yN, rotations)
      ynew = rotated_y(x2, y2, xN, yN, rotations)
      x2 = xnew
      y2 = ynew
      x1 = $game_map.round_x_with_direction(x2, reverse_dir(d))
      y1 = $game_map.round_y_with_direction(y2, reverse_dir(d))
    end
    return false unless ($game_map.valid?(x, y) && $game_map.valid?(x2, y2))
    return true if @through || debug_through?
    return false unless map_passable?(x1, y1, d)
    return false unless map_passable?(x2, y2, reverse_dir(d))
    return false if collide_with_characters?(x, y)
    return true
  end

  def rotations
    $game_variables[id] #the id of the variable used to tell the engine how many times your map is rotated
  end

  def map_rotated?
    rotations > 0
  end

  def rotated_x(x, y, xN, yN, times)
    return x if (times == 0)
    x1 = rotated_y(x, y, xN, yN, times - 1) - yN
    x1 += xN
    return x1
  end

  def rotated_y(x, y, xN, yN, times)
    return y if (times == 0)
    y1 = rotated_x(x, y, xN, yN, times - 1) - xN
    y1 = yN - y1
    return y1
  end
end
Be aware of the fact that this OVERWRITES passable? method in Game_CharacterBase class, it does not alias it. If you have other script that alias this method you have to place them BELOW this one.

I edited my post adding a better code to do it. The theory is basically the one in the following spoiler. If you are interested in it you can read it. The reason why I optimized the code that way is also written in the spoiler.

Note that the code itself can be even better. That only works for passability but there is actually a way of doing it for everything concerning tiles. Doing that would require a full script and that is something I cannot do in the few minutes I spent writing this post.
You could create something like a passability table and invert that as well.
EDIT: I put this part of the post in a spoiler since passability informations are already part of your $game_map. You can read them directly from it.
Code:
UNPASSABLE_SQUARES = [
  [1, 2], # <- this means square 1, 2 is not passable
  [3, 5], #<-  this means that square 3, 5 is not passable as well
 # ... etc.
  ] # <- do not remove this

You can create even better ones, this is just an example. After creating it you can add a condition to the passable? method in the Game_CharacterBase class that checks the passability according to that table and a switch (the one you want to use to tell the engine that you are using a rotated version of said map). If you do so you have to set your tileset to be passable everywhere in that map.

Code:
class Game_CharacterBase
  def passable?(x, y, d)
    x2 = $game_map.round_x_with_direction(x, d)
    y2 = $game_map.round_y_with_direction(y, d)
    return false if square_table_unpassable?(x2, y2)
    return false unless $game_map.valid?(x2, y2)
    return true if @through || debug_through?
    return false unless map_passable?(x, y, d)
    return false unless map_passable?(x2, y2, reverse_dir(d))
    return false if collide_with_characters?(x2, y2)
    return true
  end

  def square_table_unpassable?(x, y)
    map_rotated? ? rotated_unpassable(x, y) : UNPASSABLE_SQUARES.include?([x, y])
  end

  def map_rotated?
    $game_switches[id] # id is the id of the switch used to tell the engine that your map is rotated
  end

  def rotated_unpassable(x, y)
    xN = 30 #your central square x goes here
    yN = 30 #your central square y goes here
    x1 = x - xN
    x2 = y - yN
    newY = yN + x1
    newX = xN - y1
    return UNPASSABLE_SQUARES.include?([newX, newY])
  end
end

There are other ways of doing this (for example using terrain tags or even regions). This is not the only one but it gives you an idea of how it works.
 
Last edited:

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,421
Reaction score
596
First Language
Italian
Primarily Uses
RMVXA
From a first glance Hime's script aliases the check_passage method of Game_Map class. This means that once you pass the new x and new y to that method it should calculate passability at those coordinates.

The script I gave you should be 100% compatible with Hime's one. That, as I said, from a first glance. Give it a try and tell me if you get any error, I'll fix them as soon as possible.

I cannot guarantee that the script I wrote is free of errors since I am on mobile and I didn't have time to test it but since it is not that complicated fixing it should also be quite fast.

Unfortunately since you are from America and I am from Italy I can only answer you tomorrow (which probably means in two days because monday is always hell) but I can guarantee that I will at least give it a look.
 

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

Latest Threads

Latest Posts

Latest Profile Posts

On my journey of character rework: I had this character, she was meant to be just a princess that joins your party. And at long term she was just uninteresting... So I tweaked her to be a rebel agaisn't the royalty before meeting up with the party.

Quick tip for any other ametuer pixel artists! When trying to create a colour palette, enabling Antialiasing can speed up the process of creating different shades! Just place your lightest colour and your darkest colour next to each other, select both pixels, and stretch it out!
Revolutionizing the JRPG Industry: Knocking on Doors.

Take that, murderhobos.
Don't forget, aspiring writers: Personality isn't what your characters do, it is WHY they do it.

Forum statistics

Threads
106,054
Messages
1,018,580
Members
137,843
Latest member
Betwixt000
Top