Diagonal Movement and Character Interaction

EightDirMovement1

This is the second part of my tutorial on introducing diagonal movement into RPG Maker.

In the first part, we started with the default project: 4-directional movement and no support for diagonals movement. We modified the player input to handle 8-directional input, updated our characters to store diagonal directions, designed a format for our spritesheets to hold the diagonal sprites, and then implemented the new format in our sprite class so that it knows which sprite to draw.

If you haven’t read the first part, I would recommend doing so. You can visit it by clicking this link.

At the end of the article, we had characters that could move in all eight directions using the correct sprite. We then noticed that we couldn’t trigger events if we approached diagonally.

In this article, we see why this is happening, and how we can resolve it.

Event Triggering and Directions

Directions play a large part in event triggering.

This (kind of) makes sense: you usually check things that are in front of you or under you, rather than behind you or beside you. Well you could of course, but the “Action Trigger” in RM only supports in front or below.

We begin with the player trigger other events by pressing the action button.

Action Trigger

Currently, our diagonal movement script has no problem with checking for events under you. This is because it does not use a character’s direction property.

However, checking events in front of you does use direction. This is how it is defined in Game_Player

def check_event_trigger_there(triggers)
  x2 = $game_map.round_x_with_direction(@x, @direction)
  y2 = $game_map.round_y_with_direction(@y, @direction)
  start_map_event(x2, y2, triggers, true)
  return if $game_map.any_event_starting?
  return unless $game_map.counter?(x2, y2)
  x3 = $game_map.round_x_with_direction(x2, @direction)
  y3 = $game_map.round_y_with_direction(y2, @direction)
  start_map_event(x3, y3, triggers, true)
end

This is what this code means:

  1. Check the tile in front of you.
  2. If the tile in front of you is a counter, check the tile in front of that (this can be called “checking behind the counter”)

Hopefully it is clear what it means for a tile to be in front of you.

Incorporating diagonal directions

In the snippet I show above, the engine determines which position to check using these two methods defined in Game_Map:

def round_x_with_direction(x, d)
  round_x(x + (d == 6 ? 1 : d == 4 ? -1 : 0))
end

def round_y_with_direction(y, d)
  round_y(y + (d == 2 ? 1 : d == 8 ? -1 : 0))
end

You can ignore the rounding for now. That is just to take into consideration the possibility that your map loops.

If you look at how x_with_direction is defined, you see that it simply adds 1 or subtracts 1 depending on the direction you’re facing.

Notice also that it only checks two directions: left or right. It doesn’t consider the possibility that you’re looking towards the upper-left, upper-right, bottom-left, or bottom-right.

Realistically, this is what you need to consider:

EightDirMovement7

So when d is 3, 6, or 9, we need to increase x by 1, and when d is 7, 4, or 1, we need to decrease by 1.

A similar argument is made for the vertical direction: when d is 7, 8, or 9, then we need to increase y by 1. When d is 1, 2, or 3, we need to decrease y by 1.

Here are the new methods, that are adjusted to consider diagonals:

class Game_Map
  def x_with_direction(x, d)
    x + (d % 3 == 0 ? 1 : (d + 2) % 3 == 0 ? -1 : 0)
  end

  def y_with_direction(y, d)
    y + (d < 4 ? 1 : d > 6 ? -1 : 0)
  end

  def round_x_with_direction(x, d)
    round_x(x + (d % 3 == 0 ? 1 : (d + 2) % 3 == 0 ? -1 : 0))
  end

  def round_y_with_direction(y, d)
    round_y(y + (d < 4 ? 1 : d > 6 ? -1 : 0))
  end
end

Note that I do the same with the non-rounded versions for consistency.
For some, this might seem a bit strange, but all I’ve done is converted the observations explained above into formulas. You could conditional branches to check each case one at a time, but because there are only 8 directions, we can throw some math at it.

Add this to your script, and you should be able to trigger events diagonally now!

