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.

Event Vision

I would like a script that alows an event to see strait Forward in all for directions. Such as in a pokemon game. When the even is facing you, it will walk towards you and say something. I have something somewhat like this called the CONE OF VISION.


Code:
#the switch to be activated when the event see the hero. false if none
# Call script using this code:
# $game_map.events[event id].add_cone(sight)
# Stop cone of vision:
# $game_map.events[event id].stop_cone
SWITCH = false

class Game_Character
  attr_reader :cone
  attr_reader :prev_x
  attr_reader :prev_y
  attr_reader :prev_dir
  attr_accessor :sight

  alias conesys_gamecharacter_initialize initialize
  
  def initialize
    @cone = []
    @sight = 0
    conesys_gamecharacter_initialize
  end
  
  def get_cone(sight = 7)
    cone = []
    @sight = sight
    #This algorithim makes the cone using a 2d array
    case self.direction
    when 2 #down
      #adds the first square
      line = 1
      cone.push([self.x,self.y + 1])
      factor = 1
      #now comes the routine to make the cone
      while line < sight
        line += 1
        cone.push([self.x,self.y + line])
        1.upto(factor) do |a|
          cone.push([self.x - a,self.y + line])
          cone.push([self.x + a,self.y + line])
        end
        factor += 1
      end
    when 4 #left
      line = 1
      cone.push([self.x - 1,self.y])
      factor = 1
      #now comes the routine to make the cone
      while line < sight
        line += 1
        cone.push([self.x - line,self.y])
        1.upto(factor) do |a|
          cone.push([self.x - line,self.y - a])
          cone.push([self.x - line,self.y + a])
        end
        factor += 1
      end
      when 6 #right
      line = 1
      cone.push([self.x + 1,self.y])
      factor = 1
      #now comes the routine to make the cone
      while line < sight
        line += 1
        cone.push([self.x + line,self.y])
        1.upto(factor) do |a|
          cone.push([self.x + line,self.y - a])
          cone.push([self.x + line,self.y + a])
        end
        factor += 1
      end
    when 8 #up
      #adds the first square
      line = 1
      cone.push([self.x,self.y + 1])
      factor = 1
      #now comes the routine to make the cone
      while line < sight
        line += 1
        cone.push([self.x,self.y - line])
        1.upto(factor) do |a|
          cone.push([self.x - a,self.y - line])
          cone.push([self.x + a,self.y - line])
        end
        factor += 1
      end
    end

    cone_obstacles(cone)
  end
  #here any tile that is covered by an obstacle is removed
  #from the cone
  def cone_obstacles(cone)
    for i in 0..cone.length
      if cone[i] != nil
        if !$game_map.passable?(cone[i][0], cone[i][1], 0)
          case self.direction
          when 2 #down
            #the diference between the sight and the obstacle position
            limit = self.sight - (cone[i][1] - self.y)
            position = 1
            #to make the read easier
            index = cone.index([cone[i][0],cone[i][1] + 1])
            cone[index] = nil if index != nil
            factor = 1
            #now comes the routine to remove the bloked tiles
              while position < limit
              position += 1
              index = cone.index([cone[i][0],cone[i][1] + position])
              cone[index] = nil if index != nil
                1.upto(factor) do |a|
                  index = cone.index([cone[i][0] - a,cone[i][1] + position])
                  cone[index] = nil if index != nil
                  index = cone.index([cone[i][0] + a,cone[i][1] + position])
                  cone[index] = nil if index != nil
                end
              factor += 1
            end
          when 4 #left
            #the diference between the sight and the obstacle position
            limit = self.sight - (self.x - cone[i][0])
            position = 1
            #to make the read easier
            index = cone.index([cone[i][0] - 1,cone[i][1]])
            cone[index] = nil if index != nil
            factor = 1
            #now comes the routine to remove the bloked tiles
            while position < limit
              position += 1
              index = cone.index([cone[i][0] - position,cone[i][1]])
              cone[index] = nil if index != nil
                1.upto(factor) do |a|
                  index = cone.index([cone[i][0] - position,cone[i][1] - a])
                  cone[index] = nil if index != nil
                  index = cone.index([cone[i][0] - position,cone[i][1] + a])
                  cone[index] = nil if index != nil
                end
              factor += 1
            end
          when 6 #right
            #the diference between the sight and the obstacle position
            limit = self.sight - (cone[i][0] - self.x)
            position = 1
            #to make the read easier
            index = cone.index([cone[i][0] + 1,cone[i][1]])
            cone[index] = nil if index != nil
            factor = 1
            #now comes the routine to remove the bloked tiles
              while position < limit
              position += 1
              index = cone.index([cone[i][0] + position,cone[i][1]])
              cone[index] = nil if index != nil
                1.upto(factor) do |a|
                  index = cone.index([cone[i][0] + position,cone[i][1] - a])
                  cone[index] = nil if index != nil
                  index = cone.index([cone[i][0] + position,cone[i][1] + a])
                  cone[index] = nil if index != nil
                end
            factor += 1
            end
          when 8 #up
            #the diference between the sight and the obstacle position
            limit = self.sight - (self.y - cone[i][1])
            position = 1
            #to make the read easier
            index = cone.index([cone[i][0],cone[i][1] - 1])
            cone[index] = nil if index != nil
            factor = 1
            #now comes the routine to remove the bloked tiles
              while position < limit
              position += 1
              index = cone.index([cone[i][0],cone[i][1] - position])
              cone[index] = nil if index != nil
                1.upto(factor) do |a|
                  index = cone.index([cone[i][0] - a,cone[i][1] - position])
                  cone[index] = nil if index != nil
                  index = cone.index([cone[i][0] + a,cone[i][1] - position])
                  cone[index] = nil if index != nil
                end
              factor += 1
            end
          end
        end
      end
    end
    #update the variables used to check the need of a refresh
    @prev_x = self.x
    @prev_y = self.y
    @prev_dir = self.direction
    @cone = cone
  end

  def in_cone
    #return false if the event do not have a cone
    if cone != []
      #now it checks if the actual position of the hero is inside the cone
      for i in 0...cone.length
        if cone[i] != nil
          if $game_player.x == cone[i][0] && $game_player.y == cone[i][1]
            $game_switches[SWITCH] = true if SWITCH
            $game_map.need_refresh = true
            move_toward_player
          end
        end
      end
    end
  end
  
  def move_toward_player
    # Get difference in player coordinates
    sx = @x - $game_player.x
    sy = @y - $game_player.y
    # If coordinates are equal
    if sx == 0 and sy == 0
      return
    end
    #Now the 8-direction following
      #diagonal movements
    if sx > 0 && sy > 0;  move_upper_left
    elsif sx > 0 && sy < 0;  move_lower_left
    elsif sx < 0 && sy > 0;  move_upper_right
    elsif sx < 0 && sy < 0;  move_lower_right
      #normal movement
    elsif sx < 0 && sy == 0; move_right
    elsif sx > 0 && sy == 0; move_left
    elsif sx == 0 && sy < 0; move_down
    elsif sx == 0 && sy > 0; move_up
    end
  end
  
  #these modifications make the "hero touch" work better
  #thanks Linkin_T for the help
  def check_event_trigger_touch(x, y)
    return if not @stop_count > (40 - @move_frequency * 2) * (6 - @move_frequency)
    old_touch(x, y)
  end
  def check_event_trigger_auto
    return if not @stop_count > (40 - @move_frequency * 2) * (6 - @move_frequency)
    old_auto
  end
