Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Events that chase after the player on sight.

CJF

Member

Hello community,

I'm looking to have enemies on the world map, and I'd like them to chase the player(Entering into combat if they touch the player) if he's within a certain number of tiles, and to STOP chasing the player when he leaves said number of tiles from the event.

I'd also like to have the number of tiles that the Enemy Event starts chasing at be unique to each event.

Anyone know of such a script(Or something similar) or can create one?

I would VERY much appreciate it.

Thanks!

-CJF
 
Found this when searching for "view range". This post was made by SephirothSpawn, he is explaining how to use the script. The script was written by Near Fantastica and SephirothSpawn. There might be an updated version but I can't find the original thread.
SephirothSpawn":5t9hsqh1 said:
First off, make sure you have the most updated version:
Code:
#============================================================================== 

# ** Modules.View Range (5.0)               By Near Fantastica & SephirothSpawn

#------------------------------------------------------------------------------

# * Description :

#

#   The View Range Module is used to test objects position in comparision with

#   another object. It can test if an object is within a defined circular

#   range of another object or a rectangular defined region. It can also tell

#   you this distances between objects.

#------------------------------------------------------------------------------

# * Syntax :

#

#   Test if object is within defined range from another object :

#    - VR.in_range?(object1, object2, range)

#    - VR.in_range?(object1x, object1y, object2x, object2y, range)

#

#   Test if object is within defined rectanlge :

#    - VR.in_rect_range?(object, <args>)

#    - VR.in_rect_range?(x, y, <args>)

#

#    args can either be : x, y, width, height or Rect.new(x, y, width, height)

#

#   Test range between objects :

#    - range = VR.range(object1, object2, <integer>)

#    - range = VR.range(object1x, object1y, object2x, object2y, <integer>)

#

#    integer : if true, returns integer ; if false, returns float

#==============================================================================

 

MACL::Loaded << 'Modules.View Range'

 

#==============================================================================

# ** View Range

#==============================================================================

 

module VR

  #----------------------------------------------------------------------------

  # * Within Range Test

  #----------------------------------------------------------------------------

  def VR.in_range?(*args)

    # If 3 Arguments (Element, Object, Range)

    if args.size == 3

      x = (args[0].x - args[1].x) ** 2

      y = (args[0].y - args[1].y) ** 2

      r = args[2]

    # If 5 Arguments (Elementx, Elementy, Objectx, Objecty, Range)

    elsif args.size == 5

      x = (args[0] - args[2]) ** 2

      y = (args[1] - args[3]) ** 2

      r = args[4]

    else

      p 'Wrong Defined Number of Arguments'

      return 

    end

    return (x + y) <= (r * r)

  end

  #----------------------------------------------------------------------------

  # * Within Rect Range Test

  #----------------------------------------------------------------------------

  def VR.in_rect_range?(*args)

    # If 2 Arguments (Object, Rect)

    if args.size == 2

      x_, y_ = args[0].x, args[0].y

      x, y, w, h = args[1].x, args[1].y, args[1].width, args[1].height

    # If 3 Arguments (Objectx, Objecty, Rect)

    elsif args.size == 3

      x_, y_ = args[0], args[1]

      x, y, w, h = args[2].x, args[2].y, args[2].width, args[2].height

    # If 5 Arguments (Object, Rectx, Recty, Rectwidth, Rectheight)

    elsif args.size == 5

      x_, y_ = args[0].x, args[0].y

      x, y, w, h = args[1], args[2], args[3], args[4]

    # If 6 Arguments (Objectx, Objecty, Rectx, Recty, Rectwidth, Rectheight)

    elsif args.size == 6

      x_, y_, x, y, w, h = *args

    else

      p 'Wrong Defined Number of Arguments'

      return

    end

    # Return Object Within Rect

    return x_.between?(x, x + w) && y_.between?(y, y + h)

  end

  #----------------------------------------------------------------------------

  # * Range

  #----------------------------------------------------------------------------

  def VR.range(*args)

    # If 2 Arguments (Element, Object)

    if args.size == 2

      x = (args[0].x - args[1].x) * (args[0].x - args[1].x)

      y = (args[0].y - args[1].y) * (args[0].y - args[1].y)

      integer = true

    # If 3 Arguments (Element, Object, Integer

    elsif args.size == 3

      x = (args[0].x - args[1].x) * (args[0].x - args[1].x)

      y = (args[0].y - args[1].y) * (args[0].y - args[1].y)

      integer = args[2]

    # If 4 Arguments (Elementx, Elementy, Objectx, Objecty)

    elsif args.size == 4

      x = (args[0] - args[2]) * (args[0] - args[2])

      y = (args[1] - args[3]) * (args[1] - args[3])

      integer = true

    # If 5 Arguments (Elementx, Elementy, Objectx, Objecty, integer)

    elsif args.size == 5

      x = (args[0] - args[2]) * (args[0] - args[2])

      y = (args[1] - args[3]) * (args[1] - args[3])

      integer = args[4]

    else

      p 'Wrong Defined Number of Arguments'

      return

    end

    r = Math.sqrt(x + y)

    return integer ? r.to_i : r

  end