EightDirMovement8

Turning towards Player

If you have followed along the tutorials (or just look at the previous screenshot), you will see that while the event does respond to the player, it doesn’t actually turn towards you. I assure you that the event does turn towards you if you approach it from another direction:

EightDirMovement9

When you trigger an event, by default it will turn towards you if the direction is not locked. From Game_Event, there is the start method. From there, it calls the lock method.

def start
  return if empty?
  @starting = true
  lock if trigger_in?([0,1,2])
end

def lock
  unless @locked
    @prelock_direction = @direction
    turn_toward_player ###
    @locked = true
  end
end

We can see that it’s supposed to turn towards the player. Following the definition, we find ourselves in Game_Character:

def turn_toward_player
  turn_toward_character($game_player)
end

Which is simple enough: it turns towards a character, which happens to be the player.
And now we arrive at where we want to be:

def turn_toward_character(character)
  sx = distance_x_from(character.x)
  sy = distance_y_from(character.y)
  if sx.abs > sy.abs
    set_direction(sx > 0 ? 4 : 6) ###
  elsif sy != 0
    set_direction(sy > 0 ? 8 : 2) ###
  end
end

It should be apparent why the event wasn’t turning towards us diagonally. It only turns in 4 directions, none of which are diagonal!

Turning Towards a Character Diagonally

The turn_towards_character is meant for one character to turn towards another character in the general direction. This means that if you’re right beside the character, it’ll turn towards you correctly, but if you’re slightly further away, it will just look in your general direction.

This is how the default method works with 4 directions (play with some numbers if you’re not convinced)

EightDirMovement10

So if you’re anywhere inside those regions, that’s the direction the character will turn. If you’re exactly on the edge, it’ll take the region above that line. Each region gets 90 degrees of the circle, rotated 45 degrees along the x-axis.

What we are looking for is something more like this

EightDirMovement11

Each region covers 45 degrees, rotated 22.5 degrees to reflect where the target character could be. Because we are using a grid, and all of our distance calculations are based on grid coordinates, it would be a little difficult to accurately determine which direction the character should turn. At the very least, we should be able to handle the base case: when the characters are beside each other.

EightDirMovement12

At this point, you may want to look at how distance between two characters is calculated since who the point of reference is would affect your calculations.

I look at the problem by first breaking it down into two triangles: the upper-right triangle and the lower-left triangle.

EightDirMovement13

sx = distance_x_from(character.x)
sy = distance_y_from(character.y)
if sx > sy
  set_direction(1) # bottom
else
  set_direction(9) # top
end

It would be a bit easier to see if we extended our grid a little

EightDirMovement14

This is just how I plan to define the directions. It is a very basic setup and it really doesn’t look anything like what we would like it to ideally look, but it’ll work for starters. Here’s how it might look:

class Game_Character < Game_CharacterBase
  def turn_toward_character(character)
    sx = distance_x_from(character.x)
    sy = distance_y_from(character.y)
    if sx > sy      
      if sx == -sy
        set_direction(1)
      elsif sx.abs > sy.abs
        set_direction(4)
      else
        set_direction(2)
      end
    else
      if -sx == sy
        set_direction(9)
      elsif -sx < sy
        if sx == sy
          set_direction(7)
        else
          set_direction(8)
        end
      else
        if sx == sy
          set_direction(3)
        else
          set_direction(6)
        end
      end      
    end
  end
end

And the results

EightDirMovement15

Which doesn’t look too bad. But as I mentioned, the diagonal regions could be done better. And of course, now when you interact with an event, it will turn towards you properly.

There’s an analogous method, turn_away_from_character, which would also need to be updated. It’s basically just the opposite directions since instead of turning towards, you’re turning away.

Touch Events

Action triggered events now function correctly, but if you tried to walk up to a touch-triggered event diagonally, it won’t activate. However, if you walk up to it orthogonally, it works!

