#————————————————————————————————————————
# ●Wormaps By.Lyaci
# *世界地图界面
# *使用说明
# -呼出界面 SceneManager.call(WMAPSET::Scene_WMAP)
# 界面快捷键默认 A 键
# -每个地图对应在世界地图的坐标在“地图备注名称”里设置
# 格式 MAP001<MX100,100> 即该地图在MX这个图上显示的坐标 x100 y100
# -更多请参考范例内容
# -Ver:1.0 Date:2014.6.25
# *地图传送
# -选中后按确认键传送,可以设置总体开关和独立地图的开关
# 总体开关为偷懒用,即打开了 未设置独立开关的地图都可以传送
# 和显示说明一样,在地图备注内设置
# 格式<MOV:X,Y,D,WID> XY对应坐标,D对应朝向(2,4,6,8)->>(下,左,右,上)
# WID对应独立传送的开关ID
# -Ver:1.1 Date:2014.6.25PM
# *重新定义全局传送开关概念
# 修正行走图错位问题
# -Ver:1.2 Date:2014.6.26
# *增加自动偏量范围与调试模式
# -参考坐标变为锁标中心点(CX,CY)
# -Ver:1.3 Date:2014.6.27
# *修正参考坐标出现负数问题 & 数据接口优化
# -Ver:1.3.1 & Ver:1.3.2 Date:2014.6.28
# *1.4更新
# -结构优化,文件夹统一化,主、偏量独立范围,增加蒙版响应图(可选)
# -主量格式追加为:MAP001<MX,X,Y,F> MX=地图文件 XY=显示坐标 F=范围(响应区)
# *蒙版可以为复杂的地方提供响应,F设置为0就可以不进行默认的范围描绘
# -蒙版需要在OFLOCK_COLOR设置对应地图ID的范围色
# -蒙版的文件名为 地图文件名 + _OF 找不到文件即不启用 *更多参考范例里“椰子”
# -Ver:1.4 Date:2014.7.12
# *实现无缝连接像素级分辨区域
# -Ver:1.4.5 Date:2014.7.14
#————————————————————————————————————————
module WMAPSET
#————————————————————————————————————————
#●设置
#————————————————————————————————————————
MAP_KEY = :C #快捷键设置
MAP_WSET = 1 #禁止/允许打开世界地图开关ID
MAP_VSET = 100 #设置新的世界地图文件名的变量ID
MAP_FILE = "世界地图" #初始的地图文件名
#————————————————————————————————————————
ICON_FILE = "micon" #锁标的文件名
ICON_XY_WIN = true #辅助坐标窗口是否生成
LOCKDIS = 5 #锁标每帧移动距离
CAP_SPEED = 40 #队长行走图更新帧周期
#Ver1.1—————————————————————————————————————
MAP_WMOVSET = 100 #公用地图传送开关ID
MAP_AMOVSET = 99 #全局传送开关ID(优先公用与独立开关)
LOCK_RES = true #是否开启呼吸效果
LOCK_FLASH = true #是否开启闪烁效果
LOCK_FLASH_C1 = Color.new(100,200,255,168) #闪烁色1
LOCK_FLASH_C2 = Color.new(255,200,100,168) #闪烁色2
LOCK_FLASH_SPEED = 48 #闪烁周期
#Ver1.3—————————————————————————————————————
OFLOCK = 80 #默认主、偏量范围(未手动设置范围即使用该值)
DEBUG = true #调试模式(蒙版、主量、偏量范围显示/关闭 F5按键取色)
LOCKMOV_SOUND_SPEED = 6 #锁标移动声音间隔帧
#Ver1.4—————————————————————————————————————
WMAPS_FOLDER = "Graphics/WMAP/" #存放所有资源的文件夹
#————————————————————————————————————————
#锁定偏量增加 [地图文件名,X,Y,偏量范围] => 地图ID
#偏量用于增加响应范围,按范围影响度自行调整
OFLOCK_XY = {
#第一张世界地图偏量(只是这个范例的)
["世界地图",170,80,20] => 19, #百元镇偏量
["世界地图",170,80,20] => 3, #百元大楼偏量
["世界地图",170,80,20] => 4, #百元镇偏量
["世界地图",170,80,20] => 5, #百元镇偏量
["世界地图",170,80,20] => 6, #百元镇偏量
["世界地图",170,80,20] => 7, #百元镇偏量
["世界地图",170,80,20] => 8, #百元镇偏量
["世界地图",170,80,20] => 9, #百元镇偏量
["世界地图",170,80,20] => 10, #百元镇偏量
["世界地图",170,80,20] => 17, #百元镇偏量
["世界地图",170,80,20] => 18, #百元镇偏量
["世界地图",170,110,20] => 20, #1号街道偏量
["世界地图",380,330] => 3, #神奇洞穴偏量
["世界地图",400,350] => 3, #神奇洞穴偏量
}
#Ver1.4.5————————————————————————————————————
#自定义地图对应的范围色 地图ID => 颜色
#*蒙版用到的范围颜色也在这添加,否则蒙版会不响应
#*为了方便设置蒙版色,调试模式开启时F5键可以取得当前锁标中心范围色
OFLOCK_COLOR = {
19 => Color.new(255,0,0,84), #百元镇的范围为红色
}
#————————————————————————————————————————
# ●Scene_WMAP
# *界面生成
#————————————————————————————————————————
class Scene_WMAP
#———————————————————————————————————————
#数据内容
#———————————————————————————————————————
def data
#———————————————————————————————————————
#常量
@graphics_w = Graphics.width
@graphics_h = Graphics.height
#———————————————————————————————————————
#生成背景
map_back
#———————————————————————————————————————
#生成地图
spr_map_ini
#———————————————————————————————————————
#生成锁标
spr_lock_ini
#———————————————————————————————————————
#锁标地址数据
LOCKCOM.com(@map)
@comx,@comy,@comf,@comi = LOCKCOM.comdata(@map)
@comofc = LOCKCOM.comofc(@map)
@comide = LOCKCOM.comide(@map)
#———————————————————————————————————————
#生成范围
spr_of_ini
#———————————————————————————————————————
#锁标初始坐标
lock_xy_ini
#———————————————————————————————————————
#生成锁标坐标显示窗口
win_lockxy_ini
#生成地图信息显示窗口
win_mapint_ini
#———————————————————————————————————————
#生成队长
spr_cap_ini
#———————————————————————————————————————
update_map_int_yof
end
#———————————————————————————————————————
#主循环
#———————————————————————————————————————
def main
#准备数据
data
#执行过渡
Graphics.transition
#进行更新
update until SceneManager.scene != self
#准备过渡
Graphics.freeze
#释放全部
dispose
end
#———————————————————————————————————————
#主更新
#———————————————————————————————————————
def update
update_GI
update_input
update_lock_flash if LOCK_FLASH
update_lock_zoom if LOCK_RES
end
#———————————————————————————————————————
#画面、输入更新
#———————————————————————————————————————
def update_GI
Graphics.update
Input.update
update_cap
end
#———————————————————————————————————————
#数据更新
#———————————————————————————————————————
def update_data
update_lms
update_oflock
update_map_int_yof
refresh_window_lock_xy
end
#———————————————————————————————————————
#按键更新
#———————————————————————————————————————
def update_input
if Input.press?(:DOWN)
@lock_dy += LOCKDIS ; if @lock_dy <= @graphics_h-@lock_h
@spr_lock.y += LOCKDIS
@lock_dy = @lock_y = @spr_lock.y ; lock_mov = true ; end
end
if Input.press?(:UP)
@lock_dy -= LOCKDIS ; if @lock_dy >= 0
@spr_lock.y -= LOCKDIS
@lock_dy = @lock_y = @spr_lock.y ; lock_mov = true ; end
end
if Input.press?(:LEFT)
@lock_dx -= LOCKDIS ; if @lock_dx >= 0
@spr_lock.x -= LOCKDIS
@lock_dx = @lock_x = @spr_lock.x ; lock_mov = true ; end
end
if Input.press?(:RIGHT)
@lock_dx += LOCKDIS ; if @lock_dx <= @graphics_w-@lock_w
@spr_lock.x += LOCKDIS
@lock_dx = @lock_x = @spr_lock.x ; lock_mov = true ; end
end
if Input.trigger?(:C)
map_mov(lock_map_id)
end
if Input.trigger?(:B) or Input.trigger?(MAP_KEY)
SceneManager.return
end
if Input.trigger?(:F5) && DEBUG
p @bit_mapof.get_pixel(@lock_cx,@lock_cy)
end
if lock_mov
update_data
lock_mov = false
end
end
#———————————————————————————————————————
#范围更新
#———————————————————————————————————————
def update_oflock ; new_cxy
if @bit_mapof.get_pixel(@lock_cx,@lock_cy).alpha != 0
@new_map_id = lock_map_id
if @new_map_id != @now_map_id
@now_map_id = @new_map_id
update_lock_xy(@now_map_id)
end
else
@now_map_id = nil ; update_lock_xy(nil)
end
end
#———————————————————————————————————————
#更新锁标移动声音
#———————————————————————————————————————
def update_lms
@lock_mov_dsc += 1
if @lock_mov_dsc == LOCKMOV_SOUND_SPEED
@lock_mov_dsc = 0 ; Sound.play_cursor ; end
end
#———————————————————————————————————————
#锁标地址更新
#———————————————————————————————————————
def update_lock_xy(map_id)
if map_id
refresh_window_map_int(map_id)
@wint_clear = false
else
unless @wint_clear
@window_map_int.contents.clear
@wint_clear = true
end
end
end
#———————————————————————————————————————
#地图信息窗口坐标更新
#———————————————————————————————————————
def update_map_int_yof
if @spr_lock.y >= @graphics_h - @lock_h - 96
@window_map_int.y = 0 ; win_lock_y_set(100) ; else
@window_map_int.y = @graphics_h - 96 ; win_lock_y_set(240) ; end
end
#———————————————————————————————————————
#更新队长动作
#———————————————————————————————————————
def update_cap
@cap_dsc += 1
if @cap_dsc == CAP_SPEED ; @cap_index += 1 ; @cap_dsc = 0
@cap_index = 0 if @cap_index >= 3
@spr_cap.src_rect.x = @zx+@cw*@cap_index ; end
end
#———————————————————————————————————————
#更新锁标“呼吸”
#———————————————————————————————————————
def update_lock_zoom
if @lock_zoom_mr
@spr_lock.zoom_x += 0.01 ; @spr_lock.zoom_y += 0.01
@lock_zoom_mr = false if @spr_lock.zoom_x >= 1.1 ; else
@spr_lock.zoom_x -= 0.01 ; @spr_lock.zoom_y -= 0.01
@lock_zoom_mr = true if @spr_lock.zoom_x <= 0.9
end
end
#———————————————————————————————————————
#更新锁标闪烁
#———————————————————————————————————————
def update_lock_flash
@spr_lock.update ; @lock_flash_dsc += 1
if @lock_flash_dsc == LOCK_FLASH_SPEED
@lock_flash_dsc = 0 ; @lock_flash_wb = !@lock_flash_wb
color = @lock_flash_wb ? LOCK_FLASH_C1 : LOCK_FLASH_C2
@spr_lock.flash(color,LOCK_FLASH_SPEED)
end
end
#———————————————————————————————————————
#地图精灵
#———————————————————————————————————————
def spr_map_ini
@spr_map = Sprite.new
@map = $game_variables[MAP_VSET] == 0 ? MAP_FILE :
$game_variables[MAP_VSET]
@map_id = $game_map.instance_variable_get(:@map_id)
@spr_map.bitmap = Bitmap.new(WMAPS_FOLDER+@map)
end
#———————————————————————————————————————
#锁标精灵
#———————————————————————————————————————
def spr_lock_ini
@spr_lock = Sprite.new
@spr_lock.bitmap = Bitmap.new(WMAPS_FOLDER+ICON_FILE)
#锁标变量
@lock_x = 0 ; @lock_y = 0 ; @lock_dx = 0 ; @lock_dy = 0
@near_min = [] ; @lock_mov_dsc = 0
@lock_w = @spr_lock.bitmap.width ; @lock_h = @spr_lock.bitmap.height
@lock_mw = @lock_w*0.5 ; @lock_mh = @lock_h*0.5
@lock_flash_dsc = 0 ; @lock_flash_wb = false ; @lock_zoom_mr = true
end
#———————————————————————————————————————
#锁标初始坐标
#———————————————————————————————————————
def lock_xy_ini
lock_xy = LOCKCOM.commxy(@map,@map_id)
@near_x = lock_xy[0].to_i ; @near_y = lock_xy[1].to_i
@spr_lock.x = @lock_x = @lock_dx = @near_x - @lock_mw
@spr_lock.y = @lock_y = @lock_dy = @near_y - @lock_mh ; new_cxy
end
#———————————————————————————————————————
#队长精灵
#———————————————————————————————————————
def spr_cap_ini
#生成队长
@spr_cap = Sprite.new
cap = $game_party.members[0]
cap_name = cap ? cap.character_name : "雷鸣"
cap_index = cap ? cap.character_index : 0
@spr_cap.bitmap = Bitmap.new("Graphics/Characters/"+cap_name)
cenx = @lock_x + @lock_w*0.16
ceny = @lock_y + @lock_h*0.16
@spr_cap.x,@spr_cap.y = cenx,ceny
#捕捉位置
@cw = @spr_cap.bitmap.width / 12 ; @ch = @spr_cap.bitmap.height / 8
@zx = (cap_index%4*3)*@cw ; @zy = (cap_index/4*4)*@ch
#位图矩形
@spr_cap.src_rect = Rect.new(@zx, @zy, @cw, @ch)
#更新数据
@cap_dsc = 0 ; @cap_index = 0
end
#———————————————————————————————————————
#锁标坐标窗口
#———————————————————————————————————————
def win_lockxy_ini
return unless ICON_XY_WIN
@window_lock_xy_false = Window_Base.new(0,240,260,78)
@window_lock_xy_false.opacity = 0
c1 = Color.new(255,255,255,128)
c2 = Color.new(255,255,255,0)
@window_lock_xy_false.contents.gradient_fill_rect(0, 0, 260, 24, c1, c2)
@window_lock_xy_false.contents.gradient_fill_rect(0, 26, 260, 24, c1, c2)
@window_lock_xy = Window_Base.new(0,240,260,78)
@window_lock_xy.opacity = 0
refresh_window_lock_xy
end
#———————————————————————————————————————
#地图信息窗口
#———————————————————————————————————————
def win_mapint_ini
@window_map_int = Window_Base.new(0,0,@graphics_w,96)
#更新地图信息
map_id = lock_map_id
if map_id
refresh_window_map_int(map_id)
@now_map_id = map_id
else
@now_map_id = nil
end
end
#———————————————————————————————————————
#绘制地图信息
#———————————————————————————————————————
def refresh_window_map_int(map_id)
note = LOCKCOM.comnote(map_id)
/<INF:(.*?)>/ =~ note.gsub(/\n/){"\\n"}
return unless $1
Sound.play_recovery
note = $1.gsub(/\\n/){"\n"}
@window_map_int.contents.clear
@window_map_int.draw_text_ex(4,0,note)
end
#———————————————————————————————————————
#绘制锁标地址
#———————————————————————————————————————
def refresh_window_lock_xy
return unless ICON_XY_WIN
x,y = @lock_x,@lock_y ; cx = @lock_cx ; cy = @lock_cy
@window_lock_xy.contents.clear
@window_lock_xy.contents.draw_text(2,0,220,24,"X:#{x} Y:#{y}")
@window_lock_xy.contents.draw_text(2,24,220,24,"CX:#{cx} CY:#{cy}")
end
#———————————————————————————————————————
#设置坐标位置(Y)
#———————————————————————————————————————
def win_lock_y_set(y)
return unless ICON_XY_WIN
@window_lock_xy.y = y
@window_lock_xy_false.y = y
end
#———————————————————————————————————————
#生成背景
#———————————————————————————————————————
def map_back
@map_back = Sprite.new
@map_back.bitmap = SceneManager.background_bitmap
@map_back.color.set(16, 16, 16, 128)
end
#———————————————————————————————————————
#处理场景移动
#———————————————————————————————————————
def map_mov(map_id)
return unless map_id
mov_data = []
note = LOCKCOM.comnote(map_id)
/<MOV:(.*?)>/ =~ note
return Sound.play_buzzer unless $1
$1.scan(/\d+/) {|xy| mov_data << xy.to_i}
x,y,d,swi = *mov_data
swi = swi ? $game_switches[swi] : $game_switches[MAP_WMOVSET]
if swi && $game_switches[MAP_AMOVSET]
$game_player.reserve_transfer(map_id, x, y, d)
$game_player.perform_transfer
Sound.play_use_skill ; SceneManager.return ; else
Sound.play_buzzer ; end
end
#———————————————————————————————————————
#获取当前锁定的地图ID
#———————————————————————————————————————
def lock_map_id
@comide[@bit_mapof.get_pixel(@lock_cx,@lock_cy).to_s]
end
#———————————————————————————————————————
#更新锁标中心位置
#———————————————————————————————————————
def new_cxy
@lock_cx = @lock_x + @lock_mw
@lock_cy = @lock_y + @lock_mh
end
#———————————————————————————————————————
#生成范围
#———————————————————————————————————————
def spr_of_ini
@spr_mapof = Sprite.new
@spr_mapof.bitmap = Bitmap.new(@graphics_w,@graphics_h)
@bit_mapof = @spr_mapof.bitmap
debug(DEBUG)
of_file = WMAPS_FOLDER+@map+"_OF.png"
if FileTest.file?(of_file)
of_bitmap = Bitmap.new(of_file)
@bit_mapof.blt(0,0,of_bitmap,Rect.new(0,0,@graphics_w,@graphics_h))
of_bitmap.dispose
end
@comx.each_with_index {|x,i|
f = @comf[i] ; y = @comy[i] ; id = @comi[i]
color = @comofc[id]
@bit_mapof.fill_rect(x-f/2,y-f/2,f,f,color)
if DEBUG
color = Color.new(color.red,color.green,color.blue)
@spr_debug.bitmap.fill_rect(x-f/2,y,f,1,color)
@spr_debug.bitmap.fill_rect(x,y-f/2,1,f,color)
end }
end
#———————————————————————————————————————
#调试模式
#———————————————————————————————————————
def debug(tf)
if tf
@spr_debug = Sprite.new
@spr_debug.bitmap = Bitmap.new(@graphics_w,@graphics_h)
@spr_lock.bitmap.fill_rect(@lock_mw,@lock_mh,1,1,Color.new(0,0,0,255))
else ; @spr_mapof.visible = false ; end
end
#———————————————————————————————————————
#释放全部
#———————————————————————————————————————
def dispose
@map_back.bitmap.dispose
@spr_map.bitmap.dispose
@spr_lock.bitmap.dispose
@spr_cap.bitmap.dispose
@spr_map.dispose ; @spr_lock.dispose
@spr_cap.dispose ; @map_back.dispose
@window_map_int.dispose
@window_lock_xy.dispose if ICON_XY_WIN
@window_lock_xy_false.dispose if ICON_XY_WIN
@spr_debug.bitmap.dispose if DEBUG
@spr_debug.dispose if DEBUG
@spr_mapof.bitmap.dispose
@spr_mapof.dispose
end
end ; end
#———————————————————————————————————————
#●LOCKCOM
# *处理全部地图锁标的模块
#———————————————————————————————————————
module LOCKCOM
#———————————————————————————————————————
#载入偏量地址源
def self.com_set
@com = {} ; @rof = {}
WMAPSET::OFLOCK_XY.each {|key,id|
com=key[0,3] ; f = key[3] ; rof = f.nil? ? WMAPSET::OFLOCK : f
@com[com] = id ; @rof[com] = rof } ; @com
end
#读取全部主、偏量地址源
def self.com(map)
@com ||= LOCKCOM.com_set
@map ||= Array.new
unless @map.include?(map) ; @map << map
$data_mapinfos.each {|id,v|
/<#{map}(.*?)>/ =~ v.name ; if $1
cof=[map] ; $1.scan(/\d+/) {|xy| cof << xy.to_i }
com=cof[0,3] ; f = cof[3] ; rof = f.nil? ? WMAPSET::OFLOCK : f
@com[com] = id ; @rof[com] = rof ; end } ; end
end
#———————————————————————————————————————
#分析地址源为标准数据
def self.comdata(map)
@comxy ||= {}
@comofc ||= {}
@comide ||= {}
unless @comxy.has_key?(map)
x,y,f,i=[],[],[],[]
@comofc[map] = {}
@comide[map] = {}
oc = WMAPSET::OFLOCK_COLOR
@com.each {|key,map_id|
if key[0] == map
unless @comofc[map][map_id]
if oc[map_id] ; LOCKCOM.comio_set(map,map_id,oc[map_id])
else ; LOCKCOM.comio_rc(map,map_id) ; end
end
x<<key[1];y<<key[-1];f<<@rof[key];i<<map_id
end }
@comxy[map] = [x,y,f,i] ; end ; return *@comxy[map]
end
def self.comio_rc(map,map_id)
loop { color = LOCKCOM.color
unless @comofc[map].has_value?(color)
LOCKCOM.comio_set(map,map_id,color) ; break ; end }
end
def self.comio_set(map,map_id,color)
@comide[map][color.to_s] = map_id
@comofc[map][map_id] = color
end
#———————————————————————————————————————
#读取指定地图主量坐标
def self.commxy(map,map_id)
map_id = map_id ; until $1
/<#{map}(.*?)>/ =~ $data_mapinfos[map_id].name
map_id = $data_mapinfos[map_id].parent_id unless $1
break if map_id == 0 ; end ; $1 ? $1.split(",") : 0
end
#———————————————————————————————————————
#读取指定地图的备注
def self.comnote(map_id)
@comnote ||= {}
unless @comnote.has_key?(map_id)
note = load_data(sprintf("Data/Map%03d.rvdata2", map_id)).note
@comnote[map_id] = note ; end ; @comnote[map_id]
end
#———————————————————————————————————————
#取得范围色、范围色识别串
def self.comofc(map)
@comofc[map]
end
def self.comide(map)
@comide[map]
end
def self.color
Color.new(rand(255),rand(255),rand(255),84)
end
end
#———————————————————————————————————————
#●Scene_Map
#———————————————————————————————————————
class Scene_Map < Scene_Base
alias :n_update :update
def update
n_update
if Input.trigger?(WMAPSET::MAP_KEY) ; if $game_switches[WMAPSET::MAP_WSET]
Sound.play_ok ; SceneManager.call(WMAPSET::Scene_WMAP)
else ; Sound.play_buzzer ; end
end
end
end