#==============================================================================
# ■ Game_Map
#------------------------------------------------------------------------------
# 处理地图的类。包含卷动以及可以通行的判断功能。
# 本类的实例请参考 $game_map 。
#==============================================================================
class Game_Map
EventID = [11,12,13]
#--------------------------------------------------------------------------
# ● 定义实例变量
#--------------------------------------------------------------------------
attr_accessor :tileset_name # 元件 文件名
attr_accessor :autotile_names # 自动元件 文件名
attr_accessor :panorama_name # 全景 文件名
attr_accessor :panorama_hue # 全景 色相
attr_accessor :fog_name # 雾 文件名
attr_accessor :fog_hue # 雾 色相
attr_accessor :fog_opacity # 雾 不透明度
attr_accessor :fog_blend_type # 雾 混合方式
attr_accessor :fog_zoom # 雾 放大率
attr_accessor :fog_sx # 雾 SX
attr_accessor :fog_sy # 雾 SY
attr_accessor :battleback_name # 战斗背景 文件名
attr_accessor :display_x # 显示 X 坐标 * 128
attr_accessor :display_y # 显示 Y 坐标 * 128
attr_accessor :need_refresh # 刷新要求标志
attr_reader :passages # 通行表
attr_reader :priorities # 优先表
attr_reader :terrain_tags # 地形标记表
attr_reader :events # 事件
attr_reader :fog_ox # 雾 原点 X 坐标
attr_reader :fog_oy # 雾 原点 Y 坐标
attr_reader :fog_tone # 雾 色调
#--------------------------------------------------------------------------
# ● 初始化条件
#--------------------------------------------------------------------------
def initialize
@map_id = 0
@display_x = 0
@display_y = 0
@events_set = {}
end
#--------------------------------------------------------------------------
# ● 设置
# map_id : 地图 ID
#--------------------------------------------------------------------------
def setup(map_id)
# 地图 ID 记录到 @map_id
if @map
for i in @map.events.keys
next if !EventID.include?(i)
@events_set[@map_id] ||= {}
@events_set[@map_id][i] = [@events[i].x, @events[i].y]
end
end
@map_id = map_id
# 地图文件装载后、设置到 @map
@map = load_data(sprintf("Data/Map%03d.rxdata", @map_id))
# 定义实例变量设置地图元件信息
tileset = $data_tilesets[@map.tileset_id]
@tileset_name = tileset.tileset_name
@autotile_names = tileset.autotile_names
@panorama_name = tileset.panorama_name
@panorama_hue = tileset.panorama_hue
@fog_name = tileset.fog_name
@fog_hue = tileset.fog_hue
@fog_opacity = tileset.fog_opacity
@fog_blend_type = tileset.fog_blend_type
@fog_zoom = tileset.fog_zoom
@fog_sx = tileset.fog_sx
@fog_sy = tileset.fog_sy
@battleback_name = tileset.battleback_name
@passages = tileset.passages
@priorities = tileset.priorities
@terrain_tags = tileset.terrain_tags
# 初始化显示坐标
@display_x = 0
@display_y = 0
# 清除刷新要求标志
@need_refresh = false
# 设置地图事件数据
@events = {}
for i in @map.events.keys
@events[i] = Game_Event.new(@map_id, @map.events[i])
if @events_set[@map_id]
p @events_set[@map_id]
@events[i].moveto(*@events_set[@map_id][i]) if @events_set[@map_id][i]
else
@events_set[@map_id] = {}
end
end
# 设置公共事件数据
@common_events = {}
for i in 1...$data_common_events.size
@common_events[i] = Game_CommonEvent.new(i)
end
# 初始化雾的各种信息
@fog_ox = 0
@fog_oy = 0
@fog_tone = Tone.new(0, 0, 0, 0)
@fog_tone_target = Tone.new(0, 0, 0, 0)
@fog_tone_duration = 0
@fog_opacity_duration = 0
@fog_opacity_target = 0
# 初始化滚动信息
@scroll_direction = 2
@scroll_rest = 0
@scroll_speed = 4
end
#--------------------------------------------------------------------------
# ● 获取地图 ID
#--------------------------------------------------------------------------
def map_id
return @map_id
end
#--------------------------------------------------------------------------
# ● 获取宽度
#--------------------------------------------------------------------------
def width
return @map.width
end
#--------------------------------------------------------------------------
# ● 获取高度
#--------------------------------------------------------------------------
def height
return @map.height
end
#--------------------------------------------------------------------------
# ● 获取遇敌列表
#--------------------------------------------------------------------------
def encounter_list
return @map.encounter_list
end
#--------------------------------------------------------------------------
# ● 获取遇敌步数
#--------------------------------------------------------------------------
def encounter_step
return @map.encounter_step
end
#--------------------------------------------------------------------------
# ● 获取地图数据
#--------------------------------------------------------------------------
def data
return @map.data
end
#--------------------------------------------------------------------------
# ● BGM / BGS 自动切换
#--------------------------------------------------------------------------
def autoplay
if @map.autoplay_bgm
$game_system.bgm_play(@map.bgm)
end
if @map.autoplay_bgs
$game_system.bgs_play(@map.bgs)
end
end
#--------------------------------------------------------------------------
# ● 刷新
#--------------------------------------------------------------------------
def refresh
# 地图 ID 有效
if @map_id > 0
# 刷新全部的地图事件
for event in @events.values
event.refresh
end
# 刷新全部的公共事件
for common_event in @common_events.values
common_event.refresh
end
end
# 清除刷新要求标志
@need_refresh = false
end
#--------------------------------------------------------------------------
# ● 向下滚动
# distance : 滚动距离
#--------------------------------------------------------------------------
def scroll_down(distance)
@display_y = [@display_y + distance, (self.height - 15) * 128].min
end
#--------------------------------------------------------------------------
# ● 向左滚动
# distance : 滚动距离
#--------------------------------------------------------------------------
def scroll_left(distance)
@display_x = [@display_x - distance, 0].max
end
#--------------------------------------------------------------------------
# ● 向右滚动
# distance : 滚动距离
#--------------------------------------------------------------------------
def scroll_right(distance)
@display_x = [@display_x + distance, (self.width - 20) * 128].min
end
#--------------------------------------------------------------------------
# ● 向上滚动
# distance : 滚动距离
#--------------------------------------------------------------------------
def scroll_up(distance)
@display_y = [@display_y - distance, 0].max
end
#--------------------------------------------------------------------------
# ● 有效坐标判定
# x : X 坐标
# y : Y 坐标
#--------------------------------------------------------------------------
def valid?(x, y)
return (x >= 0 and x < width and y >= 0 and y < height)
end
#--------------------------------------------------------------------------
# ● 可以通行判定
# x : X 坐标
# y : Y 坐标
# d : 方向 (0,2,4,6,8,10)
# ※ 0,10 = 全方向不能通行的情况的判定 (跳跃等)
# self_event : 自己 (判定事件可以通行的情况下)
#--------------------------------------------------------------------------
def passable?(x, y, d, self_event = nil)
# 被给予的坐标地图外的情况下
unless valid?(x, y)
# 不能通行
return false
end
# 方向 (0,2,4,6,8,10) 与障碍物接触 (0,1,2,4,8,0) 后变换
bit = (1 << (d / 2 - 1)) & 0x0f
# 循环全部的事件
for event in events.values
# 自己以外的元件与坐标相同的情况
if event.tile_id >= 0 and event != self_event and
event.x == x and event.y == y and not event.through
# 如果障碍物的接触被设置的情况下
if @passages[event.tile_id] & bit != 0
# 不能通行
return false
# 如果全方向的障碍物的接触被设置的情况下
elsif @passages[event.tile_id] & 0x0f == 0x0f
# 不能通行
return false
# 这以外的优先度为 0 的情况下
elsif @priorities[event.tile_id] == 0
# 可以通行
return true
end
end
end
# 从层按从上到下的顺序调查循环
for i in [2, 1, 0]
# 取得元件 ID
tile_id = data[x, y, i]
# 取得元件 ID 失败
if tile_id == nil
# 不能通行
return false
# 如果障碍物的接触被设置的情况下
elsif @passages[tile_id] & bit != 0
# 不能通行
return false
# 如果全方向的障碍物的接触被设置的情况下
elsif @passages[tile_id] & 0x0f == 0x0f
# 不能通行
return false
# 这以外的优先度为 0 的情况下
elsif @priorities[tile_id] == 0
# 可以通行
return true
end
end
# 可以通行
return true
end
#--------------------------------------------------------------------------
# ● 茂密判定
# x : X 坐标
# y : Y 坐标
#--------------------------------------------------------------------------
def bush?(x, y)
if @map_id != 0
for i in [2, 1, 0]
tile_id = data[x, y, i]
if tile_id == nil
return false
elsif @passages[tile_id] & 0x40 == 0x40
return true
end
end
end
return false
end
#--------------------------------------------------------------------------
# ● 反击判定
# x : X 坐标
# y : Y 坐标
#--------------------------------------------------------------------------
def counter?(x, y)
if @map_id != 0
for i in [2, 1, 0]
tile_id = data[x, y, i]
if tile_id == nil
return false
elsif @passages[tile_id] & 0x80 == 0x80
return true
end
end
end
return false
end
#--------------------------------------------------------------------------
# ● 地获取地形标志
# x : X 坐标
# y : Y 坐标
#--------------------------------------------------------------------------
def terrain_tag(x, y)
if @map_id != 0
for i in [2, 1, 0]
tile_id = data[x, y, i]
if tile_id == nil
return 0
elsif @terrain_tags[tile_id] > 0
return @terrain_tags[tile_id]
end
end
end
return 0
end
#--------------------------------------------------------------------------
# ● 获取指定位置的事件 ID
# x : X 坐标
# y : Y 坐标
#--------------------------------------------------------------------------
def check_event(x, y)
for event in $game_map.events.values
if event.x == x and event.y == y
return event.id
end
end
end
#--------------------------------------------------------------------------
# ● 滚动开始
# direction : 滚动方向
# distance : 滚动距离
# speed : 滚动速度
#--------------------------------------------------------------------------
def start_scroll(direction, distance, speed)
@scroll_direction = direction
@scroll_rest = distance * 128
@scroll_speed = speed
end
#--------------------------------------------------------------------------
# ● 滚动中判定
#--------------------------------------------------------------------------
def scrolling?
return @scroll_rest > 0
end
#--------------------------------------------------------------------------
# ● 开始变更雾的色调
# tone : 色调
# duration : 时间
#--------------------------------------------------------------------------
def start_fog_tone_change(tone, duration)
@fog_tone_target = tone.clone
@fog_tone_duration = duration
if @fog_tone_duration == 0
@fog_tone = @fog_tone_target.clone
end
end
#--------------------------------------------------------------------------
# ● 开始变更雾的不透明度
# opacity : 不透明度
# duration : 时间
#--------------------------------------------------------------------------
def start_fog_opacity_change(opacity, duration)
@fog_opacity_target = opacity * 1.0
@fog_opacity_duration = duration
if @fog_opacity_duration == 0
@fog_opacity = @fog_opacity_target
end
end
#--------------------------------------------------------------------------
# ● 刷新画面
#--------------------------------------------------------------------------
def update
# 还原必要的地图
if $game_map.need_refresh
refresh
end
# 滚动中的情况下
if @scroll_rest > 0
# 滚动速度变化为地图坐标系的距离
distance = 2 ** @scroll_speed
# 执行滚动
case @scroll_direction
when 2 # 下
scroll_down(distance)
when 4 # 左
scroll_left(distance)
when 6 # 右
scroll_right(distance)
when 8 # 上
scroll_up(distance)
end
# 滚动距离的减法运算
@scroll_rest -= distance
end
# 更新地图事件
for event in @events.values
event.update
end
# 更新公共事件
for common_event in @common_events.values
common_event.update
end
# 处理雾的滚动
@fog_ox -= @fog_sx / 8.0
@fog_oy -= @fog_sy / 8.0
# 处理雾的色调变更
if @fog_tone_duration >= 1
d = @fog_tone_duration
target = @fog_tone_target
@fog_tone.red = (@fog_tone.red * (d - 1) + target.red) / d
@fog_tone.green = (@fog_tone.green * (d - 1) + target.green) / d
@fog_tone.blue = (@fog_tone.blue * (d - 1) + target.blue) / d
@fog_tone.gray = (@fog_tone.gray * (d - 1) + target.gray) / d
@fog_tone_duration -= 1
end
# 处理雾的不透明度变更
if @fog_opacity_duration >= 1
d = @fog_opacity_duration
@fog_opacity = (@fog_opacity * (d - 1) + @fog_opacity_target) / d
@fog_opacity_duration -= 1
end
end
end