RMRK is retiring.
Server is paid up for the rest of 2026, but the forum may go after that. See here for more information. Please archive or save anything you would like to keep before 2027.
Main Menu
  • Welcome to The RPG Maker Resource Kit.

Snippet Request: Calculate distance

Started by sanchezinc, February 17, 2011, 07:18:11 AM

0 Members and 1 Guest are viewing this topic.

sanchezinc

Hello, my objective is to execute a parallel process event when the character is close enough to him.
My idea is to have a conditional branch before the actions to allow or prevent execution.

I'm using an anti event lag script by NearFantastica that has this little code
def in_range?(object)
  screne_x = $game_map.display_x
  screne_x -= 256
  screne_y = $game_map.display_y
  screne_y -= 256
  screne_width = $game_map.display_x
  screne_width += 2816
  screne_height = $game_map.display_y
  screne_height += 2176
  return false if object.real_x <= screne_x
  return false if object.real_x >= screne_width
  return false if object.real_y <= screne_y
  return false if object.real_y >= screne_height
  return true
end


I want to use this, to verify if the event in on screen. So in the conditional branch script, im typing
"in_range?($game_map.events[039])" hoping to get a true or false returned. This gives me a Syntax Error.

Is this possible? and if it is, what am I doing wrong?
Thanx for your help.

Zeriab

If you use leading zeroes the interpreter expect the number to be base 8 rather than base ten. (I.e. 0-7 instead of 0-9)
Remove the leading zero and tell me what happens then.

*hugs*

sanchezinc

#2
Ok that got me a new error, NoMethodError

undefined method 'in_range?' for #<Interpreter:0x8b73a78>

Hope this helps to understand what is going on.

EDIT: Found a way to do what I wanted. I added this to the scripts.
class MyClass
  def self.distance(object)
    screne_x = $game_map.display_x
    screne_x -= 50
    screne_y = $game_map.display_y
    screne_y -= 50
    screne_width = $game_map.display_x
    screne_width += 2450
    screne_height = $game_map.display_y
    screne_height += 1900
    return false if object.real_x <= screne_x
    return false if object.real_x >= screne_width
    return false if object.real_y <= screne_y
    return false if object.real_y >= screne_height
    return true
  end
end

This is the same code modified in both parameters, and making it a self method in another class. This allowed me to make the conditional branch using this piece of code.
MyClass.distance($game_map.events[39])
It works perfctly, but I don't know if this was the best solution, memory or processor wise. Or even if the creation of a new class is recommended. So if u have a better solution I'll be pleased to use it. So far it appears to work perfect for me.

ForeverZero

#3
class Interpreter
  def range?(args)
    if args.is_a?(Array)
      # If an array of coordinates has been passed
      x, y = args[0], args[1]
    else
      # Assume the argument is either an event or a $game_player
      x, y = args.x, args.y
    end
    return Math.hypot((self.x - x), (self.y - y))
  end
end   
 

You can use this an events code, it will test the distance from itself to the argument that was passed. You can either pass an event ($game_map.events[2], $game_player, or an array of coordinates ([3, 5]). It will return the distance, in tiles, that the event is from the argument.

ex. In an events code, you could use this:

Conditional Branch: Script: range?($game_player) <= 4

This will return in true when the player is within 4 tiles of the event.

sanchezinc

#4
Thanx! I like the versatility of your code, I could also use that for other features different from what I was looking for. But I do have a couple questions. How would I make this an event's code? With the call script? If that's the case, and the code doesnt fit in a single call script, can it be divided in 2 or more sections? Hope I was clear on my questions. And thank you once again.

EDIT:

I think it's important to mention that the code I posted is NOT to calculate distance, I put a missleading thread title. What it really does is determine if a given event is in the screen (or area around the screen to be more precise). The advantage I see on this is (I think) if you pan the screen, the event will be performing the actions. Thanx again for the distance contribution, I think this will be usefull for lots of people, not oonly me.

ForeverZero

#5
I edited the code above, I noticed an error with the argument.

Here's an old script I wrote (my scripts can be found as Chaos Project) that should take care of all your problems.

#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
# Event Range Conditions
# Author: ForeverZer0
# Version: 1.0
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
#
# Explanation:
#
#   Allows you to set up conditional branches in events that will be based off
#   the event's coordinates in relation to the player's coordinates without
#   having to create any variables for the X and Y of each.
#
#   Here are the new features you can use a conditional branch. Just type these
#   into the script box for the branch.
#
#   range?(RANGE, EVENT_ID) - Will be true if player is anywhere in the radius
#                             defined by RANGE from the event with EVENT_ID
#
#   on_screen?(EVENT_ID)    - Will be true if the event with EVENT_ID is within
#                             the visible screen
#
#   x_dist?(DIST, EVENT_ID) - Returns true if the player's x/y is within DIST
#            OR               of event's x/y with EVENT_ID. These are absolute
#   y_dist?(DIST, EVENT_ID)   values, meaning it doesn't matter which direction,
#                             it just uses the total distance in tiles for that
#                             axis. Use a DIST of 0 to check if that axis is
#                             equal.
#
#   player_above?(EVENT_ID) - Returns true when player is above event.
#   player_below?(EVENT_ID) - Returns true when player is below event.
#   player_right?(EVENT_ID) - Returns true when player is right of the event.
#   player_left?(EVENT_ID)  - Returns true when player is left of the event.
#
#   For all of these, if the conditional branch that is using them is within
#   the event that it applies to, you do not have to include the EVENT_ID, it
#   is assumed to be that event's ID unless otherwise defined.
#
#   You can use these as a condition for just about anything, such as having
#   an event say something, run away, or run toward the player if it is within a
#   specific distance, and it's much easier than using multiple branches and
#   game variables to set it up.
#
#   Remember that if you use a range condition with a parallel trigger, it will
#   continue to execute as long as the condition is met and if the player cannot
#   move during the event's code, the game will effectively be stuck.
#
# Compatability:
#
#   - You may encounter issues if using a Pixel Movement script, though it
#     should still work fine with an 8-Way Movement script. (Not tested)
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:

class Interpreter
 
  def range?(range = 4, id = @event_id)
    e = $game_map.events[id]
    radius = (Math.hypot((e.x - $game_player.x), (e.y - $game_player.y))).abs
    return (radius <= range)
  end
 
  def on_screen?(id = @event_id)
    x, y = $game_map.events[id].real_x, $game_map.events[id].real_y
    if ((x - $game_map.display_x + 64) / 4).between?(0, 640) &&
       ((y - $game_map.display_y) / 4).between?(0, 480)
      return true
    end
    return false
  end
 
  def x_dist?(distance = 0, id = @event_id)
    x_dif = ($game_map.events[id].x - $game_player.x).abs
    return (x_dif <= distance)
  end
 
  def y_dist?(distance = 0, id = @event_id)
    y_dif = ($game_map.events[id].y - $game_player.y).abs
    return (y_dif <= distance)
  end
 
  def player_above?(id = @event_id)
    return ($game_map.events[id].y > $game_player.y)
  end
 
  def player_below?(id = @event_id)
    return ($game_map.events[id].y < $game_player.y)
  end
 
  def player_right?(id = @event_id)
    return ($game_map.events[id].x < $game_player.x)
  end
 
  def player_left?(id = @event_id)
    return ($game_map.events[id].x > $game_player.x)
  end
 
end


sanchezinc

Excelent script, just tried it on my game, works perfectly. This should have been a standard script built into the original RMXP. Its so basic and useful.