Project1
标题:
关于跟随队员的跳跃问题
[打印本页]
作者:
yyf_ang
时间:
2013-10-11 13:25
标题:
关于跟随队员的跳跃问题
本帖最后由 yyf_ang 于 2013-10-11 14:12 编辑
如果队长跳过一条沟,如何让后面的队员也跟着一起跳过去
作者:
tseyik
时间:
2013-10-11 13:47
#==============================================================================
# ■ 隊列ジャンプ実装 (VX Ace用)
#------------------------------------------------------------------------------
# バージョン : 1.06
# 最終更新日 : 2012/04/19
# 製作者 : CanariAlternate
# サイト名 : カルトの鳥篭
# サイトURL : http://canarialt.blog.fc2.com
#------------------------------------------------------------------------------
# 設置場所 : 「隊列強制認識」より下。対応Ver1.08以降
#
# 機能 : 隊列をジャンプに対応させます。
#
# 仕様 : 隊列の先頭(プレイヤー) ~ 隊列の最後尾 のジャンプが終了するまでダッシュが
# 禁止されます。この間に移動速度が変化すると隊列の間隔がずれる為です。
#
# : 隊列の先頭(プレイヤー) ~ 隊列の最後尾 のジャンプが終了するまでの間は
# 移動速度の変更を行わないことを推奨します。理由は上記と同様です。
#
# : 隊列のキャラクターはVX Aceのデフォルトの仕様ではパーティ人数に関係なく3人
# 生成されています。隊列歩行をOFFにしていても透明なだけで隊列はプレイヤー
# の後ろを行進しています。
# 当スクリプトでは可視状態の隊列のキャラクターのみジャンプを行います。
# その為、特に長距離ジャンプの直後などは不可視状態の隊列のキャラクターが
# 壁の中に居るという状況がありえます。
# この状態でメンバーの追加や隊列歩行のONなどで不可視が解除されると
# 隊列のキャラクターが壁の中に出現したりします。
# これに対する対策としては直前に場所移動を実行したり隊列強制認識を使って
# 隊列のキャラクターに対してイベントの位置設定を実行したりです。
#
# ※隊列のキャラクターは壁の中に出現したとしてもすり抜けてプレイヤーを
# 追いかけてきます。なのでこれらは見た目の問題となります。
#
#------------------------------------------------------------------------------
# 更新履歴 : 2012/04/12 Ver1.00 隊列ジャンプ実装を作成
# : 2012/04/13 Ver1.01 1/2倍速以下で正常に動作しないのを修正
# : 2012/04/14 Ver1.02 同期が上手くいかないのでアルゴリズムを変更
# : 2012/04/16 Ver1.03 同期が上手くいかないのでアルゴリズムを変更
# : 2012/04/18 Ver1.04 隊列の人数が5人以上でも同期できるように修正
# : 2012/04/19 Ver1.05 可視の隊員がジャンプ終了でダッシュ禁止解除に修正
# : 2012/04/19 Ver1.06 場所移動時にジャンプ状態が初期化されてないのを修正
#==============================================================================
$imported ||= {}
$imported["CanariAlternate_Jump_Follower"] = true
if $imported["CanariAlternate_Jump_Follower"]
#==============================================================================
# ■ Game_CharacterBase
#------------------------------------------------------------------------------
# キャラクターを扱う基本のクラスです。全てのキャラクターに共通する、座標やグ
# ラフィックなどの基本的な情報を保持します。
#==============================================================================
class Game_CharacterBase
#--------------------------------------------------------------------------
# ● 指定位置に移動 [alias]
#--------------------------------------------------------------------------
alias _moveto_calt moveto
def moveto(x, y)
@jump_count = 0 # ジャンプ状態も初期化
_moveto_calt(x, y)
end
end
#==============================================================================
# ■ Game_Player
#------------------------------------------------------------------------------
# プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの
# 機能を持っています。このクラスのインスタンスは $game_player で参照されます。
#==============================================================================
class Game_Player < Game_Character
attr_writer :jump_point # ジャンプ記憶変数
attr_reader :jump_count
#--------------------------------------------------------------------------
# ● ジャンプ記憶変数の取得 [new]
#--------------------------------------------------------------------------
def jump_point
return @jump_point ||= []
end
#--------------------------------------------------------------------------
# ● 場所移動の実行 [alias]
#--------------------------------------------------------------------------
alias _perform_transfer_calt perform_transfer
def perform_transfer
@jump_point = [] if transfer? # ジャンプ記憶変数の初期化
_perform_transfer_calt
end
#--------------------------------------------------------------------------
# ● 追従と同期を禁止 [alias]
#--------------------------------------------------------------------------
if $imported["CanariAlternate_Overwrite_Follower"]
alias _follow_disable_calt follow_disable
def follow_disable
_follow_disable_calt
@jump_point = [] # ジャンプ記憶変数の初期化
end
end
#--------------------------------------------------------------------------
# ● ジャンプが実行されるか判定 [new]
# x_plus : X 座標加算値
# y_plus : Y 座標加算値
#--------------------------------------------------------------------------
def jump_judge(x_plus, y_plus)
x_plus != 0 || y_plus != 0
end
#--------------------------------------------------------------------------
# ● ジャンプ [alias]
# x_plus : X 座標加算値
# y_plus : Y 座標加算値
#--------------------------------------------------------------------------
alias _jump_calt jump
def jump(x_plus, y_plus)
@duplication = true if jump_point.size == 0 # 重複実行防止
@followers.move if jump_judge(x_plus, y_plus) # 隊列の追従を呼出
_jump_calt(x_plus, y_plus) # 再定義前の処理
if $imported["CanariAlternate_Overwrite_Follower"] # 隊列強制認識を実装
return if @followers.follow_disable # 追従が禁止されている時
end
return if @followers.visible_last_follower_index == 0 # 可視状態の隊員がいない
@jump_point.push([1, @x, @y]) if jump_judge(x_plus, y_plus) # ジャンプ情報を記憶
end
#--------------------------------------------------------------------------
# ● ダッシュ状態判定 [alias]
#--------------------------------------------------------------------------
alias _dash_calt? dash?
def dash?
# 可視状態の隊員全員がジャンプ終了するまでダッシュ禁止
if jump_point.size > 0 || @followers.visible_folloers.any? {|follower| follower.jumping? }
if $imported["CanariAlternate_Overwrite_Follower"] # 隊列強制認識を実装
return false unless @followers.follow_disable # 追従が禁止されていない時
else
return false
end
end
_dash_calt?
end
#--------------------------------------------------------------------------
# ● フレーム更新 [alias]
#--------------------------------------------------------------------------
alias _update_calt update
def update
if jump_point.size > 0
@followers.move if moving? && !@duplication # 移動中かつ重複実行でない
@duplication = false if @duplication # 重複実行防止を偽を代入
end
_update_calt
end
#--------------------------------------------------------------------------
# ● 移動に関する計算式の取得 [new]
#--------------------------------------------------------------------------
def move_speed_formula
2 ** get_move_speed
end
#--------------------------------------------------------------------------
# ● 移動に必要なフレーム数の取得 [new]
#--------------------------------------------------------------------------
def real_move_frame
256 / move_speed_formula
end
#--------------------------------------------------------------------------
# ● 移動速度の取得 [new]
#--------------------------------------------------------------------------
def get_move_speed
@move_speed
end
#--------------------------------------------------------------------------
# ● ジャンプ時間の計算 [new]
# cnt : 計算途中のデータ, char : 計算対象
#--------------------------------------------------------------------------
def jump_frame_formula(cnt, char)
jump_point.size.times do |i| # ジャンプ時間計算
if jump_point[i][0] == char.member_index
# 基準座標からの移動距離を計算
px = jump_point[i][1] - cnt[1]
py = jump_point[i][2] - cnt[2]
# ジャンプ時間を加算
cnt[0] += 2 * (10 + Math.sqrt(px * px + py * py).round - get_move_speed)
cnt[1] = jump_point[i][1] # 基準X座標を更新
cnt[2] = jump_point[i][2] # 基準Y座標を更新
end
end
sx = char.preceding_character.x - cnt[1]
sy = char.preceding_character.y - cnt[2]
if char.member_index > 1
# 先導キャラがプレイヤーでない
if sx != 0 || sy != 0
cnt[0] += real_move_frame
cnt[1] = char.preceding_character.x
cnt[2] = char.preceding_character.y
end
# 先導キャラを対象に計算を行う
cnt = jump_frame_formula(cnt, char.preceding_character) # 再帰的に
else
# 先導がプレイヤー
if sx != 0 || sy != 0
# 実座標から移動済みフレーム数を逆算
rx = char.preceding_character.real_x - cnt[1]
ry = char.preceding_character.real_y - cnt[2]
fx = rx.abs / (move_speed_formula / 256.0)
fy = ry.abs / (move_speed_formula / 256.0)
cnt[0] += fx > fy ? fx : fy # 移動済フレーム数を加算
elsif char.preceding_character.jumping?
# ジャンプ未終了フレーム数を減算
cnt[0] -= char.preceding_character.jump_count
end
end
return cnt
end
#--------------------------------------------------------------------------
# ● ジャンプ処理中の追従処理の実行判定 [new]
# char : 実行判定の対象
#--------------------------------------------------------------------------
def jump_follower_move?(char)
return true if jump_point.size == 0 # ジャンプ記憶変数が空なら実行
@duplication = true unless moving? # 停止中なら重複実行防止に真を代入
# 先頭キャラとのフレーム数の差, 計算用基準座標x, 計算用基準座標y
cnt = [0, char.x, char.y]
if char.jumping? # ジャンプ中
cnt[0] += char.jump_count # ジャンプ未終了フレーム数を加算
elsif char.moving? # 移動している
# 実座標から移動未終了フレーム数を逆算
rx = char.real_x - cnt[1]
ry = char.real_y - cnt[2]
fx = rx.abs / (move_speed_formula / 256.0)
fy = ry.abs / (move_speed_formula / 256.0)
cnt[0] += fx > fy ? fx : fy # 移動未終了フレーム数を加算
end
cnt = jump_frame_formula(cnt, char) # ジャンプ時間の計算
# 先頭とのフレーム数の差が必要な間隔以上なら実行
return (cnt[0] >= real_move_frame * char.member_index) ? true : false
end
end
#==============================================================================
# ■ Game_Follower
#------------------------------------------------------------------------------
# フォロワーを扱うクラスです。フォロワーとは、隊列歩行で表示する、先頭以外の
# 仲間キャラクターのことです。Game_Followers クラスの内部で参照されます。
#==============================================================================
class Game_Follower < Game_Character
attr_reader :preceding_character
attr_reader :member_index
attr_reader :jump_count
#--------------------------------------------------------------------------
# ● 先導キャラクターを追う [override]
#--------------------------------------------------------------------------
def chase_preceding_character
unless moving?
return unless $game_player.jump_follower_move?(self) # 実行判定
sx = distance_x_from(@preceding_character.x)
sy = distance_y_from(@preceding_character.y)
# ジャンプ処理
if $game_player.jump_point.size > 0
jp_exe = false # 実行判定結果
jpdel = false # 記憶用済み判定結果
$game_player.jump_point.size.times do |i|
if $game_player.jump_point[i][0] == @member_index && !jp_exe
$game_player.jump_point[i][0] += 1
jp_exe = i
# 用済み判定
jpdel = i if $game_player.jump_point[i][0] > $game_player.followers.visible_last_follower_index
end
end
if jp_exe
x_plus = $game_player.jump_point[jp_exe][1] - x
y_plus = $game_player.jump_point[jp_exe][2] - y
jump(x_plus, y_plus)
$game_player.jump_point.delete_at jpdel if jpdel # 用済みなら消去
return
end
end
# 衝突判定(先導キャラの移動先には進入しない)
# ※この機能はジャンプとは関連が無いので消去しても全体に影響は無い。
if (sx.abs > 1 || sy.abs > 1) && @member_index > 1
# 自己の移動予定座標の演算
plan_x = @x # 移動予定座標X
plan_y = @y # 移動予定座標Y
if sx != 0 && sy != 0
plan_x += sx > 0 ? -1 : 1
plan_y += sy > 0 ? -1 : 1
elsif sx != 0
plan_x += sx > 0 ? -1 : 1
elsif sy != 0
plan_y += sy > 0 ? -1 : 1
end
# 先導キャラの移動予定座標の演算
p_sx = @preceding_character.distance_x_from(@preceding_character.preceding_character.x)
p_sy = @preceding_character.distance_y_from(@preceding_character.preceding_character.y)
p_plan_x = @preceding_character.x # 移動予定座標X
p_plan_y = @preceding_character.y # 移動予定座標Y
if p_sx != 0 && p_sy != 0
p_plan_x += p_sx > 0 ? -1 : 1
p_plan_y += p_sy > 0 ? -1 : 1
elsif p_sx != 0
p_plan_x += p_sx > 0 ? -1 : 1
elsif p_sy != 0
p_plan_y += p_sy > 0 ? -1 : 1
end
# 同座標へ移動予定の場合は向き変更のみ行い終了
if plan_x == p_plan_x && plan_y == p_plan_y
if sx.abs > sy.abs
set_direction(sx > 0 ? 4 : 6)
else
set_direction(sy > 0 ? 8 : 2)
end
return
end
end
# プリセット処理
if sx != 0 && sy != 0
move_diagonal(sx > 0 ? 4 : 6, sy > 0 ? 8 : 2)
elsif sx != 0
move_straight(sx > 0 ? 4 : 6)
elsif sy != 0
move_straight(sy > 0 ? 8 : 2)
end
end
end
end
#==============================================================================
# ■ Game_Followers
#------------------------------------------------------------------------------
# フォロワーの配列のラッパーです。このクラスは Game_Player クラスの内部で使
# 用されます。
#==============================================================================
class Game_Followers
#--------------------------------------------------------------------------
# ● 可視状態隊員の最後尾の member_index を取得 [new]
#--------------------------------------------------------------------------
def visible_last_follower_index
v_folloers = visible_folloers
return v_folloers.size == 0 ? 0 : v_folloers[-1].member_index
end
end
end
复制代码
作者:
yyf_ang
时间:
2013-10-11 14:10
tseyik 发表于 2013-10-11 13:47
脚本复制过去果然可以了,万分感谢。
话说我对脚本基本不懂呢,佩服那些写出脚本的人。
作者:
yyf_ang
时间:
2013-10-11 14:11
还有这个脚本看起来好复杂,原来还以为是几句话就能解决的呢,我果然是脚本盲。
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1