Looking at the two definitions, when you move_straight, it actually performs a check to see if there are any touch-triggered events in front of you, whereas when you move diagonally, no such check occurs. This is possibly because there is no concept of “in front” when you’re moving diagonally in the default engine.

Now that we have an actual definition for what it means for a tile to be in front of you even if you’re moving diagonally, we can simply add the check of the move_diagonal method as well. Note that we should only check if we couldn’t move, because that indicates something is blocking our way. At this point it might be better to simply overwrite the method.

Summary

Diagonal movements results in issues with event triggers and turning towards or away from characters. In this section we managed to implement

  • Diagonal event triggering
  • Turning towards and away from a character

This should cover most of the diagonal movement related issues, and you can now have eight directional movement in your game.

Credits

All of the sprites shown in the screenshots are taken from this website: http://usui.moo.jp/rpg_chadot.html

Spread the Word

If you liked the post and feel that others could benefit from it, consider tweeting it or sharing it on whichever social media channels that you use. You can also follow @HimeWorks on Twitter or like my Facebook page to get the latest updates or suggest topics that you would like to read about.

You may also like...

35 Responses

  1. محتوای بیشتر در لینک زیر می باشد
    اندازه گیری دما; big-news.ir,

  2. Billie says:

    Somebody essentially assist to make significantly articles I would state.
    This is the first time I frequented your web page and so far?
    I amazed with the analysis you made to make this
    actual submit incredible. Wonderful activity!

  3. Vidal says:

    I am really thankful to the holder of this website who has shared this fantastic
    piece of writing at at this time.

  4. Lashelle says:

    I pay a visit each day a few websites and blogs
    to read articles, but this blog gives quality based writing.

  5. Kenita says:

    This blog was… how do I say it? Relevant!! Finally I have found something which helped me.

    Many thanks!

  6. Kelleen says:

    Hmm it looks like your site ate my first comment (it was extremely long) so I
    guess I’ll just sum it up what I wrote and say, I’m
    thoroughly enjoying your blog. I as well am an aspiring blog writer but
    I’m still new to the whole thing. Do you have any recommendations for inexperienced blog writers?
    I’d certainly appreciate it.

  7. Aarthi says:

    Whats up are using WordPress for your blog
    platform? I’m new to the blog world but I’m trying to get
    started and create my own. Do you need any html coding knowledge to make your own blog?
    Any help would be greatly appreciated!

  8. Damany says:

    I enjoy looking through an article that will make men and women think.
    Also, thanks for allowing for me to comment!

  9. Karlisha says:

    Hurrah! At last I got a website from where I be able to truly obtain useful data regarding my
    study and knowledge.

  10. Cerissa says:

    We are a group of volunteers and starting a new scheme in our community.
    Your web site provided us with valuable information to work
    on. You’ve done a formidable job and our entire community will
    be grateful to you.

  11. Nasiya says:

    Pretty! This has been an incredibly wonderful post.
    Thank you for providing this information.

  12. Adaline says:

    I am really loving the theme/design of your weblog.

    Do you ever run into any browser compatibility problems?
    A few of my blog readers have complained about my site not working correctly in Explorer but looks great
    in Chrome. Do you have any suggestions to help fix this problem?

  13. Ronette says:

    Hey! I know this is kind of off topic but I was wondering which blog platform are you using for this website?
    I’m getting tired of WordPress because I’ve had problems with hackers and I’m looking at options for another platform.
    I would be awesome if you could point me in the
    direction of a good platform.

  14. Odilia says:

    Definitely believe that which you said. Your favourite reason appeared
    to be at the net the simplest factor to remember of.
    I say to you, I certainly get annoyed whilst folks consider concerns that they plainly
    don’t understand about. You managed to hit the nail upon the highest and also outlined out
    the entire thing with no need side effect , other people can take a signal.
    Will probably be back to get more. Thank you

  15. Vernard says:

    Hi! Would you mind if I share your blog with my myspace group?
    There’s a lot of folks that I think would really enjoy your content.

    Please let me know. Thank you

  16. Jovon says:

    Hi there colleagues, how is the whole thing, and what you wish for to say on the topic of
    this piece of writing, in my view its in fact amazing in favor of me.

  17. Velia says:

    whoah this blog is magnificent i really like studying your articles.
    Keep up the great work! You recognize, lots of individuals are looking around for this info,
    you can aid them greatly.

  18. Prashant says:

    I like the helpful info you provide in your articles.
    I will bookmark your weblog and check again here frequently.
    I’m quite certain I will learn plenty of new stuff right here!

    Best of luck for the next!

  19. Patina says:

    May I just say what a comfort to find someone that actually knows what they’re talking about over the internet.
    You definitely understand how to bring a problem to light and make it important.
    A lot more people have to check this out and understand this side of the
    story. I can’t believe you aren’t more popular since you definitely have the gift.

  20. Aarthi says:

    Does your website have a contact page? I’m having problems locating it but, I’d like to
    shoot you an e-mail. I’ve got some creative ideas for
    your blog you might be interested in hearing. Either way, great site and
    I look forward to seeing it grow over time.

  21. Ursula says:

    Wow, that’s what I was looking for, what a stuff!

    existing here at this website, thanks admin of this website.

  22. Kyler says:

    Great post. I was checking continuously this blog and I’m impressed!
    Very useful info specifically the last part 🙂 I care for such information a lot.
    I was looking for this certain information for a long time.
    Thank you and best of luck.

  23. Arwyn says:

    Today, while I was at work, my sister stole my iphone and tested to see if it can survive a 30 foot
    drop, just so she can be a youtube sensation. My apple ipad is now broken and she has 83 views.
    I know this is totally off topic but I had to share
    it with someone!

  24. Takashi says:

    Nice post. I was checking continuously this blog
    and I am impressed! Very helpful information particularly the final part 🙂 I take care of such info much.
    I used to be seeking this certain info for a very lengthy time.
    Thank you and best of luck.

  25. Crysal says:

    I am curious to find out what blog system you have been working
    with? I’m experiencing some minor security issues with my latest blog and I’d like
    to find something more safeguarded. Do you have any solutions?

  26. Noel says:

    I savour, cause I found exactly what I was having a look for.
    You have ended my 4 day long hunt! God Bless you man. Have a great day.
    Bye

  27. Kaylynne says:

    I like what you guys tend to be up too. This sort of clever work and reporting!
    Keep up the superb works guys I’ve included you guys to my
    personal blogroll.

  28. Amazing things here. I am very satisfied to look your
    post. Thanks so much and I am having a look ahead to contact you.
    Will you kindly drop me a mail?

  29. هایفوتراپی در تهران

  30. Thanks for ones marvelous posting! I truly enjoyed reading it, you may be a great author.
    I will be sure to bookmark your blog and will often come back later in life.

    I want to encourage one to continue your great posts, have a nice evening!

  31. Wow, that’s what I wwas looking for, what a data!
    present heee at this website, tuanks armin of tnis website.

  32. minecraft says:

    Excellent items from you, man. I’ve understand your stuff prior to and you are simply too wonderful.
    I actually like what you’ve bought here, really like what you’re saying and the best way wherein you are saying it.
    You make it enjoyable and you still care for to stay it sensible.
    I cant wait to learn much more from you. That is really a terrific
    website.

  33. board says:

    This website really has all of the info I wanted about this subject and didn’t know who to ask.

  34. Arsist says:

    Let’s say I wanted to activate an event that is one tile above me and 1 tile to
    the right of me, and have an object blocking my upward movement and an object blocking my sideways movement. When the character is blocked, they can’t actually turn diagonal — they can only move diagonally, not explicitly turn diagonally. However, this can be achieved with a turn-in-place D8 script.

Leave a Reply to board Cancel reply

Your email address will not be published. Required fields are marked *