end

class Game_Event < Game_Character

  attr_reader :has_cone
  alias conesys_gameevent_initialize initialize
  alias old_touch check_event_trigger_touch
  alias old_auto check_event_trigger_auto
      
  def initialize(map_id, event)
    #a flag that tells if the event is cone-following-enabled or not
    @has_cone = false
    conesys_gameevent_initialize(map_id, event)
  end
  
    #start the cone routine.
  def add_cone(sight = 7)
    @has_cone = true
    get_cone(sight)
  end
    #stop the "cone following"
  def stop_cone
    @has_cone = false
  end
end

class Game_Player < Game_Character
  
  alias conesys_gameplayer_update update
  
  def update
    check_cone
    conesys_gameplayer_update
  end
  
  def check_cone
    #check if the event has a cone
    for i in $game_map.events.keys
      event = $game_map.events[i]
      if event.has_cone && $scene.is_a?(Scene_Map)
        #check if the player is inside the cone of vision and make the
        #event follow him
        event.in_cone
        #update the cone if the event moved or the direction is different
        if event.x != event.prev_x || event.y != event.prev_y || event.direction != event.prev_dir
          event.get_cone(event.sight)
        end
      end
    end
  end
end

But i dont want a "Cone" I would like a Strait line.
 
You dont really need a script to do this. All you need is some understanding of events. Make an event in each direction of the character and have it so so when the event is facing up, if your within one of the events that are facing up, the character will move some many spaces untill its within your character, and then have a message box. If you want me to explain this in more detail, Just pm me, and ill try to get a couple of screens of what to do.

