# # マップ軽量化スクリプト  v1.06a2 by tonbi # # # # ・使い方 # # Scene_Debug より下、Main より上に、新規セッションを作って、 # この文章全部を貼り付けてください。 # # このスクリプトを使用することで、 # マップの通行判定、イベント取得、キャラ描画 # といった処理が高速化します。 # 高速化するだけなので、何かができるようになるってことはありません。 # # ・置物タイプイベント・ # # さらに、イベントの処理の高速化として、「置物」タイプを使用可能です # イベントの最初のページの開始条件に変数何か(何でもOK)-99999999 以上 # と、設定するか、または、イベント名に"????,置物"と、","に続いて"置物" # と書いてください。この置物イベントは、移動、ページ変更、グラフィック # 変更等、何もできません。が、イベントの実行自体は、開始条件「決定ボタン」 # か「プレイヤーから接触」で実行することができます。 # つまり、調べたら「唯の屍のようだ」や、触れたら「ダメージぐさっ」などは # 可能です。また、マップに入った瞬間のページ固定なんで、一応2ページ以降も # 使えます。 # # ・最背面に表示・ # # 最初のページの実行リストの一番初めを「注釈:再背面に表示」としてください。 # 常に主人公の下に表示されるようになります。ワナや屍などは、これを指定する # ことで、多少表示が速くなります。 # ほかにも、セーブ魔方陣や死体蹂躙イベントなどにどうぞ # # ・画面移動しない設定・ # # マップのサイズが20*15なときや、イベントメニュー画面、イベント戦闘などで、 # 画面が絶対動かないときに指定してください。置物タイプの処理が極めて早く # なります。マップサイズが20*15のときはオートでオン。マップ移動時はオフに # # # 以下のコマンドが、イベント>>スクリプト実行 で使えるようになります。 # あとでイベント中から変更する際に使ってください。 # (id)にはそれを適用するイベントIDを入れてください。 # 省略時は、そのスクリプトを実行したイベント自信になります # # 例 event_refresh >> このイベントのページ更新。 # event_bottom_off(50) >> イベントID:50のイベントを再背面に。 # # # # 指定イベントを置物に設定する # event_off(id) # # 指定イベントの置物を解除する # event_on(id) # # 置物イベントのページを更新する # event_refresh(id) # # 最背面に表示をオフにする # draw_bottom_off(id) # # 最背面に表示をオンにする # draw_bottom_on(id) # # 画面位置移動オンにする # move_display_on # # 画面位置移動オフにする # move_display_off # # # # # あと、使用する際は、↓の部分を必用に応じて書き換えてください。 class Game_Character DRAWRANGEX = 14 *128 # マップキャラのスプライトを更新する距離(タイル単位) DRAWRANGEY = 12 *128 # かなり大きいキャラチップを使う場合は増やしてください。 # X:14 Y:12前後推奨 *128は変えないでください # ちなみに上がX(横)下がY(縦)です。 MOVERANGE = 50 *128 # イベントの移動タイプ「ランダム」「近づく」の稼動範囲 # これより遠い場合は動きません。 # マップサイズより大入れると無効 # ルートの指定でのランダム等には影響しません。 # 50前後推奨 *128は変えないでください end class Game_Map OBJECT_WORD = "置物" # イベント名に、"???,置物" と入れると、置物として扱う。 # この文字を変更すると、↑の置物と言う条件がかわる。 BOTTOM_WORD = "最背面に表示" # イベントの最初のページに、注釈として # "最背面に表示" と入れると、常に主人公の下に表示(Z=0) # セーブ魔方陣や死体蹂躙イベントなどにどうぞ。 # スプライトの重ね合わせ計算しない分早いです。 end # 動作解説 # # できる限り、for i in all ....... end を減らしました # # ・マップの通行判定 # $game_map.passages_data[x,y] # に先にすべてのレイヤー分計算しておくことで高速化 # ついでにタイルイベントの通行データもイベントに同期 # # ・イベントの取得 # $game_map.charpos_data[x,y] # にイベント移動時などに自分のIDを登録 # 取得はテーブル読むだけでOK # 重なったイベントは1つしか取得できないという欠点も。 # また、遠くのランダム移動イベントなどを移動させないことで、 # この処理も若干高速化 # # ・マップスプライト # $onscreen[char_ID] # このグローバル変数に、画面内フラグを設定 # 画面から遠く離れたキャラクタースプライトは、 # 一切更新しないことで高速化 # # # ・置物イベント # $game_map.events_obj[char_ID] # true なら置物。ほとんどの更新処理を飛ばしますが、 # 実行は可能。自動実行、並列処理はできません。 # # ・最背面に表示 # $game_map.events_bottom[char_ID] # true なら再背面に表示します。魔方陣やワナなどに。 # これをオンにすると描画も早くなります。 # # # # ※通常時の処理は軽くなりますが、マップ移動時などの処理は重くなります # # # #------------------------------------------------------------------- # ●Game_Tempクラス #-------------------------------------------------------------------- class Game_Temp alias initialize_tonbi1 initialize def initialize initialize_tonbi1 $onscreen = [] # スプライト画面内フラグ end end #------------------------------------------------------------------- # ●Game_Mapクラス #-------------------------------------------------------------------- class Game_Map attr_accessor :passages_data # 新-通行判定フラグ[x,y] attr_accessor :charpos_data # イベントの位置データ[x,y] attr_accessor :events_obj # イベント(置物)フラグ attr_accessor :move_display # 画面位置移動する?フラグ attr_accessor :events_bottom # イベントZ座標非更新フラグ #-------------------------------------------------------------------------- # ● 特殊イベント判定(イベント製作前) # id : イベントID #-------------------------------------------------------------------------- def check_special_event_befor(id) @events_obj[id] = false @events_bottom[id] = false # 最初のページの実行条件が変数 -99999999 以上なら 置物 または名前の,以降 if @map.events[id].pages[0].condition.variable_value == -99999999 or @map.events[id].subname == OBJECT_WORD @events_obj[id] = true end for j in 0..1000 if @map.events[id].pages[0].list[j].code != 108 break end # コメントに置物とあれば if @map.events[id].pages[0].list[j].parameters[0] == OBJECT_WORD @events_obj[id] = true end # コメントに再背面に表示とあれば if @map.events[id].pages[0].list[j].parameters[0] == BOTTOM_WORD @events_bottom[id] = true end end end #-------------------------------------------------------------------------- # ● 特殊イベント判定(イベント製作後) # id : イベントID #-------------------------------------------------------------------------- def check_special_event_after(id) # あとでいろいろ追加できるようにこれ呼び出す end #-------------------------------------------------------------------------- # ● 特殊マップ判定 #-------------------------------------------------------------------------- def check_special_map # あとでいろいろ追加できるようにこれ呼び出す 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)) # 公開インスタンス変数にタイルセットの情報を設定 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 # イベント位置のテーブル作成 @charpos_data=Table.new(self.width,self.height) if self.width == 20 and self.height == 15 @move_display = false else @move_display = true end check_special_map # 通行判定用テーブル作成(ここ変更) # 先にすべてのレイヤー分計算しておくことで高速化 @passages_data=Table.new(self.width,self.height) for x in 0..(self.width) for y in 0..(self.height) Graphics.update if y%1000==0 @passages_data[x,y] = 0 for i in [2,1,0] tile_id = self.data[x,y,i] if tile_id == nil @passages_data[x,y] |= 0x0f break elsif @passages[tile_id] & 0x0f != 0 @passages_data[x,y] |= @passages[tile_id] break elsif @priorities[tile_id] == 0 break end end for i in [0,1,2] tile_id = self.data[x,y,i] if tile_id == nil break elsif @passages[tile_id] & 0x40 == 0x40 @passages_data[x,y] |= 0x40 break end end for i in [0,1,2] tile_id = self.data[x,y,i] if tile_id == nil break elsif @passages[tile_id] & 0x80 == 0x80 @passages_data[x,y] |= 0x80 break end end end end # マップイベントのデータを設定 @events_obj = [] @events_bottom = [] @events_bottom[0] = false @events = {} for i in @map.events.keys check_special_event_befor(i) @events[i] = Game_Event.new(@map_id, @map.events[i]) check_special_event_after(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) @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 #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh # マップ ID が有効なら if @map_id > 0 # すべてのマップイベントをリフレッシュ for i in @events.keys unless @events_obj[i] @events[i].refresh end end # すべてのコモンイベントをリフレッシュ for common_event in @common_events.values common_event.refresh end end # リフレッシュ要求フラグをクリア @need_refresh = false 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 i in @events.keys if @events_obj[i] == true @events[i].update_obj else @events[i].update end 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 #-------------------------------------------------------------------------- # ● 通行可能判定 # x : X 座標 # y : Y 座標 # d : 方向 (0,2,4,6,8,10) # ※ 0,10 = 全方向通行不可の場合を判定 (ジャンプなど) # すでにタイルイベントは通行判定テーブルに適応済みなので判定は削除 #-------------------------------------------------------------------------- def passable?(x, y, d) # 与えられた座標がマップ外の場合 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 # タイル ID を取得 passages_flag = @passages_data[x, y] if passages_flag == nil return false # 障害物ビットがセットされている場合 elsif passages_flag & bit != 0 # 通行不可 return false # 全方向の障害物ビットがセットされている場合 elsif passages_flag & 0x0f == 0x0f # 通行不可 return false end # 通行可 return true end #-------------------------------------------------------------------------- # ● 茂み判定 # x : X 座標 # y : Y 座標 #-------------------------------------------------------------------------- def bush?(x, y) if @map_id != 0 passages_flag = @passages_data[x, y] if passages_flag == nil return false elsif passages_flag & 0x40 == 0x40 return true end end return false end #-------------------------------------------------------------------------- # ● カウンター判定 # x : X 座標 # y : Y 座標 #-------------------------------------------------------------------------- def counter?(x, y) if @map_id != 0 passages_flag = @passages_data[x, y] if passages_flag == nil return false elsif passages_flag & 0x80 == 0x80 return true end end return false end #-------------------------------------------------------------------------- # ● 指定位置のイベント情報削除 # x : X 座標 # y : Y 座標 # id : イベントID # イベントが移動した際は、そのタイルから、そのイベント情報を消します #-------------------------------------------------------------------------- def throughable(x, y,id) if @charpos_data[x,y]==id @charpos_data[x,y]=0 elsif @charpos_data[x,y]==id*-1 @charpos_data[x,y]=0 end end #-------------------------------------------------------------------------- # ● 指定位置のイベント情報削除(タイル) # x : X 座標 # y : Y 座標 # id : イベントID # タイルイベントの場合、変更しておいた通行判定を元に戻す #-------------------------------------------------------------------------- def throughable_tile(x, y,id) if @charpos_data[x,y]==id @charpos_data[x,y]=0 elsif @charpos_data[x,y]==id*-1 @charpos_data[x,y]=0 end @passages_data[x,y] &= 0xf0 for i in [2,1,0] tile_id = self.data[x,y,i] if tile_id == nil @passages_data[x,y] |= 0x0f break elsif @passages[tile_id] & 0x0f != 0 @passages_data[x,y] |= @passages[tile_id] &0x0f break elsif @priorities[tile_id] == 0 break end end end #-------------------------------------------------------------------------- # ● 指定位置にイベント情報設置 # x : X 座標 # y : Y 座標 # id : イベントID(マイナスなら通れる) # イベントが移動したとき、新たなタイルに自分のIDを書き込む #-------------------------------------------------------------------------- def throughunable(x, y, id) if @charpos_data[x,y]==0 @charpos_data[x,y]=id end end #-------------------------------------------------------------------------- # ● 指定位置にイベント情報設置(タイル) # x : X 座標 # y : Y 座標 # id : イベントID(マイナスなら通れる) # tile : タイルグラフィックID # タイルイベントなら、通行判定も変更する #-------------------------------------------------------------------------- def throughunable_tile(x, y, id, tile) if id > 0 @passages_data[x,y] &= 0xf0 @passages_data[x,y] |= @passages[tile]&0x0f id *= -1 end if @charpos_data[x,y]==0 @charpos_data[x,y]=id end end #-------------------------------------------------------------------------- # ● 指定位置が通行可能か? # x : X 座標 # y : Y 座標 # id : イベントID(マイナスなら通れる) #-------------------------------------------------------------------------- def throughable?(x, y, self_id) id = @charpos_data[x,y] if id != 0 and id != self_id return id end return 0 end #-------------------------------------------------------------------------- # ● 指定位置のイベントID取得その2 # x : X 座標 # y : Y 座標 # id : 除くイベントID(つまり自分) #-------------------------------------------------------------------------- def getevent(x, y, self_id) unless valid?(x, y) return 0 end id = @charpos_data[x,y] if id != 0 and id != self_id if id <0 id *= -1 end return id end return 0 end #-------------------------------------------------------------------------- # ● 指定位置のイベント ID 取得 # x : X 座標 # y : Y 座標 #-------------------------------------------------------------------------- def check_event(x, y) unless valid?(x, y) return 0 end id = @charpos_data[x,y] if id <0 id *= -1 end return id end end #-------------------------------------------------------------------------- # ● Game_Characterクラス #-------------------------------------------------------------------------- class Game_Character #-------------------------------------------------------------------------- # ● 通行可能判定 # x : X 座標 # y : Y 座標 # d : 方向 (0,2,4,6,8) ※ 0 = 全方向通行不可の場合を判定 (ジャンプ用) #-------------------------------------------------------------------------- def passable?(x, y, d) # 新しい座標を求める new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0) new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0) # 座標がマップ外の場合 unless $game_map.valid?(new_x, new_y) # 通行不可 return false end # すり抜け ON の場合 if @through == true # 通行可 return true end # イベントと位置がかぶってるか?(ここ変更) i = $game_map.throughable?(new_x, new_y, @id) if self != $game_player # 自分がイベント if i != 0 return false end else # 自分がプレイヤー if i > 0 # 当たったイベントがすり抜けオフなら unless $game_map.events[i].through # 当たったイベントが空イベントでないなら if $game_map.events[i].tile_id != 0 or $game_map.events[i].character_name != "" # 通行不可 return false end end end end # 自分のマップから出れるか? unless $game_map.passable?(x, y,d) return false end # 移動先のマップに入れるか? unless $game_map.passable?(new_x, new_y, 10 - d) # 通行不可 return false end # プレイヤーの座標が移動先と一致した場合 if $game_player.x == new_x and $game_player.y == new_y and self != $game_player # すり抜け OFF なら unless $game_player.through # 自分のグラフィックがキャラクターの場合 if @character_name != "" # 通行不可 return false end end end # 通行可 return true end #-------------------------------------------------------------------------- # ● 指定位置に移動 # x : X 座標 # y : Y 座標 # 前のタイルから自分のIDを消して、新たなタイルに登録(以下しばらく #-------------------------------------------------------------------------- def moveto(x, y) if @tile_id == 0 $game_map.throughable(@x,@y,@id) else $game_map.throughable_tile(@x,@y,@id) end @x = x % $game_map.width @y = y % $game_map.height @real_x = @x * 128 @real_y = @y * 128 @prelock_direction = 0 if @tile_id == 0 $game_map.throughunable(@x,@y,@id) else if @through == true $game_map.throughunable_tile(@x,@y,@id*-1,@tile_id) else $game_map.throughunable_tile(@x,@y,@id,@tile_id) end end end #-------------------------------------------------------------------------- # ● 移動タイプ : カスタム #-------------------------------------------------------------------------- def move_type_custom # 停止中でなければ中断 if jumping? or moving? return end # 移動コマンドのリストの最後に到達するまでループ while @move_route_index < @move_route.list.size # 移動コマンドを取得 command = @move_route.list[@move_route_index] # コマンドコード 0 番 (リストの最後) の場合 if command.code == 0 # オプション [動作を繰り返す] が ON の場合 if @move_route.repeat # 移動ルートのインデックスを最初に戻す @move_route_index = 0 end # オプション [動作を繰り返す] が OFF の場合 unless @move_route.repeat # 移動ルート強制中の場合 if @move_route_forcing and not @move_route.repeat # 移動ルートの強制を解除 @move_route_forcing = false # オリジナルの移動ルートを復帰 @move_route = @original_move_route @move_route_index = @original_move_route_index @original_move_route = nil end # 停止カウントをクリア @stop_count = 0 end return end # 移動系コマンド (下に移動〜ジャンプ) の場合 if command.code <= 14 # コマンドコードで分岐 case command.code when 1 # 下に移動 move_down when 2 # 左に移動 move_left when 3 # 右に移動 move_right when 4 # 上に移動 move_up when 5 # 左下に移動 move_lower_left when 6 # 右下に移動 move_lower_right when 7 # 左上に移動 move_upper_left when 8 # 右上に移動 move_upper_right when 9 # ランダムに移動 move_random when 10 # プレイヤーに近づく move_toward_player when 11 # プレイヤーから遠ざかる move_away_from_player when 12 # 一歩前進 move_forward when 13 # 一歩後退 move_backward when 14 # ジャンプ jump(command.parameters[0], command.parameters[1]) end # オプション [移動できない場合は無視] が OFF で、移動失敗の場合 if not @move_route.skippable and not moving? and not jumping? return end @move_route_index += 1 return end # ウェイトの場合 if command.code == 15 # ウェイトカウントを設定 @wait_count = command.parameters[0] * 2 - 1 @move_route_index += 1 return end # 向き変更系のコマンドの場合 if command.code >= 16 and command.code <= 26 # コマンドコードで分岐 case command.code when 16 # 下を向く turn_down when 17 # 左を向く turn_left when 18 # 右を向く turn_right when 19 # 上を向く turn_up when 20 # 右に 90 度回転 turn_right_90 when 21 # 左に 90 度回転 turn_left_90 when 22 # 180 度回転 turn_180 when 23 # 右か左に 90 度回転 turn_right_or_left_90 when 24 # ランダムに方向転換 turn_random when 25 # プレイヤーの方を向く turn_toward_player when 26 # プレイヤーの逆を向く turn_away_from_player end @move_route_index += 1 return end # その他のコマンドの場合 if command.code >= 27 # コマンドコードで分岐 case command.code when 27 # スイッチ ON $game_switches[command.parameters[0]] = true $game_map.need_refresh = true when 28 # スイッチ OFF $game_switches[command.parameters[0]] = false $game_map.need_refresh = true when 29 # 移動速度の変更 @move_speed = command.parameters[0] when 30 # 移動頻度の変更 @move_frequency = command.parameters[0] when 31 # 移動時アニメ ON @walk_anime = true when 32 # 移動時アニメ OFF @walk_anime = false when 33 # 停止時アニメ ON @step_anime = true when 34 # 停止時アニメ OFF @step_anime = false when 35 # 向き固定 ON @direction_fix = true when 36 # 向き固定 OFF @direction_fix = false when 37 # すり抜け ON @through = true if @tile_id == 0 $game_map.throughunable(@x,@y,@id) else if @through == true $game_map.throughunable_tile(@x,@y,@id*-1,@tile_id) else $game_map.throughunable_tile(@x,@y,@id,@tile_id) end end when 38 # すり抜け OFF @through = false if @tile_id == 0 $game_map.throughunable(@x,@y,@id) else if @through == true $game_map.throughunable_tile(@x,@y,@id*-1,@tile_id) else $game_map.throughunable_tile(@x,@y,@id,@tile_id) end end when 39 # 最前面に表示 ON @always_on_top = true when 40 # 最前面に表示 OFF @always_on_top = false when 41 # グラフィック変更 # (ここ追加) if tile_id == 0 $game_map.throughable(@x,@y,@id) else $game_map.throughable_tile(@x,@y,@id) end @tile_id = 0 @character_name = command.parameters[0] @character_hue = command.parameters[1] if @original_direction != command.parameters[2] @direction = command.parameters[2] @original_direction = @direction @prelock_direction = 0 end if @original_pattern != command.parameters[3] @pattern = command.parameters[3] @original_pattern = @pattern end # (ここ追加) if @tile_id == 0 $game_map.throughunable(@x,@y,@id) else if @through == true $game_map.throughunable_tile(@x,@y,@id*-1,@tile_id) else $game_map.throughunable_tile(@x,@y,@id,@tile_id) end end when 42 # 不透明度の変更 @opacity = command.parameters[0] when 43 # 合成方法の変更 @blend_type = command.parameters[0] when 44 # SE の演奏 $game_system.se_play(command.parameters[0]) when 45 # スクリプト result = eval(command.parameters[0]) end @move_route_index += 1 end end end #-------------------------------------------------------------------------- # ● 下に移動 # turn_enabled : その場での向き変更を許可するフラグ #-------------------------------------------------------------------------- def move_down(turn_enabled = true) # 下を向く if turn_enabled turn_down end # 通行可能な場合 if passable?(@x, @y, 2) # (ここ追加)以下しばらく同じ if tile_id == 0 $game_map.throughable(@x,@y,@id) else $game_map.throughable_tile(@x,@y,@id) end # 下を向く turn_down # 座標を更新 @y += 1 # (ここ追加)以下しばらく同じ if @tile_id == 0 $game_map.throughunable(@x,@y,@id) else if @through == true $game_map.throughunable_tile(@x,@y,@id*-1,@tile_id) else $game_map.throughunable_tile(@x,@y,@id,@tile_id) end end # 歩数増加 increase_steps # 通行不可能な場合 else # 接触イベントの起動判定 check_event_trigger_touch(@x, @y+1) end end #-------------------------------------------------------------------------- # ● 左に移動 # turn_enabled : その場での向き変更を許可するフラグ #-------------------------------------------------------------------------- def move_left(turn_enabled = true) # 左を向く if turn_enabled turn_left end # 通行可能な場合 if passable?(@x, @y, 4) # ここを追加 if tile_id == 0 $game_map.throughable(@x,@y,@id) else $game_map.throughable_tile(@x,@y,@id) end # 左を向く turn_left # 座標を更新 @x -= 1 # ここを追加 if @tile_id == 0 $game_map.throughunable(@x,@y,@id) else if @through == true $game_map.throughunable_tile(@x,@y,@id*-1,@tile_id) else $game_map.throughunable_tile(@x,@y,@id,@tile_id) end end # 歩数増加 increase_steps # 通行不可能な場合 else # 接触イベントの起動判定 check_event_trigger_touch(@x-1, @y) end end #-------------------------------------------------------------------------- # ● 右に移動 # turn_enabled : その場での向き変更を許可するフラグ #-------------------------------------------------------------------------- def move_right(turn_enabled = true) # 右を向く if turn_enabled turn_right end # 通行可能な場合 if passable?(@x, @y, 6) # ここを追加 if tile_id == 0 $game_map.throughable(@x,@y,@id) else $game_map.throughable_tile(@x,@y,@id) end # 右を向く turn_right # 座標を更新 @x += 1 # ここを追加 if @tile_id == 0 $game_map.throughunable(@x,@y,@id) else if @through == true $game_map.throughunable_tile(@x,@y,@id*-1,@tile_id) else $game_map.throughunable_tile(@x,@y,@id,@tile_id) end end # 歩数増加 increase_steps # 通行不可能な場合 else # 接触イベントの起動判定 check_event_trigger_touch(@x+1, @y) end end #-------------------------------------------------------------------------- # ● 上に移動 # turn_enabled : その場での向き変更を許可するフラグ #-------------------------------------------------------------------------- def move_up(turn_enabled = true) # 上を向く if turn_enabled turn_up end # 通行可能な場合 if passable?(@x, @y, 8) # ここを追加 if tile_id == 0 $game_map.throughable(@x,@y,@id) else $game_map.throughable_tile(@x,@y,@id) end # 上を向く turn_up # 座標を更新 @y -= 1 # ここを追加 if @tile_id == 0 $game_map.throughunable(@x,@y,@id) else if @through == true $game_map.throughunable_tile(@x,@y,@id*-1,@tile_id) else $game_map.throughunable_tile(@x,@y,@id,@tile_id) end end # 歩数増加 increase_steps # 通行不可能な場合 else # 接触イベントの起動判定 check_event_trigger_touch(@x, @y-1) end end #-------------------------------------------------------------------------- # ● 左下に移動 #-------------------------------------------------------------------------- def move_lower_left # 向き固定でない場合 unless @direction_fix # 右向きだった場合は左を、上向きだった場合は下を向く @direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction) end # 下→左、左→下 のどちらかのコースが通行可能な場合 if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 4)) or (passable?(@x, @y, 4) and passable?(@x - 1, @y, 2)) # ここを追加 if tile_id == 0 $game_map.throughable(@x,@y,@id) else $game_map.throughable_tile(@x,@y,@id) end # 座標を更新 @x -= 1 @y += 1 # ここを追加 if @tile_id == 0 $game_map.throughunable(@x,@y,@id) else if @through == true $game_map.throughunable_tile(@x,@y,@id*-1,@tile_id) else $game_map.throughunable_tile(@x,@y,@id,@tile_id) end end # 歩数増加 increase_steps end end #-------------------------------------------------------------------------- # ● 右下に移動 #-------------------------------------------------------------------------- def move_lower_right # 向き固定でない場合 unless @direction_fix # 左向きだった場合は右を、上向きだった場合は下を向く @direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction) end # 下→右、右→下 のどちらかのコースが通行可能な場合 if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 6)) or (passable?(@x, @y, 6) and passable?(@x + 1, @y, 2)) # ここを追加 if tile_id == 0 $game_map.throughable(@x,@y,@id) else $game_map.throughable_tile(@x,@y,@id) end # 座標を更新 @x += 1 @y += 1 # ここを追加 if @tile_id == 0 $game_map.throughunable(@x,@y,@id) else if @through == true $game_map.throughunable_tile(@x,@y,@id*-1,@tile_id) else $game_map.throughunable_tile(@x,@y,@id,@tile_id) end end # 歩数増加 increase_steps end end #-------------------------------------------------------------------------- # ● 左上に移動 #-------------------------------------------------------------------------- def move_upper_left # 向き固定でない場合 unless @direction_fix # 右向きだった場合は左を、下向きだった場合は上を向く @direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction) end # 上→左、左→上 のどちらかのコースが通行可能な場合 if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 4)) or (passable?(@x, @y, 4) and passable?(@x - 1, @y, 8)) # ここを追加 if tile_id == 0 $game_map.throughable(@x,@y,@id) else $game_map.throughable_tile(@x,@y,@id) end # 座標を更新 @x -= 1 @y -= 1 # ここを追加 if @tile_id == 0 $game_map.throughunable(@x,@y,@id) else if @through == true $game_map.throughunable_tile(@x,@y,@id*-1,@tile_id) else $game_map.throughunable_tile(@x,@y,@id,@tile_id) end end # 歩数増加 increase_steps end end #-------------------------------------------------------------------------- # ● 右上に移動 #-------------------------------------------------------------------------- def move_upper_right # 向き固定でない場合 unless @direction_fix # 左向きだった場合は右を、下向きだった場合は上を向く @direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction) end # 上→右、右→上 のどちらかのコースが通行可能な場合 if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 6)) or (passable?(@x, @y, 6) and passable?(@x + 1, @y, 8)) # ここを追加 if tile_id == 0 $game_map.throughable(@x,@y,@id) else $game_map.throughable_tile(@x,@y,@id) end # 座標を更新 @x += 1 @y -= 1 # ここを追加 if @tile_id == 0 $game_map.throughunable(@x,@y,@id) else if @through == true $game_map.throughunable_tile(@x,@y,@id*-1,@tile_id) else $game_map.throughunable_tile(@x,@y,@id,@tile_id) end end # 歩数増加 increase_steps end end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update #画面上での位置 sx = @real_x - $game_map.display_x - 1280 sy = @real_y - $game_map.display_y - 960 # 絶対値を求める abs_sx = sx > 0 ? sx : -sx abs_sy = sy > 0 ? sy-3 : -sy # 縦か横が DRAWRANGE タイル以上離れている場合 if abs_sx > DRAWRANGEX or abs_sy > DRAWRANGEY # スプライト非更新にする $onscreen[@id]=false else # スプライト更新ありにする $onscreen[@id]=true end # ジャンプ中、移動中、停止中で分岐 if jumping? update_jump elsif moving? update_move else update_stop end # アニメカウントが最大値を超えた場合 # ※最大値は、基本値 18 から移動速度 * 1 を引いた値 if @anime_count > 18 - @move_speed * 2 # 停止時アニメが OFF かつ 停止中の場合 if not @step_anime and @stop_count > 0 # パターンをオリジナルに戻す @pattern = @original_pattern # 停止時アニメが ON または 移動中の場合 else # パターンを更新 @pattern = (@pattern + 1) % 4 end # アニメカウントをクリア @anime_count = 0 end # ウェイト中の場合 if @wait_count > 0 # ウェイトカウントを減らす @wait_count -= 1 return end # 移動ルート強制中の場合 if @move_route_forcing # カスタム移動 move_type_custom return end # イベント実行待機中またはロック状態の場合 if @starting or lock? # 自律移動はしない return end # 停止カウントが一定の値 (移動頻度から算出) を超えた場合 if @stop_count > (40 - @move_frequency * 2) * (6 - @move_frequency) # 移動タイプで分岐 case @move_type when 1 # ランダム if abs_sx + abs_sy <= MOVERANGE # MOVERANGE(24)以上離れていると無視 move_type_random end when 2 # 近づく if abs_sx + abs_sy <= MOVERANGE # MOVERANGE(24)以上離れていると無視 move_type_toward_player end when 3 # カスタム move_type_custom end end end #-------------------------------------------------------------------------- # ● フレーム更新(置物用) #-------------------------------------------------------------------------- def update_obj #画面上での位置 sx = @real_x - $game_map.display_x - 1280 sy = @real_y - $game_map.display_y - 960 # 絶対値を求める abs_sx = sx > 0 ? sx : -sx abs_sy = sy > 0 ? sy-3 : -sy # 縦か横が DRAWRANGE タイル以上離れている場合 if abs_sx > DRAWRANGEX or abs_sy > DRAWRANGEY # スプライト非更新にする $onscreen[@id]=false else # スプライト更新ありにする $onscreen[@id]=true end end #-------------------------------------------------------------------------- # ● 画面 Z 座標の取得(前に求めたYを使うため一部省略 # height : キャラクターの高さ #-------------------------------------------------------------------------- def screen_z(height = 0) # 最前面に表示フラグが ON の場合 if @always_on_top # 無条件に 999 return 999 end # タイルの場合 if @tile_id > 0 # タイルのプライオリティ * 32 を足す return $game_map.priorities[@tile_id] * 32 # キャラクターの場合 else # 高さが 32 を超えていれば 31 を足す return ((height > 32) ? 31 : 0) end end end class Game_Event < Game_Character #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- def refresh # ローカル変数 new_page を初期化 new_page = nil # 一時消去されていない場合 unless @erased # 番号の大きいイベントページから順に調べる for page in @event.pages.reverse # イベント条件を c で参照可能に c = page.condition # スイッチ 1 条件確認 if c.switch1_valid if $game_switches[c.switch1_id] == false next end end # スイッチ 2 条件確認 if c.switch2_valid if $game_switches[c.switch2_id] == false next end end # 変数 条件確認 if c.variable_valid if $game_variables[c.variable_id] < c.variable_value next end end # セルフスイッチ 条件確認 if c.self_switch_valid key = [@map_id, @event.id, c.self_switch_ch] if $game_self_switches[key] != true next end end # ローカル変数 new_page を設定 new_page = page # ループを抜ける break end end # 前回と同じイベントページの場合 if new_page == @page # メソッド終了 return end # ページが変更になったとき(位置情報一端削除) if @tile_id == 0 $game_map.throughable(@x,@y,@id) else $game_map.throughable_tile(@x,@y,@id) end # @page に現在のイベントページを設定 @page = new_page # 起動中フラグをクリア clear_starting # 条件を満たすページがない場合 if @page == nil # 各インスタンス変数を設定 @tile_id = 0 @character_name = "" @character_hue = 0 @move_type = 0 @through = true @trigger = nil @list = nil @interpreter = nil # メソッド終了 return end # 各インスタンス変数を設定 @tile_id = @page.graphic.tile_id @character_name = @page.graphic.character_name @character_hue = @page.graphic.character_hue if @original_direction != @page.graphic.direction @direction = @page.graphic.direction @original_direction = @direction @prelock_direction = 0 end if @original_pattern != @page.graphic.pattern @pattern = @page.graphic.pattern @original_pattern = @pattern end @opacity = @page.graphic.opacity @blend_type = @page.graphic.blend_type @move_type = @page.move_type @move_speed = @page.move_speed @move_frequency = @page.move_frequency @move_route = @page.move_route @move_route_index = 0 @move_route_forcing = false @walk_anime = @page.walk_anime @step_anime = @page.step_anime @direction_fix = @page.direction_fix @through = @page.through @always_on_top = @page.always_on_top @trigger = @page.trigger @list = @page.list @interpreter = nil # 位置情報復活 if @tile_id == 0 $game_map.throughunable(@x,@y,@id) else if @through == true $game_map.throughunable_tile(@x,@y,@id*-1,@tile_id) else $game_map.throughunable_tile(@x,@y,@id,@tile_id) end end # トリガーが [並列処理] の場合 if @trigger == 4 # 並列処理用インタプリタを作成 @interpreter = Interpreter.new end # 自動イベントの起動判定 check_event_trigger_auto end end #-------------------------------------------------------------------------- # ● Game_Playerクラス #-------------------------------------------------------------------------- class Game_Player < Game_Character #-------------------------------------------------------------------------- # ● 同位置のイベント起動判定 #-------------------------------------------------------------------------- def check_event_trigger_here(triggers) result = false # イベント実行中の場合 if $game_system.map_interpreter.running? return result end # @x,@y のイベント取得 for排除(ここ変更) i = $game_map.getevent(@x,@y,0) if i != 0 event = $game_map.events[i] if triggers.include?(event.trigger) if not event.jumping? and event.over_trigger? event.start result = true end end end return result end #-------------------------------------------------------------------------- # ● 正面のイベント起動判定 #-------------------------------------------------------------------------- def check_event_trigger_there(triggers) result = false # イベント実行中の場合 if $game_system.map_interpreter.running? return result end # 正面の座標を計算 new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0) new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0) # 正面のイベントを取得(ここ変更) i = $game_map.getevent(new_x,new_y,0) if i != 0 event = $game_map.events[i] if triggers.include?(event.trigger) if not event.jumping? and not event.over_trigger? event.start result = true end end end # 該当するイベントが見つからなかった場合 if result == false # 正面のタイルがカウンターなら if $game_map.counter?(new_x, new_y) # 1 タイル奥の座標を計算 new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0) new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0) # 正面のイベントを取得(ここ変更) i = $game_map.getevent(new_x,new_y,0) if i != 0 event = $game_map.events[i] if triggers.include?(event.trigger) if not event.jumping? and not event.over_trigger? event.start result = true end end end end end return result end #-------------------------------------------------------------------------- # ● 接触イベントの起動判定 #-------------------------------------------------------------------------- def check_event_trigger_touch(x, y) result = false # イベント実行中の場合 if $game_system.map_interpreter.running? return result end i = $game_map.getevent(x,y,0) # (ここ変更) if i != 0 event = $game_map.events[i] if [1,2].include?(event.trigger) if not event.jumping? event.start result = true end end end return result end end #------------------------------------------------------------------------------ # ● Sprite_Characterクラス #------------------------------------------------------------------------------ class Sprite_Character < RPG::Sprite #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update(id = -1) super() # タイル ID、ファイル名、色相のどれかが現在のものと異なる場合 if @tile_id != @character.tile_id or @character_name != @character.character_name or @character_hue != @character.character_hue # タイル ID とファイル名、色相を記憶 @tile_id = @character.tile_id @character_name = @character.character_name @character_hue = @character.character_hue # タイル ID が有効な値の場合 if @tile_id >= 384 self.bitmap = RPG::Cache.tile($game_map.tileset_name, @tile_id, @character.character_hue) self.src_rect.set(0, 0, 32, 32) self.ox = 16 self.oy = 32 # タイル ID が無効な値の場合 else self.bitmap = RPG::Cache.character(@character.character_name, @character.character_hue) @cw = bitmap.width / 4 @ch = bitmap.height / 4 self.ox = @cw / 2 self.oy = @ch end end # 可視状態を設定 self.visible = (not @character.transparent) # グラフィックがキャラクターの場合 if @tile_id == 0 # 転送元の矩形を設定 sx = @character.pattern * @cw sy = (@character.direction - 2) / 2 * @ch self.src_rect.set(sx, sy, @cw, @ch) end # スプライトの座標を設定 y = @character.screen_y self.x = @character.screen_x self.y = y if $game_map.events_bottom[id] != true self.z = y+@character.screen_z(@ch) end # 不透明度、合成方法、茂み深さを設定 self.opacity = @character.opacity self.blend_type = @character.blend_type self.bush_depth = @character.bush_depth # アニメーション if @character.animation_id != 0 animation = $data_animations[@character.animation_id] animation(animation, true) @character.animation_id = 0 end end end #-------------------------------------------------------------------------- # ● Spriteset_Mapクラス #-------------------------------------------------------------------------- class Spriteset_Map #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- attr_accessor :character_sprites def initialize $onscreen = [] # ビューポートを作成 @viewport1 = Viewport.new(0, 0, 640, 480) @viewport2 = Viewport.new(0, 0, 640, 480) @viewport3 = Viewport.new(0, 0, 640, 480) @viewport2.z = 200 @viewport3.z = 5000 # タイルマップを作成 @tilemap = Tilemap.new(@viewport1) @tilemap.tileset = RPG::Cache.tileset($game_map.tileset_name) for i in 0..6 autotile_name = $game_map.autotile_names[i] @tilemap.autotiles[i] = RPG::Cache.autotile(autotile_name) end @tilemap.map_data = $game_map.data @tilemap.priorities = $game_map.priorities # パノラマプレーンを作成 @panorama = Plane.new(@viewport1) @panorama.z = -1000 # フォグプレーンを作成 @fog = Plane.new(@viewport1) @fog.z = 3000 # キャラクタースプライトを作成 # 順番変更(Game_Charcterとあわせるため。(ここ変更) @spritecnt = 0 @character_sprites = [] for i in $game_map.events.keys.sort sprite = Sprite_Character.new(@viewport1, $game_map.events[i]) if $game_map.events_bottom[i] == true sprite.z = 0 end @character_sprites[i]=sprite $onscreen[i] = true end @character_sprites[0]=Sprite_Character.new(@viewport1, $game_player) $onscreen[0] = true # 天候を作成 @weather = RPG::Weather.new(@viewport1) # ピクチャを作成 @picture_sprites = [] for i in 1..50 @picture_sprites.push(Sprite_Picture.new(@viewport2, $game_screen.pictures[i])) end # タイマースプライトを作成 @timer_sprite = Sprite_Timer.new # フレーム更新 update end #-------------------------------------------------------------------------- # ● 解放 #-------------------------------------------------------------------------- def dispose # タイルマップを解放 @tilemap.tileset.dispose for i in 0..6 @tilemap.autotiles[i].dispose end @tilemap.dispose # パノラマプレーンを解放 @panorama.dispose # フォグプレーンを解放 @fog.dispose # キャラクタースプライトを解放 for i in @character_sprites if i != nil i.dispose end end # 天候を解放 @weather.dispose # ピクチャを解放 for sprite in @picture_sprites sprite.dispose end # タイマースプライトを解放 @timer_sprite.dispose # ビューポートを解放 @viewport1.dispose @viewport2.dispose @viewport3.dispose end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update # パノラマが現在のものと異なる場合 if @panorama_name != $game_map.panorama_name or @panorama_hue != $game_map.panorama_hue @panorama_name = $game_map.panorama_name @panorama_hue = $game_map.panorama_hue if @panorama.bitmap != nil @panorama.bitmap.dispose @panorama.bitmap = nil end if @panorama_name != "" @panorama.bitmap = RPG::Cache.panorama(@panorama_name, @panorama_hue) end Graphics.frame_reset end # フォグが現在のものと異なる場合 if @fog_name != $game_map.fog_name or @fog_hue != $game_map.fog_hue @fog_name = $game_map.fog_name @fog_hue = $game_map.fog_hue if @fog.bitmap != nil @fog.bitmap.dispose @fog.bitmap = nil end if @fog_name != "" @fog.bitmap = RPG::Cache.fog(@fog_name, @fog_hue) end Graphics.frame_reset end # タイルマップを更新 @tilemap.ox = $game_map.display_x / 4 @tilemap.oy = $game_map.display_y / 4 @tilemap.update # パノラマプレーンを更新 @panorama.ox = $game_map.display_x / 8 @panorama.oy = $game_map.display_y / 8 # フォグプレーンを更新 @fog.zoom_x = $game_map.fog_zoom / 100.0 @fog.zoom_y = $game_map.fog_zoom / 100.0 @fog.opacity = $game_map.fog_opacity @fog.blend_type = $game_map.fog_blend_type @fog.ox = $game_map.display_x / 4 + $game_map.fog_ox @fog.oy = $game_map.display_y / 4 + $game_map.fog_oy @fog.tone = $game_map.fog_tone # キャラクタースプライトを更新(ここ変更) # 画面外のスプライトは更新しない if $game_map.move_display == true for i in $game_map.events.keys if $onscreen[i] @character_sprites[i].update(i) end end else for i in $game_map.events.keys if $onscreen[i] unless $game_map.events_obj[i] @character_sprites[i].update(i) end end end end # プレイヤーキャラ更新 @character_sprites[0].update(0) # 天候グラフィックを更新 @weather.type = $game_screen.weather_type @weather.max = $game_screen.weather_max @weather.ox = $game_map.display_x / 4 @weather.oy = $game_map.display_y / 4 @weather.update # ピクチャを更新 for sprite in @picture_sprites sprite.update end # タイマースプライトを更新 @timer_sprite.update # 画面の色調とシェイク位置を設定 @viewport1.tone = $game_screen.tone @viewport1.ox = $game_screen.shake # 画面のフラッシュ色を設定 @viewport3.color = $game_screen.flash_color # ビューポートを更新 @viewport1.update @viewport3.update end end class Interpreter # 指定イベントを置物に設定する def event_off(id = @event_id) $game_map.events_obj[id] = true return true end # 指定イベントの置物を解除する def event_on(id = @event_id) $game_map.events_obj[id] = false return true end # 置物イベントのページを更新する def event_refresh(id = @event_id) $game_map.events[id].refresh if $game_map.move_display == false $scene.spriteset.character_sprites[id].update end return true end # 画面位置移動オンにする def move_display_on $game_map.move_display = true return true end # 画面位置移動オフにする def move_display_off $game_map.move_display = false return true end # 最背面に表示をオフにする def draw_bottom_off(id = @event_id) $game_map.events_bottom[id] = false return true end # 最背面に表示をオンにする def draw_bottom_on(id = @event_id) $game_map.events_bottom[id] = true $scene.spriteset.character_sprites[id].z = 0 return true end end class Scene_Map attr_accessor :spriteset end #============================================================================== # □ RPG::MapInfo >>サブネーム..","以降の文字のことを subname に取得 #============================================================================== module RPG class MapInfo def name name = @name.split(/,/)[0] return name != nil ? name : '' end def name=(str) str2 = @name[/^[^,]*(,.*)/, 1] @name = str2 != nil ? str + str2 : str end def subname(i = 1) name = @name.split(/,/)[i] return name != nil ? name : "" end end end #============================================================================== # □ RPG::Event >>サブネーム..","以降の文字のことを subname に取得 #============================================================================== module RPG class Event def name name = @name.split(/,/)[0] return name != nil ? name : '' end def name=(str) str2 = @name[/^[^,]*(,.*)/, 1] @name = str2 != nil ? str + str2 : str end def subname(i = 1) name = @name.split(/,/)[i] return name != nil ? name : "" end end end