end

As it says in the script heading, you can test:
- If object is within x distance from another object
- If object is bound within a rectangle
- Return the distance from one object to another

You can use this for the Condition and script option, store variables, etc.

Anyways, to test if object 1 is within x distances to object 2. You can use any object with a .x and .y instance, more often you use events and the player.
Code:
# Events

$game_map.events[event_id]

# Player

$game_player

So to test if the player is within 5 tiles of a target event
Code:
VR.in_range?($game_player, $game_map.events[event_id], 5)

It's as simple as that. Be sure to read the script heading, and ask any questions if you are unsure about something.
 

Yin

Member

This is also an option.

Code:
#--------------------------------------------------------------------------

#             Enemy Detection System

#             by Gubid - 8/12/07

#             v 1.2.2 Updated 10/2/07

#--------------------------------------------------------------------------

#Description:

#This system allows events that are named something including "ENEMY" then

#that event will be told to approach Game_Player, until Game_Player has gotten

#a specified distance away. At that time event will return to its original

#position if desired. If you happen to get close enough to the returning event

#it will begin to follow you again.

#

#Thanks to Near Fantasia for supplying the slightly modified path finding script.

#--------------------------------------------------------------------------

#if there are any questions as to the use of this script or

#modifications/additions/etc, please post it to the thread on CreationAyslum.net

#--------------------------------------------------------------------------

 

#--------------------------------------------------------------------------

#Update_Detect - How to Stop Detection if desired

#--------------------------------------------------------------------------

#1. Within a event, add a SCRIPT (3rd page)

#2. type "update_detect(EVENT_ID, TRUE/FALSE)" -Note: it defaults to false

 

#--------------------------------------------------------------------------

#RETURN TO POSITION

#--------------------------------------------------------------------------

#Use this to determine if you would like the event to return to its original

#position or not.

#--------------------------------------------------------------------------

RETURN_TO_POSITION = true

 

#--------------------------------------------------------------------------

#CHASE_SPEED and ENABLE_SPEED_CHANGE

#--------------------------------------------------------------------------

#Use this to set the speed in which enemies will approach after spotting you

#and whether or not their speed will change.

#--------------------------------------------------------------------------

CHASE_SPEED = 3

ENABLE_SPEED_CHANGE = true

 

#--------------------------------------------------------------------------

#VIEW_RANGE

#--------------------------------------------------------------------------

#Use this to set the distance in which you must be in order to start the detection

#process, or escape to stop.

#--------------------------------------------------------------------------

VIEW_RANGE = 5

 

#--------------------------------------------------------------------------

#ESCAPE_RANGE

#--------------------------------------------------------------------------

#Use this to set the distance in which you must escape to stop the detection process

#--------------------------------------------------------------------------

ESCAPE_RANGE = 9

 

#--------------------------------------------------------------------------

#Other Notes

#--------------------------------------------------------------------------

#If the event has a custom move route, they will resume that route when finished

#chasing you, but if you dont set RETURN_TO_POSITION, then they will resume

#their custom route at the location they stopped chasing you.

 

class Game_Map

#--------------------------------------------------------------------------

# * Frame Update

