[VX] Sound Emitting Areas

Started by modern algebra, July 26, 2008, 11:59:26 pm

Previous topic - Next topic

modern algebra

July 26, 2008, 11:59:26 pm Last Edit: February 21, 2009, 05:42:59 am by shdwlink1993
Sound Emitting Area
Authors: modern algebra
Version: 1.0b
Type: Music Environment Effect
Key Term: Environment Add-on



Introduction

This script allows you to set a bgm, bgs, se, or me to areas and itdynamically changes the volume depending on how far the player is from the area, creating the impression that the sound is emitting from that area.


Version History


  • <Version 1.0> - Original Release July 26, 2008




Features


  • Can set a bgm, bgs, se, or me

  • Smooth volume transition

  • Allows you to set SE repetition by frames and with variance

  • Lots of options for configuring each sound




Screenshots

Not applicable for this script. See the Demo for a better understanding of the script.


Demo

http://www.sendspace.com/file/n2nu5f


Script
Spoiler: ShowHide

#==============================================================================
#  Sound Emitting Areas (VX)
#  Version 1.0b
#  Author: modern algebra (rmrk.net)
#  Date: July 26, 2008
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Description:
#    This script allows you to set a bgm, bgs, se, or me to areas and it
#    dynamically changes the volume depending on how far the player is from the
#    area, creating the impression that the sound is emitting from that area.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Instructions:
#    See the CONFIGURABLE REGION at line 45
#==============================================================================

#==============================================================================
# ** RPG::Area
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of Changes:
#    new instance variables - se_frames, se_frame_variance, me_frames,
#                             me_frame_variance
#    new methods - setup_sound_emissions, bgm, bgs, me, se, bgm?, bgs?, se?,
#                me?, volume, update_se, update_me
#==============================================================================