EDIT:
Alright, heres how to do it using events. First off, make a common event, name it something like Character X,Y position (it doesnt really matter, but if your using alot of common events, it could come in handy naming it something youll most likely remember). After this, put inside this common event 2 variable controls, 1 for your characters x position on the map, and one for your characters y position on the map. This should be easy to find on there. Now, make a map with a characters movement to be a set path, and he rotates 90 degrees in any direction, but has a wait of 5 to 10 frames. This will make the character rotate. now, make a parrele prosess event in that map that calls the common event that contains your characters x and y posistion. This will allow you to use these in any map pretty much. Now, make another paralle process that has a conditional branch. It would have 3 branches, 1 would be if the character event, the second the x axis, the third is the y axis. Have it so the conditional branch for the x axis is set to be equal to the x in which you want the character to see on the x axis, do the same for the y. It could take a while to set this up. If I can, and if you want, i will try to get you some pics.
 
Ok. (Photobuckets uploading is very slow... So when it uploads the snaps, ill add um into the explaination.)

Step 1, goto database and Common Events. Create two variables (variable 1 and variable 2) to be set to Character Players Map X and Map Y as those two variables.


Step 2, in the map, create an event with 2 conditional branches inside of each other (one for the x axis and one for the y axis of the map. These should be the same variable your using for each spot. Have them to be if equal to the space in which the event is. Im not sure of you can place if equal to 2 different blocks, but you can try if you want to. If you cant, then there should be more than one event to call this in each square where you want their vision to be. Also, there should be another conditional branch which i forgot in the pic. It should be outside of the other two and used as a direction indicator for the event your using as a spotter. The x value should come after this, then the y value inside of the x.)

Step 3 you make a message for the character, a move route, and if you'd like, you can also make it so it calls a battle scene.

Step 4 set this event to Paralelle Process

Step 5, Make a new event in the corner of the map that calls the Common Event in which your using as the x and y variable, and this event should also be a paralelle process.

Now, this isn't the best way of doing it, but it still gets the job done, and isnt to hard to use since it only requires a couple of events.

Note: If youd like, you should do it like this, Make a single event that calls the Common Event with the x,y values in it, and put all the cordinents in it for the spotting. each one should be inside a different direction, depending on the direct. so all right directions would go under a right catagorie. This would lower the amount of event work, and I do believe might run slightly smoother than my other way, and it'll be alot more organized. Also, it'll control more than just a single event. Or, if you want to be even more organized, set up each character that is a spotter to be a paralelle process and just put each cordinate and direction inside of them, which will make it easier to set up the movement for when the move toward the character.
 
Alright, ill try to put one together, but i cant promise that itll be very good

Edit: Heres the demo. I only have 4 directs of view. I didnt add any diagonal directs, but if you want to add them, just look at the event thats on block 1,1 on the map. I only put a single event spotting, but all of them should work the same. make sure if your gonna use this to make a common event for the (X,Y) position of your character on the map. Just look at the block 1,1 event and you'll understand it pretty well. Its not that hard to understand.

Heres the link to download it from http://www.megaupload.com/?d=97944YIN (if this doesnt work, tell me, Ill fix it.)
 

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