| 赞 | 2 |
| VIP | |
| 好人卡 | |
| 积分 | 5 |
| 经验 | |
| 最后登录 | 2026-5-19 |
| 在线时间 | 59 小时 |
- 梦石
- 0
- 星屑
- 499
- 在线时间
- 59 小时
- 注册时间
- 2016-1-25
- 回帖
- 9
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有账号?注册会员
×
事件注释播放的声音没有了范围渐变,变成全图最高音量播放
脚本小白求助
动态事件音源#==============================================================================
# 动态事件音源
# Version: 1.0.5
# Author: modern algebra (rmrk.net)
# Date: 30 March 2014
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# 介绍:
#
# 本脚本可以做出类似音源的效果,就是玩家离事件越近,播放的音乐声音越大。
# 可以播放SE, ME, BGM 和 BGS, 注意一次只能播放BGM 或 BGS 中的一个.
# 所以你不能设定播放BGM 或 BGS的事件超过两个.
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# 使用方法:
#
# 将本脚本放在插件脚本之下,Main之上.
#
# 在事件页的第一行里插入一个注释,如果空间不够,你可以插入多个注释。
# 注释里填入:
#
# \emit_BGM {
# name = ""
# min_volume = 0
# max_volume = 80
# pitch = 100
# radius = 15
# source_radius = 0
# }
#
# 你可以把第一行的 BGM 改变为 BGS, SE, 或 ME. 一个事件只能"携带"一种声音
# 括号里的参数,只有name = ""是必须要写的,其他的可以被无视。同时,它们也
# 不一定非要分成多行,你也可以通过semicolons来分隔它们. 各设定的功能为:
#
# name = ""
# 声音的文件名(不包括拓展名),放在 " " 里面
# min_volume = 0
# 最小音量.
# max_volume = 80
# 最大音量
# pitch = 100
# 音调.
# radius = 15
# 声音传播的半径,玩家在声音范围内才会听到声音。玩家离音源事件越近,
# 声音越接近最大音量(max_volume).
# source_radius = 0
# 声音音源半径,在音源半径中,声音音量始终等于最大音量(max_volume)
# 音源半径会增加声音传播半径,也就是说,假如音源半径为2、传播半径为6,
# 当玩家在事件距离事件2图块时,声音为最大音量;玩家距离事件2到8图块时,
# 声音不断减小;玩家距离事件8图块之外,声音完全消失。
#
# 如果声音的类型是 SE 或 ME, 则还可以使用额外两个设定。
# 第一个:可以设定音调的范围,音调会在该范围内随机选择, 例如:
#
# pitch = 75...125
#
# 在上面这个例子中, 音量会在每次播放时从 75 到 125 中随机选择。
#
# 第二个:播放时间间隔(60 帧 = 1 秒) ,既可以是整数也可以是一个范围.
# 例子1:
#
# time = 120
#
# 在上面一个例子中, SE/ME 会每 120 帧 (2 秒) 播放一次.
# 例子 2:
#
# time = 600...900
#
# 在上面一个例子中,SE/ME 会每 600 - 900 帧 (10 - 15 秒) 播放一次.
#
# 最后,还有一个功能. 如果你想设定音源区域大于1X1 (例如, 一个4X3的瀑布作为音源
# ), 则你可以把音源事件放在音源区域的最左上角,然后在注释里使用[x, y]来设定
# 音源范围大小:
#
# \emit_BGS[x, y] { ... }
#
# 所以回到之前我说的那个瀑布, 就应该设置成 [3, 2], 因为第一个事件已经包含在音
# 源范围内了.
#``````````````````````````````````````````````````````````````````````````````
# 例子:
#
# \emit_BGM { name = "Fire" }
#
# 事件会不断播放"Fire" BGM. 因为其他参数都没有被设定,所以都使用默认值:
# volume = 80; pitch = 100; radius = 15.
#
# \emit_BGS[0, 4] {
# name = "River"; volume = 100;
# radius = 10 }
#
# 事件会不断播放 "River" BGS. 音源大小为该事件那一格 + 它下面的4格 ,总共5
# 格,像数字1一样,是竖直长条形。音源最大音量是100,玩家离音源越远,声音越小
# 声音传播范围10格,再远处就听不见声音了。
#
# \emit_SE { name = "Dog";
# radius = 12; pitch = 90..120;
# time = 420...720; source_radius = 3 }
#
# 该事件每隔7 - 12秒就会播放"Dog" SE. 播放时, 音调会随机变成 90 - 120 之间
# 的任意一个值,音源半径是3,所以在狗狗事件3X3格内音量最大。因为传播半径是12
# 所以声音的总区域是半径为15的方形.
#``````````````````````````````````````````````````````````````````````````````
# 如果你担心会发生卡顿, 你可以将 SMOOTH_TRANSITION 设定为 false.
#==============================================================================
$imported = {} unless $imported
$imported[:MA_DynamicSoundEmittingEvents] = true
#==============================================================================
# ** Sound Emitter
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This class holds sound emission data and updating methods
#==============================================================================
class MA_SoundEmitter
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
# 可编辑区域
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# SMOOTH_TRANSITION (平滑渐变) - 开启时,当玩家和音源事件的相对距离发生改变
# 时,可以平滑的过度。关闭时声音的改变会变得唐突,但对于小传播半径的音源也不
# 是很明显。为了获得最好的效果,建议开启此功能,但是如果你担心这会造成游戏卡
# 顿,那还是关闭了吧。
SMOOTH_TRANSITION = true
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# 以下为不可编辑区域
#////////////////////////////////////////////////////////////////////////////
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Public Instance Variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
attr_accessor :event_id
attr_accessor :sound_type
attr_accessor :radius
attr_accessor :source_radius
attr_accessor :min_volume
attr_accessor :max_volume
attr_accessor :pitch
attr_accessor :time
attr_accessor :size_x
attr_accessor :size_y
attr_reader :filename
attr_reader :audiofile
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialize
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize(event_id = 0)
@event_id = event_id
clear
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Clear
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def clear
RPG.const_get(@sound_type).stop if audiofile && @sound_type == :BGM || @sound_type == :BGS
@sound_type = :SE
@radius = 15
@source_radius = 0
@min_volume = 0
@max_volume = 80
@pitch = 100
@time = 600..900
@player_x, @player_y = -1, -1
@event_x, @event_y = -1, -1
@size_x, @size_y = 0, 0
load_audiofile("")
reset_timer
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Frame Update
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def update
return unless audiofile && $game_map.events[event_id]
case @sound_type
when :SE, :ME
return unless update_se_me?
audiofile.volume = calc_volume if recalc_vol?
audiofile.pitch = calc_pitch
reset_timer
when :BGM, :BGS
return unless recalc_vol?
new_vol = calc_volume # Distance calculation
# If variation < 3 and not transitioning to limit
return if audiofile.volume == new_vol ||
(audiofile.volume.between?(new_vol - 2, new_vol + 2) &&
(audiofile.volume != 0 && new_vol != 0) &&
(audiofile.volume != max_volume && new_vol != max_volume))
audiofile.volume = new_vol
end
audiofile.play
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Update SE/ME?
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def update_se_me?
if @timer > 0 # If timer not counted down
@timer -= 1 # Reduce timer
return false
end
return true
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Recalculate Volume?
# * Reset Position Vars
#``````````````````````````````````````````````````````````````````````````
# Done this way to account for the value of SMOOTH_TRANSITION
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pos_val = SMOOTH_TRANSITION ? "real_" : ""
madsee_pos_methods = <<POS_END
def recalc_vol?
event = $game_map.events[event_id]
!(@player_x == $game_player.#{pos_val}x && @event_x == event.#{pos_val}x &&
@player_y == $game_player.#{pos_val}y && @event_y == event.#{pos_val}y)
end
def reset_position_vars
event = $game_map.events[event_id]
@player_x, @player_y = $game_player.#{pos_val}x, $game_player.#{pos_val}y
@event_x, @event_y = event.#{pos_val}x, event.#{pos_val}y
end
POS_END
eval(madsee_pos_methods)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Reset Timer
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def reset_timer
@timer = time.is_a?(Integer) ? time : time.first + rand(time.last - time.first)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Calculate Volume
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def calc_volume
reset_position_vars
r = radius + source_radius + 1
# Get real horizontal distance between emitter and player
raw_dist_x = @player_x - @event_x
dist_x = raw_dist_x > 0 ? [raw_dist_x - @size_x, 0].max : -raw_dist_x
if $game_map.loop_horizontal? # Accomodate if map looping
loop_x = [$game_map.width - dist_x - @size_x, 0].max
dist_x = loop_x if loop_x < dist_x
end
return min_volume if dist_x > r
# Get real vertical distance between emitter and player
raw_dist_y = @player_y - @event_y
dist_y = raw_dist_y > 0 ? [raw_dist_y - @size_y, 0].max : -raw_dist_y
if $game_map.loop_vertical? # Accomodate if map loops vertically
loop_y = [$game_map.height - dist_y - @size_y, 0].max
dist_y = loop_y if loop_y < dist_y
end
return min_volume if dist_y > r
# Get diagonal distance
dist = Math.hypot(dist_x, dist_y)
return min_volume + (dist > r ? 0 : (([(r - dist) / (r - source_radius), 1].min)*(max_volume - min_volume)).to_i)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Calculate Pitch
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def calc_pitch
pitch.is_a?(Integer) ? pitch : pitch.first + rand(pitch.last - pitch.first)
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Load AudioFile
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def load_audiofile(filename = @filename)
@filename = filename
@audiofile = RPG.const_get(@sound_type).new(@filename)
@audiofile.pitch = calc_pitch
end
alias :"filename=" :load_audiofile
end
#==============================================================================
# ** Game_Map
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased methods - setup
#==============================================================================
class Game_Map
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Setup Events
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias madsee_setup_3kq4 setup
def setup(*args)
# Clear Emitters if they were present in last map, primarily to stop the
# them if they are playing BGMs or BGSes.
@events.values.each { |e|
e.madsee_emitter.clear if e.madsee_emitter } if @events
madsee_setup_3kq4(*args) # Call original method
end
end
#==============================================================================
# ** Game_Event
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased methods - initialize; clear_page_settings; setup_page_settings;
# update
# new method - madsee_emitter; madsee_setup_emitter; ma_collect_init_comment
#==============================================================================
class Game_Event
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Public Instance Variables
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
attr_reader :madsee_emitter
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Setup Page Settings
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias madsee_stuppges_6ag6 setup_page_settings
def setup_page_settings(*args)
madsee_stuppges_6ag6(*args) # Call original method
madsee_setup_emitter
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Clear Page Settings
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias madsee_clrpageset_4sm7 clear_page_settings
def clear_page_settings(*args)
madsee_clrpageset_4sm7(*args) # Call original method
@madsee_emitter.clear if @madsee_emitter
@madsee_emitter = nil
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Setup Emitter
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def madsee_setup_emitter
# Collect First comment
comment = ma_collect_init_comment
if comment[/\\EMIT[_ ](BGM|BGS|ME|SE)\[?(\d*)[;;,\s]*(\d*)\]?\s*\{(.+?)\}/mi]
@madsee_emitter ? @madsee_emitter.clear : @madsee_emitter = MA_SoundEmitter.new(@id)
@madsee_emitter.sound_type = $1.upcase.to_sym
@madsee_emitter.size_x = $2.to_i
@madsee_emitter.size_y = $3.to_i
props = $4.dup
props.gsub!(/(?<!file)name/i) { "filename" }
props.gsub!(/(?<!_)volume/i) { "max_volume" }
props.split(/[\n;]+/).each { |expression|
if expression[/\A\s*(.+?)\s*=\s*(.+?)\s*\Z/]
@madsee_emitter.send(:"#{$1.downcase}=", eval($2)) rescue msgbox("#{$1.downcase} is not a valid property for a Sound Emitting Event")
end
}
@madsee_emitter.audiofile.pitch = @madsee_emitter.calc_pitch
@madsee_emitter.reset_timer
@madsee_emitter = nil if @madsee_emitter.filename.empty?
else
@madsee_emitter.clear if @madsee_emitter
@madsee_emitter = nil
end
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Collect First Comment
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def ma_collect_init_comment
comment, i = "", 0
while !@list.nil? && (@list.code == 108 || @list.code == 408)
comment += @list.parameters[0] + "\n"
i += 1
end
comment
end unless self.method_defined?(:ma_collect_init_comment)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Frame Update
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias madsee_updt_1ex0 update
def update(*args)
madsee_updt_1ex0(*args) # Call original method
@madsee_emitter.update if @madsee_emitter
end
end
音量调节#==============================================================================
# ○サウンドコンフィグ
# for RGSS3
# 巫女瓜 / Space not far
# http://muspell.raindrop.jp/
# タイトル画面に音量調節機能を追加します。
#==============================================================================
module SoundConfig
FileName = "SoundConfig.rvdata2" # 音量調節の保存先
Span = 5 # 音量調節間隔。100の約数を推奨
Position = 2 # 位置 0:左上 1:右上 2:左下 3:右下
end
module RPG
#==============================================================================
# ■ AudioFile
#==============================================================================
class AudioFile
alias snf_volume_initialize initialize unless $@
def initialize(name = "", volume = 100, pitch = 100)
snf_volume_initialize(name, volume, pitch)
@base_volume = @volume
end
#--------------------------------------------------------------------------
# ● 音量変更
#--------------------------------------------------------------------------
def volume_change
@base_volume = @volume if @base_volume.nil?
@volume = (@base_volume * correction_value / 100)
end
#--------------------------------------------------------------------------
# ● 音量補正値の取得
#--------------------------------------------------------------------------
def correction_value
if self.is_a?(RPG::BGM) or self.is_a?(RPG::ME) or self.is_a?(RPG::BGS)
return SoundConfig.load(0)
elsif self.is_a?(RPG::SE)
return SoundConfig.load(1)
end
return 100
end
end
class BGS < AudioFile
alias snf_volume_play play unless $@
def play(pos = 0)
volume_change
snf_volume_play(pos)
end
end
class BGM < AudioFile
alias snf_volume_play play unless $@
def play(pos = 0)
volume_change
snf_volume_play(pos)
end
end
class SE < AudioFile
alias snf_volume_play play unless $@
def play
volume_change
snf_volume_play
end
end
class ME < AudioFile
alias snf_volume_play play unless $@
def play
volume_change
snf_volume_play
end
end
end
class Scene_Volume < Scene_MenuBase
#--------------------------------------------------------------------------
# ● 開始処理
#--------------------------------------------------------------------------
def start
super
create_soundconfig
end
#--------------------------------------------------------------------------
# ● 生成背景
#--------------------------------------------------------------------------
def create_background
@background_sprite = Sprite.new
@background_sprite.bitmap = SceneManager.background_bitmap
end
#--------------------------------------------------------------------------
# ● 释放背景
#--------------------------------------------------------------------------
def dispose_background
@background_sprite.dispose
@sprite_sound.dispose
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
super
if Input.repeat?(:LEFT)
vol = [bgm_vol - volume_span, 0].max
SoundConfig.save(0, vol)
Sound.play_cursor
refresh_soundconfig
RPG::BGM::last.play
end
if Input.repeat?(:RIGHT)
vol = [bgm_vol + volume_span, 100].min
SoundConfig.save(0, vol)
Sound.play_cursor
refresh_soundconfig
RPG::BGM::last.play
end
if Input.repeat?(:L)
vol = [se_vol - volume_span, 0].max
SoundConfig.save(1, vol)
Sound.play_cursor
refresh_soundconfig
end
if Input.repeat?(:R)
vol = [se_vol + volume_span, 100].min
SoundConfig.save(1, vol)
Sound.play_cursor
refresh_soundconfig
end
if Input.repeat?(:B)
return_scene
end
end
#--------------------------------------------------------------------------
# @ スプライト作成
#--------------------------------------------------------------------------
def create_soundconfig
@sprite_sound = Sprite.new
@sprite_sound.bitmap = Bitmap.new(Graphics.width, Graphics.height)
@sprite_sound.z = 150
refresh_soundconfig
end
def bgm_vol
return SoundConfig.load(0)
end
def se_vol
return SoundConfig.load(1)
end
def volume_span
return SoundConfig::Span
end
def refresh_soundconfig
@sprite_sound.bitmap.clear
@sprite_sound.bitmap.font.size = 12
@sprite_sound.bitmap.font.name = "MS ゴシック"
case SoundConfig::Position
when 0 #左上
align = 0
y = 4
when 1 #右上
align = 2
y = 4
when 2 #左下
align = 0
y = Graphics.height - 40
when 3 #右下
align = 2
y = Graphics.height - 40
end
@sprite_sound.bitmap.draw_text(4, y, Graphics.width - 8, 12, sprintf(" ← BGM %03d% →" , bgm_vol.to_s), align)
@sprite_sound.bitmap.draw_text(4, y + 12, Graphics.width - 8, 12, sprintf(" Q SE %03d% W" , se_vol.to_s), align)
@sprite_sound.bitmap.draw_text(4, y + 24, Graphics.width - 8, 12, " 按 X 返回", align)
end
end
module SoundConfig
def self.save(index, value)
data = self.loaddata
data[index] = value
file = File.open(FileName, "wb")
Marshal.dump(data, file)
file.close
end
def self.load(index)
data = self.loaddata
value = data[index] if data
if value.nil?
value = 100
self.save(index, value)
end
return value
end
def self.loaddata
if FileTest.exist?(FileName)
file = File.open(FileName, "r")
data = Marshal.load(file)
file.close
else
data = []
end
return data
end
end |
|