大家好,欢迎来到IT知识分享网。
目录
无需多言,很轻松就能知道这是个管理游戏地图的类。本类在游戏中对应且仅对应全局变量$game_map,因为在游戏中仅仅能存在一张地图,也就是角色所在的地图。
Game_Map类代码解析
#============================================================================== # ■ Game_Map #------------------------------------------------------------------------------ # 处理地图的类。包含卷动以及可以通行的判断功能。 # 本类的实例请参考 $game_map 。 #============================================================================== class Game_Map #-------------------------------------------------------------------------- # ● 定义实例变量 #-------------------------------------------------------------------------- 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 SX为x方向的自动滚动速度 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 end #-------------------------------------------------------------------------- # ● 设置 # map_id : 地图 ID #-------------------------------------------------------------------------- def setup(map_id) # 地图 ID 记录到 @map_id @map_id = map_id # 地图文件装载后、设置到 @map @map = load_data(sprintf("Data/Map%03d.rxdata", @map_id)) sprintf的定义可以参考C语言中的sprintf,就是格式化字符串 # 定义实例变量设置地图元件信息 tileset = $data_tilesets[@map.tileset_id] 获取本地图使用的图块实例RPG::Tileset @tileset_name = tileset.tileset_name 以下参照RPG::Tileset的定义 @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 @map.events是一个关于RPG::Event的哈希表 @events[i] = Game_Event.new(@map_id, @map.events[i]) 实例化事件 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) Tone是有关色调的RGSS内部类 雾原本的颜色 @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 请注意这里的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 15为屏幕的高度(图块单位),128为滚动一格display_*变动的值 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 20为屏幕的宽度 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 <<是移位操作 11110&0 # 循环全部的事件 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 Game_Event.@through 是否能被穿透的标记 # 如果障碍物的接触被设置的情况下 if @passages[event.tile_id] & bit != 0 这个事件对应的图块id的通行表与障碍物的方向 # 不能通行 return false # 如果全方向的障碍物的接触被设置的情况下 elsif @passages[event.tile_id] & 0x0f == 0x0f 0X0F是全方向不可通行(0x01+0x02+0x04+0x08)=(11110)2 # 不能通行 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] 本坐标上的第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 茂密标志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 柜台标志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) duration是持续的帧数 @fog_tone_target = tone.clone tone是一个RGB+颜色浓度(灰)的数组 @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 也就是地图滚动速度为速度值*2 图块/帧 # 执行滚动 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 滚动速度为此方向上的自动滚动速度/8 图块/帧 可以看出初始化的雾是向右滚动的 @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
关于角色朝向与判断是否通行的函数
本类中用于判断能否通行的方法passable?对于角色(事件)的一次行动(上下左右走动)会调用两次(在Game_Character中),第一次其参数d1为[0,2,4,6,8,10],用于判断;第二次其参数d2为[0,1,2,4,8,0](d2=10-d1),用于判断角色在目标点图块的此方向是否可通行。
至于RPG::Tileset类的属性passages如何判断通行度等参数,可以查看前文中关于本类的解析。对于passages而言,我们先将其转换为八位二进制,然后与目标数进行与操作,就可知其是否满足条件。
关于@events与其初始化
如图:
@map先使用Map.rxdata里的RPG::Event对象集合赋值,之后遍历@map根据其中的对象属性生成Game_Event对象放入@events内。
所以@events是Game_Event对象的集合。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/118082.html