class RPG::Area
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Public Instance Variables
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  attr_reader   :se_frames
  attr_reader   :se_frame_variance
  attr_reader   :me_frames
  attr_reader   :me_frame_variance
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Setup Sound Emissions
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def setup_sound_emissions
    # Set Default Values
    @bgs_name, @bgs_pitch, @bgs_radius, @bgs_max_volume = '', 100, 10, 100
    @bgm_name, @bgm_pitch, @bgm_radius, @bgm_max_volume = '', 100, 10, 100
    @se_name, @se_pitch, @se_radius, @se_max_volume = '', 100, 10, 100
    @me_name, @me_pitch, @me_radius, @me_max_volume = '', 100, 10, 100
    @se_frames, @se_frame_variance, @me_frames, @me_frame_variance = 20, 0, 20, 0
    case @id
    #\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    #  !*!*! CONFIGURABLE REGION
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #  Set this region up in this way:
    #   
    #    when area_id
    #      @bgm_name = 'Name of BGM you wish to emit'
    #      @bgm_pitch = the pitch of the BGM, from 50 to 150
    #      @bgm_radius = the radius, in squares, of BGM range.
    #      @bgm_max_volume = The maximum volume of the BGM
    #      @bgs_name = 'Name of BGS you wish to emit'
    #      @bgs_pitch = the pitch of the BGS, from 50 to 150
    #      @bgs_radius = the radius, in squares, of BGS range.
    #      @bgs_max_volume = The maximum volume of the BGS
    #      @se_name = 'Name of SE you wish this area to emit'
    #      @se_pitch = the pitch of the SE, from 50 to 150
    #      @se_radius = the radius, in squares, of the SE range
    #      @se_max_volume = the maximum volume of the SE
    #      @se_frames = the average number of frames between playing the SE
    #      @se_frame_variance = how many more or less frames off the average is the range
    #      @me_name = 'Name of ME you wish this area to emit'
    #      @me_pitch = the pitch of the ME, from 50 to 150
    #      @me_radius = the radius, in squares, of the ME range
    #      @me_max_volume = the maximum volume of the ME
    #      @me_frames = the average number of frames between playing the ME
    #      @me_frame_variance = how many more or less frames off the average is the range
    #
    #  You can omit any of the above stats and they will set to default values,
    #    which are there are no names set, pitch = 100, radius = 10,
    #    max_volume = 100, frames = 20, and frame_variance = 0.
    #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
    when 1 # Waterfall
      # BGS
      @bgs_name = 'River'
      @bgs_radius = 15
      @bgs_max_volume = 110
    when 4 # Chicken Coop
      # SE
      @se_name = 'Chicken'
      @se_max_volume = 75
      @se_frames = 120        # 120 average number of frames between chicken SE
      @se_frame_variance = 40 # [(120-40) - (120+40)] = 80-160 => Frame Range
    #||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
    #  !*!*! END CONFIGURABLE REGION
    #////////////////////////////////////////////////////////////////////////
    end
    # Initialize frame counts
    @se_frame_count = @se_frames + rand (2*@se_frame_variance) - @se_frame_variance
    @me_frame_count = @me_frames + rand (2*@me_frame_variance) - @me_frame_variance
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Update Sound
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def update_sound
    bgm.play if @bgm_name != ''
    bgs.play if @bgs_name != ''
    update_se if @se_name != ''
    update_me if @me_name != ''
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * BGM
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def bgm
    @bgm = RPG::BGM.new (@bgm_name, 0, @bgm_pitch) if @bgm == nil
    @bgm.volume = volume (@bgm_radius, @bgm_max_volume)
    return @bgm
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * BGS
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def bgs
    @bgs = RPG::BGS.new (@bgs_name, 0, @bgs_pitch) if @bgs == nil
    @bgs.volume = volume (@bgs_radius, @bgs_max_volume)
    return @bgs
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * SE
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def se
    @se = RPG::SE.new (@se_name, 0, @se_pitch) if @se == nil
    @se.volume = volume (@se_radius, @se_max_volume)
    return @se
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * SE Update
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def update_se
    if @se_frame_count == 0
      se.play
      @se_frame_count = @se_frames + rand (2*@se_frame_variance) - @se_frame_variance
    else
      @se_frame_count -= 1
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * ME
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def me
    @me = RPG::ME.new (@me_name, 0, @me_pitch) if @me == nil
    @me.volume = volume (@me_radius, @me_max_volume)
    return @me
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * ME Update
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def update_me
    if @me_frame_count == 0
      me.play
      @me_frame_count = @me_frames + rand (2*@me_frame_variance) - @me_frame_variance
    else
      @me_frame_count -= 1
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Volume
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def volume (radius, max_volume)
    x, y = $game_player.x, $game_player.y
    # Determine distance between position and the sound emitting object
    xd, yd = x - @rect.x, y - @rect.y
    # Evaluate X distance
    xd > 0 ? xd = x.between? (@rect.x, @rect.x + @rect.width) ? 0 : xd - @rect.width : xd *= -1
    # Evaluate Y distance
    yd > 0 ? yd = y.between? (@rect.y, @rect.y + @rect.height) ? 0 :yd - @rect.height : yd *= -1
    # Calculate the total distance
    total_distance = Math.sqrt(xd*xd + yd*yd).ceil.to_i
    # Get the percentage of max volume
    percent = (total_distance.to_f / radius.to_f)*100
    percent = (100 - [percent, 100].min).to_f / 100.0
    return (percent*max_volume.to_f).to_i
  end
end

#==============================================================================
# ** Game_Map
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Summary of Changes:
#    aliased method - update, setup
#==============================================================================

class Game_Map
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Setup
  #    map_id : the ID of the map
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_dynamic_snd_emit_stup_rn4 setup
  def setup(map_id)
    # Run Original Method
    modalg_dynamic_snd_emit_stup_rn4 (map_id)
    # Get all areas that belong to this map
    @areas = []
    $data_areas.values.each { |area| @areas.push (area) if map_id == area.map_id }
    # Ensure Area Sound Effects are setup
    @areas.each { |i| i.setup_sound_emissions if i.se_frames == nil }
    @advanced_areas_included = false
    begin
      # Test for exception thrown on .active?
      $data_areas[1].active?
      @advanced_areas_included = true
    rescue
    end
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Update
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias modalg_dyn_sound_emitting_objects_upd_4h3 update
  def update
    # Run Original Map
    modalg_dyn_sound_emitting_objects_upd_4h3
    # For all area
    @areas.each { |area|
      next if @advanced_areas_included && !area.active?
      area.update_sound
    }
  end
end



Instructions

See inside the script.


Compatibility

There should not be any Compatibility errors. If there are, post either here or RMRK.net .


Credits and Thanks


  • modern algebra




Author's Notes

Please post at rmrk.net for the swiftest support, as I am not as active here as I should be.

This script is based off of the version I wrote for RMXP with a number of significant alterations. This script is completely compatible with my Advanced Areas script, and I recommend it if you do not want the sounds playing all the time, as the Advanced Areas script includes a way to turn the area off by a switch and this script will recognize that command as well.