#--------------------------------------------------------------------------

  alias en_detect_gm_update update

  def update

    en_detect_gm_update

    

    # Update map event

    for event in @events.values

      if !event.name.include?("enemy")

        next

      else

        if event.character_name != ""

          if event.stop_detect? 

            next

          end

          if check_distance(event.id) == true

            if event.exclamation == false

              event.old_type = event.move_type

              event.move_type = 2

              if ENABLE_SPEED_CHANGE

                event.old_speed = event.move_speed

                event.move_speed = CHASE_SPEED

              end

              event.exclamation = true

              event.animation_id = 98 #98 happens to be the exclamation animation

              event.f_route.clear

            end

          else

            if event.exclamation == true

              event.exclamation = false

              if RETURN_TO_POSITION == true

                if event.x != @map.events[event.id].x or event.y != @map.events[event.id].y

                  route = get_route(event, @map.events[event.id].x, @map.events[event.id].y)

                  event.run_route(route)

                end

              else

                event.restore_route

              end

            end

          end

        end

      end

    end

  end

  

  def check_distance(id = nil)

    unless id == nil

      event = $game_map.events[id]

      range = ($game_player.x - event.x).abs + ($game_player.y - event.y).abs

      

      if range <= VIEW_RANGE and range > 0

        return true

      elsif range <= ESCAPE_RANGE and range > 0 and event.exclamation

        return true

      end

    end

  end

 

  def get_route(event, x=0, y=0)

    target_x = x

    target_y = y

    max = (target_x - event.x).abs + (target_y - event.y).abs + 5

    position = [[event.x, event.y]]

    route = [[]]

    more_step = [0]

    for i in more_step

      x = position[i][0]

      y = position[i][1]

      if !position.include?([x, y + 1]) and event.passable?(x, y, 2)

        position.push([x, y + 1])

        route.push(route[i] + [2])

        if route[i].size + 1 < max

          more_step.push(route.index(route[i] + [2]))

        end

      end

  

      if !position.include?([x - 1, y]) and event.passable?(x, y, 4)

        position.push([x - 1, y])

        route.push(route[i] + [4])

        if route[i].size + 1 < max

          more_step.push(route.index(route[i] + [4]))

        end

      end

 

      if !position.include?([x + 1, y]) and event.passable?(x, y, 6)

        position.push([x + 1, y])

        route.push(route[i] + [6])

        if route[i].size + 1 < max

          more_step.push(route.index(route[i] + [6]))

        end

      end

 

      if !position.include?([x, y - 1]) and event.passable?(x, y, 8)

        position.push([x, y - 1])

        route.push(route[i] + [8])

        if route[i].size + 1 < max

          more_step.push(route.index(route[i] + [8]))

        end

      end

    end

    if position.index([target_x, target_y]) == false

      return [2]

    else

      return route[position.index([target_x, target_y])]

    end

  end

end

 

 

class Game_Event

  attr_accessor :move_type

  attr_accessor :move_speed

  attr_accessor :old_speed

  attr_accessor :exclamation

  attr_accessor :old_type

  attr_accessor :stop_trigger

  attr_reader   :f_route

 

  def initialize(map_id, event)

    super()

    @map_id = map_id

    @event = event

    @id = @event.id

    @erased = false

    @starting = false

    @through = true

    @name = @event.name

    @exclamation = false

    @f_route = []

    @step = 0

    @old_type = @move_type

    @old_move_route =  @move_route

    @old_speed = @move_speed

    @stop_trigger = false

    moveto(@event.x, @event.y)

    refresh    

  end

  

  def stop_detect? 

    return @stop_trigger

  end

    

  def restore_route

    @move_type = @old_type

    @move_route_index = @original_move_route_index

    @move_speed = @old_speed

    refresh

    return

  end

  

  def name

    return @name

  end

 

  alias en_det_update update

  def update

    if @f_route.size > 0

      run_path unless self.moving?

      if @f_route.size == 0

        restore_route

      end

    end    

    en_det_update

  end

  

  def run_route(route)

    @f_route = route

    @step = 0

  end

  

  def run_path

    if @f_route.size > 0

      if @f_route[@step] == nil

        @f_route = []

      end

      action = @f_route[@step]

      @step += 1

      case action

      when 2

        self.move_down

      when 4

        self.move_left

      when 6

        self.move_right

      when 8

        self.move_up

      end

    end

  end  

end

 

class Interpreter

  def update_detect(id, set = false)

    $game_map.events[id].stop_trigger = set

  end

 

  def spotted?

    is_true = 0

    for event in $game_map.events.values

      if event.exclamation

        is_true += 1

      end

    end

    if is_true > 0

      return true

    else

      return false

    end

  end

 

  def change_switch(id = 0, value = false, type = 0, switch = "A")

    if id > 0

      if type == 0 #for use of main switches

        #id is switch_id and value should set to true or false

        $game_switches[id] = value

      elsif type == 1 #For use of self switches

        #id is event.id and switch is the desired selfswitch. It must be text!

        #value is true or false

        key = [$game_map.map_id, id, switch]

        # Updates self switch

        $game_self_switches[key] = value

      end

      # Refresh map

      $game_map.need_refresh = true

      return true

    end

  end

end
Just put enemy in the event's name. I use it! But I don't know about the different distances. I'm not sure if you can change it.
 

CJF

Member

Yin":3pt30jbb said:
This is also an option.
Just put enemy in the event's name. I use it! But I don't know about the different distances. I'm not sure if you can change it.

Hmm... I'm getting a "SyntaxError occurred" on line 2 whenever I try to use it. Any ideas? Line 2 is just ASCII art...

EDIT: The problem was when I selected all, the line numbers from the script were causing a syntax error.
 
I was using the second option just yesterday and it worked fine. But now I run the game again and it doesn't work anymore. The event just sits there, and doesn't move towards the player. I have tried re-making the event, and I've also deleted and re-entered the script. I can't think of what might be wrong, has anyone else experienced this?

Thanks in advance
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top