XP パーティ行列歩行システム
# 設定項目
module TKS
The_Number_of_PMembers = 4 # パーティメンバの最大人数
end
#----------------------------------------------------------------------------
# ● パーティメンバをプレイヤーの元に集めるコマンド
# 書式:◆スクリプト:gather_party
#----------------------------------------------------------------------------
def gather_party
# dir→commandID変換配列の作成
dir_to_number = [0, 5, 1, 6, 2, 0, 3, 7, 4, 8]
# commandIDテーブルの初期化
direction = []
for i in 0 .. $game_pmembers.size - 1
direction[i] = 0
end
# パーティメンバの移動ルートの作成
for i in 1 .. $game_pmembers.size
direction[i - 1] = dir_to_number[$game_pmembers[i].dir]
# グラフィックが透明の場合
if $game_pmembers[i].character_name == ""
# ダイレクトに移動させる
$game_pmembers[i].moveto($game_player.x, $game_player.y)
$game_pmembers[i].direction = $game_player.direction
# グラフィックが透明でない場合
else
# 移動ルートを作成する
move_route = RPG::MoveRoute.new
move_route.repeat = false
move_route.skippable = false
move_route.list = []
max = $game_pmembers.size
i2 = 0
for dir in direction.reverse
if dir != 0
move_route.list[i2] = RPG::MoveCommand.new(dir)
i2 += 1
end
end
move_route.list[i2] = RPG::MoveCommand.new(15 + $game_player.direction / 2)
move_route.list[i2 + 1] = RPG::MoveCommand.new(0)
$game_pmembers[i].force_move_route(move_route)
end
end
# パーティメンバの予約歩行進路をクリア
for member in $game_pmembers.values
member.dir = 0
end
# 継続
return true
end
#----------------------------------------------------------------------------
# ● ドラホコシステムをON/OFFにするイベント
# 書式:◆スクリプト:dorahoko_system(true)
# ◆スクリプト:dorahoko_system(false)
#----------------------------------------------------------------------------
def dorahoko_system(value)
# システムフラグを更新
$game_system.dorahoko_system = value
# 継続
return true
end
#==============================================================================
# ■ Game_PMembers
#------------------------------------------------------------------------------
# マップ移動中の後続パーティメンバのクラスです。
#==============================================================================
class Game_PMembers < Game_Character
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_accessor :dir # 歩かせる方向
attr_accessor :move_speed # 移動速度
attr_accessor :move_frequency # 移動頻度
attr_accessor :direction # 向き
#--------------------------------------------------------------------------
# ● オブジェクト初期化
# mamber_id : メンバID
#--------------------------------------------------------------------------
def initialize(member_id)
# Game_Characterクラスのinitializeメソッドを呼び出す
super()
# 特有・例外部分を設定する
@member_id = member_id
@through = false
@dir = 0
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
# Game_Characterクラスのupdateメソッドを呼び出す
super()
# 特有・例外部分を更新する
# パーティメンバが一人でもいる場合
if $game_party.actors[0] != nil
# ドラホコシステムがオンで
# プレイヤーのグラフィックと戦闘のグラフィックが一致していて
# プレイヤーが透明状態ではなく
# このパーティメンバが有効なとき
if ($game_system.dorahoko_system == true and
$game_player.character_name == $game_party.actors[0].character_name and
$game_player.transparent == false and
$game_party.actors[@member_id] != nil)
# グラフィックと色調をデータと一致させる
@character_name = $game_party.actors[@member_id].character_name
@character_hue = $game_party.actors[@member_id].character_hue
# それ以外のとき
else
# グラフィックを透明にして、見えなくする
@character_name = ""
@character_hue = 0
end
end
end
#--------------------------------------------------------------------------
# ● @dirの方向に移動
#--------------------------------------------------------------------------
def walk
# 停止中でなければ中断
if jumping? or moving?
return
end
# 予約された方向で分岐
case @dir
when 1 # 左下
move_lower_left
when 2 # 下
move_down
when 3 # 右下
move_lower_right
when 4 # 左
move_left
when 6 # 右
move_right
when 7 # 左上
move_upper_left
when 8 # 上
move_up
when 9 # 右上
move_upper_right
end
end
#--------------------------------------------------------------------------
# ● 通行可能判定
# x : X 座標
# y : Y 座標
# d : 方向 (0,2,4,6,8) ※ 0 = 全方向通行不可の場合を判定 (ジャンプ用)
#--------------------------------------------------------------------------
def passable?(x, y, d)
# 通行可
return true
end
end
#----------------------------------------------------------------------------
# ▼ 以下、再定義
#----------------------------------------------------------------------------
class Game_System
attr_accessor :dorahoko_system
alias tks_initialize initialize
def initialize
@dorahoko_system = true
tks_initialize
end
end
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
# 通行可
return true
end
# 移動元のタイルから指定方向に出られない場合
unless $game_map.passable?(x, y, d, self)
# 通行不可
return false
end
# 移動先のタイルに指定方向から入れない場合
unless $game_map.passable?(new_x, new_y, 10 - d)
# 通行不可
return false
end
#>---------------------------------------------------------------------------
# 全パーティメンバのループ
for member in $game_pmembers.values
# パーティメンバの座標が移動先と一致した場合
if member.x == new_x and member.y == new_y
# すり抜け OFF なら
unless member.through
# 自分がイベントで、相手のグラフィックがキャラクターの場合
if self != $game_player and member.character_name != ""
return false
end
end
end
end
#<---------------------------------------------------------------------------
# 全イベントのループ
for event in $game_map.events.values
# イベントの座標が移動先と一致した場合
if event.x == new_x and event.y == new_y
# すり抜け OFF なら
unless event.through
# 自分がイベントの場合
if self != $game_player
# 通行不可
return false
end
# 自分がプレイヤーで、相手のグラフィックがキャラクターの場合
if event.character_name != ""
# 通行不可
return false
end
end
end
end
# プレイヤーの座標が移動先と一致した場合
if $game_player.x == new_x and $game_player.y == new_y
# すり抜け OFF なら
unless $game_player.through
# 自分のグラフィックがキャラクターの場合
if @character_name != ""
# 通行不可
return false
end
end
end
# 通行可
return true
end
end
class Spriteset_Map
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
# ビューポートを作成
@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
# キャラクタースプライトを作成
@character_sprites = []
for i in $game_map.events.keys.sort
sprite = Sprite_Character.new(@viewport1, $game_map.events[i])
@character_sprites.push(sprite)
end
#>---------------------------------------------------------------------------
# パーティメンバ用のスプライトを作成
for i in $game_pmembers.keys.sort.reverse
sprite = Sprite_Character.new(@viewport1, $game_pmembers[i])
@character_sprites.push(sprite)
end
#<---------------------------------------------------------------------------
@character_sprites.push(Sprite_Character.new(@viewport1, $game_player))
# 天候を作成
@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
end
class Game_Player
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
alias tks_update update
def update
tks_update
# パーティメンバの速度と頻度を合わせる
for member in $game_pmembers.values
member.move_speed = @move_speed
member.move_frequency = @move_frequency
member.update
end
end
#--------------------------------------------------------------------------
# ● 指定位置に移動
# x : X 座標
# y : Y 座標
#--------------------------------------------------------------------------
alias tks_moveto moveto
def moveto(x, y)
tks_moveto(x, y)
# パーティメンバも同じ位置に移動
for member in $game_pmembers.values
member.moveto(x, y)
member.dir = 0
end
end
#--------------------------------------------------------------------------
# ● 下に移動
# turn_enabled : その場での向き変更を許可するフラグ
#--------------------------------------------------------------------------
def move_down(turn_enabled = true)
# 下を向く
if turn_enabled
turn_down
end
# 通行可能な場合
if passable?(@x, @y, 2)
# 後続メンバーを歩かせる
for member in $game_pmembers.values
member.walk
end
max = $game_pmembers.size
for i in 0 .. max - 2
$game_pmembers[max - i].dir = $game_pmembers[max - i - 1].dir
end
$game_pmembers[1].dir = 2
# 下を向く
turn_down
# 座標を更新
@y += 1
# 歩数増加
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)
# 後続メンバーを歩かせる
for member in $game_pmembers.values
member.walk
end
max = $game_pmembers.size
for i in 0 .. max - 2
$game_pmembers[max - i].dir = $game_pmembers[max - i - 1].dir
end
$game_pmembers[1].dir = 4
# 左を向く
turn_left
# 座標を更新
@x -= 1
# 歩数増加
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)
# 後続メンバーを歩かせる
for member in $game_pmembers.values
member.walk
end
max = $game_pmembers.size
for i in 0 .. max - 2
$game_pmembers[max - i].dir = $game_pmembers[max - i - 1].dir
end
$game_pmembers[1].dir = 6
# 右を向く
turn_right
# 座標を更新
@x += 1
# 歩数増加
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)
# 後続メンバーを歩かせる
for member in $game_pmembers.values
member.walk
end
max = $game_pmembers.size
for i in 0 .. max - 2
$game_pmembers[max - i].dir = $game_pmembers[max - i - 1].dir
end
$game_pmembers[1].dir = 8
# 上を向く
turn_up
# 座標を更新
@y -= 1
# 歩数増加
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))
# 後続メンバーを歩かせる
for member in $game_pmembers.values
member.walk
end
max = $game_pmembers.size
for i in 0 .. max - 2
$game_pmembers[max - i].dir = $game_pmembers[max - i - 1].dir
end
$game_pmembers[1].dir = 1
# 座標を更新
@x -= 1
@y += 1
# 歩数増加
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))
# 後続メンバーを歩かせる
for member in $game_pmembers.values
member.walk
end
max = $game_pmembers.size
for i in 0 .. max - 2
$game_pmembers[max - i].dir = $game_pmembers[max - i - 1].dir
end
$game_pmembers[1].dir = 3
# 座標を更新
@x += 1
@y += 1
# 歩数増加
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))
# 後続メンバーを歩かせる
for member in $game_pmembers.values
member.walk
end
max = $game_pmembers.size
for i in 0 .. max - 2
$game_pmembers[max - i].dir = $game_pmembers[max - i - 1].dir
end
$game_pmembers[1].dir = 7
# 座標を更新
@x -= 1
@y -= 1
# 歩数増加
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))
# 後続メンバーを歩かせる
for member in $game_pmembers.values
member.walk
end
max = $game_pmembers.size
for i in 0 .. max - 2
$game_pmembers[max - i].dir = $game_pmembers[max - i - 1].dir
end
$game_pmembers[1].dir = 9
# 座標を更新
@x += 1
@y -= 1
# 歩数増加
increase_steps
end
end
end
class Interpreter
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
# ループカウントを初期化
@loop_count = 0
# ループ
loop do
# ループカウントに 1 加算
@loop_count += 1
# イベントコマンド 100 個を実行した場合
if @loop_count > 100
# フリーズ防止のため、Graphics.update を呼ぶ
Graphics.update
@loop_count = 0
end
# マップがイベント起動時と異なる場合
if $game_map.map_id != @map_id
# イベント ID を 0 にする
@event_id = 0
end
# 子インタプリタが存在する場合
if @child_interpreter != nil
# 子インタプリタを更新
@child_interpreter.update
# 子インタプリタの実行が終わった場合
unless @child_interpreter.running?
# 子インタプリタを消去
@child_interpreter = nil
end
# 子インタプリタがまだ存在する場合
if @child_interpreter != nil
return
end
end
# メッセージ終了待機中の場合
if @message_waiting
return
end
# 移動完了待機中の場合
if @move_route_waiting
# プレイヤーが移動ルート強制中の場合
if $game_player.move_route_forcing
return
end
# ループ (マップイベント)
for event in $game_map.events.values
# このイベントが移動ルート強制中の場合
if event.move_route_forcing
return
end
end
#>---------------------------------------------------------------------------
# ループ(パーティメンバ)
for member in $game_pmembers.values
# このメンバが移動ルート強制中の場合
if member.move_route_forcing
return
end
end
#<---------------------------------------------------------------------------
# 移動完了待機中フラグをクリア
@move_route_waiting = false
end
# ボタン入力待機中の場合
if @button_input_variable_id > 0
# ボタン入力の処理を実行
input_button
return
end
# ウェイト中の場合
if @wait_count > 0
# ウェイトカウントを減らす
@wait_count -= 1
return
end
# アクションを強制されているバトラーが存在する場合
if $game_temp.forcing_battler != nil
return
end
# 各種画面の呼び出しフラグがセットされている場合
if $game_temp.battle_calling or
$game_temp.shop_calling or
$game_temp.name_calling or
$game_temp.menu_calling or
$game_temp.save_calling or
$game_temp.gameover
return
end
# 実行内容リストが空の場合
if @list == nil
# メインのマップイベントの場合
if @main
# 起動中のイベントをセットアップ
setup_starting_event
end
# 何もセットアップされなかった場合
if @list == nil
return
end
end
# イベントコマンドの実行を試み、戻り値が false の場合
if execute_command == false
return
end
# インデックスを進める
@index += 1
end
end
end
class Scene_Title
#--------------------------------------------------------------------------
# ● コマンド : ニューゲーム
#--------------------------------------------------------------------------
def command_new_game
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# BGM を停止
Audio.bgm_stop
# プレイ時間計測用のフレームカウントをリセット
Graphics.frame_count = 0
# 各種ゲームオブジェクトを作成
$game_temp = Game_Temp.new
$game_system = Game_System.new
$game_switches = Game_Switches.new
$game_variables = Game_Variables.new
$game_self_switches = Game_SelfSwitches.new
$game_screen = Game_Screen.new
$game_actors = Game_Actors.new
$game_party = Game_Party.new
$game_troop = Game_Troop.new
$game_map = Game_Map.new
$game_player = Game_Player.new
# 初期パーティをセットアップ
$game_party.setup_starting_members
#>---------------------------------------------------------------------------
# パーティメンバ後続キャラクタを設定
$game_pmembers = {}
for i in 1 .. TKS::The_Number_of_PMembers - 1
$game_pmembers[i] = Game_PMembers.new(i)
end
#<---------------------------------------------------------------------------
# 初期位置のマップをセットアップ
$game_map.setup($data_system.start_map_id)
# プレイヤーを初期位置に移動
$game_player.moveto($data_system.start_x, $data_system.start_y)
# プレイヤーをリフレッシュ
$game_player.refresh
#>---------------------------------------------------------------------------
# パーティメンバを更新
for member in $game_pmembers.values
member.update
end
#<---------------------------------------------------------------------------
# マップに設定されている BGM と BGS の自動切り替えを実行
$game_map.autoplay
# マップを更新 (並列イベント実行)
$game_map.update
# マップ画面に切り替え
$scene = Scene_Map.new
end
end
class Scene_Map
#--------------------------------------------------------------------------
# ● プレイヤーの場所移動
#--------------------------------------------------------------------------
def transfer_player
# プレイヤー場所移動フラグをクリア
$game_temp.player_transferring = false
# 移動先が現在のマップと異なる場合
if $game_map.map_id != $game_temp.player_new_map_id
# 新しいマップをセットアップ
$game_map.setup($game_temp.player_new_map_id)
end
# プレイヤーの位置を設定
$game_player.moveto($game_temp.player_new_x, $game_temp.player_new_y)
# プレイヤーとパーティメンバの向きを設定
case $game_temp.player_new_direction
#>---------------------------------------------------------------------------
when 0 # 無指定
for member in $game_pmembers.values
case $game_player.direction
when 2
member.turn_down
when 4
member.turn_left
when 6
member.turn_right
when 8
member.turn_up
end
end
#<---------------------------------------------------------------------------
when 2 # 下
$game_player.turn_down
#>---------------------------------------------------------------------------
for member in $game_pmembers.values
member.turn_down
end
#<---------------------------------------------------------------------------
when 4 # 左
$game_player.turn_left
#>---------------------------------------------------------------------------
for member in $game_pmembers.values
member.turn_left
end
#<---------------------------------------------------------------------------
when 6 # 右
$game_player.turn_right
#>---------------------------------------------------------------------------
for member in $game_pmembers.values
member.turn_right
end
#<---------------------------------------------------------------------------
when 8 # 上
$game_player.turn_up
#>---------------------------------------------------------------------------
for member in $game_pmembers.values
member.turn_up
end
#<---------------------------------------------------------------------------
end
# プレイヤーとパーティメンバの姿勢を矯正
$game_player.straighten
#>---------------------------------------------------------------------------
for member in $game_pmembers.values
member.straighten
end
#<---------------------------------------------------------------------------
# マップを更新 (並列イベント実行)
$game_map.update
# スプライトセットを再作成
@spriteset.dispose
@spriteset = Spriteset_Map.new
# トランジション処理中の場合
if $game_temp.transition_processing
# トランジション処理中フラグをクリア
$game_temp.transition_processing = false
# トランジション実行
Graphics.transition(20)
end
# マップに設定されている BGM と BGS の自動切り替えを実行
$game_map.autoplay
# フレームリセット
Graphics.frame_reset
# 入力情報を更新
Input.update
end
end
class Scene_Save
#--------------------------------------------------------------------------
# ● セーブデータの書き込み
# file : 書き込み用ファイルオブジェクト (オープン済み)
#--------------------------------------------------------------------------
alias tks_write_save_data write_save_data
def write_save_data(file)
tks_write_save_data(file)
Marshal.dump($game_pmembers, file)
end
end
class Scene_Load
#--------------------------------------------------------------------------
# ● セーブデータの読み込み
# file : 読み込み用ファイルオブジェクト (オープン済み)
#--------------------------------------------------------------------------
alias tks_read_save_data read_save_data
def read_save_data(file)
tks_read_save_data(file)
$game_pmembers = Marshal.load(file)
end
end
スクリプトエディタで、Mainセクションの上に新たなセクションを作り、
そこに貼り付ければ、多分動くと思います。
ただし、セーブファイルがらみの処理を改変していますので
セーブデータからゲームを始めないでください。エラーになります。
動かない場合は、再定義の代わりに#>----から#<----の間のスクリプトを自分で挿入してください。
他のスクリプトと干渉を起こす可能性のある再定義メソッドは以下のとおりです。
Game_Character
passable?
Spriteset_Map
initialize
Game_Player
move_down
move_left
move_right
move_up
move_lower_left
move_lower_right
move_upper_left
move_upper_right
Interpreter
update
Scene_Title
command_new_game
Scene_Map
transfer_player