Project1

标题: 关于跟随队员的跳跃问题 [打印本页]

作者: yyf_ang    时间: 2013-10-11 13:25
标题: 关于跟随队员的跳跃问题
本帖最后由 yyf_ang 于 2013-10-11 14:12 编辑

如果队长跳过一条沟,如何让后面的队员也跟着一起跳过去
作者: tseyik    时间: 2013-10-11 13:47
  1. #==============================================================================
  2. # ■ 隊列ジャンプ実装 (VX Ace用)
  3. #------------------------------------------------------------------------------
  4. # バージョン : 1.06
  5. # 最終更新日 : 2012/04/19
  6. # 製作者     : CanariAlternate
  7. # サイト名   : カルトの鳥篭
  8. # サイトURL  : http://canarialt.blog.fc2.com
  9. #------------------------------------------------------------------------------
  10. # 設置場所 : 「隊列強制認識」より下。対応Ver1.08以降
  11. #
  12. # 機能 : 隊列をジャンプに対応させます。
  13. #
  14. # 仕様 : 隊列の先頭(プレイヤー) ~ 隊列の最後尾 のジャンプが終了するまでダッシュが
  15. #          禁止されます。この間に移動速度が変化すると隊列の間隔がずれる為です。
  16. #
  17. #      : 隊列の先頭(プレイヤー) ~ 隊列の最後尾 のジャンプが終了するまでの間は
  18. #          移動速度の変更を行わないことを推奨します。理由は上記と同様です。
  19. #
  20. #      : 隊列のキャラクターはVX Aceのデフォルトの仕様ではパーティ人数に関係なく3人
  21. #          生成されています。隊列歩行をOFFにしていても透明なだけで隊列はプレイヤー
  22. #          の後ろを行進しています。
  23. #          当スクリプトでは可視状態の隊列のキャラクターのみジャンプを行います。
  24. #          その為、特に長距離ジャンプの直後などは不可視状態の隊列のキャラクターが
  25. #          壁の中に居るという状況がありえます。
  26. #          この状態でメンバーの追加や隊列歩行のONなどで不可視が解除されると
  27. #          隊列のキャラクターが壁の中に出現したりします。
  28. #          これに対する対策としては直前に場所移動を実行したり隊列強制認識を使って
  29. #          隊列のキャラクターに対してイベントの位置設定を実行したりです。
  30. #
  31. #          ※隊列のキャラクターは壁の中に出現したとしてもすり抜けてプレイヤーを
  32. #            追いかけてきます。なのでこれらは見た目の問題となります。
  33. #
  34. #------------------------------------------------------------------------------
  35. # 更新履歴 : 2012/04/12 Ver1.00 隊列ジャンプ実装を作成
  36. #          : 2012/04/13 Ver1.01 1/2倍速以下で正常に動作しないのを修正
  37. #          : 2012/04/14 Ver1.02 同期が上手くいかないのでアルゴリズムを変更
  38. #          : 2012/04/16 Ver1.03 同期が上手くいかないのでアルゴリズムを変更
  39. #          : 2012/04/18 Ver1.04 隊列の人数が5人以上でも同期できるように修正
  40. #          : 2012/04/19 Ver1.05 可視の隊員がジャンプ終了でダッシュ禁止解除に修正
  41. #          : 2012/04/19 Ver1.06 場所移動時にジャンプ状態が初期化されてないのを修正
  42. #==============================================================================

  43. $imported ||= {}
  44. $imported["CanariAlternate_Jump_Follower"] = true
  45. if $imported["CanariAlternate_Jump_Follower"]

  46. #==============================================================================
  47. # ■ Game_CharacterBase
  48. #------------------------------------------------------------------------------
  49. #  キャラクターを扱う基本のクラスです。全てのキャラクターに共通する、座標やグ
  50. # ラフィックなどの基本的な情報を保持します。
  51. #==============================================================================
  52. class Game_CharacterBase
  53.   #--------------------------------------------------------------------------
  54.   # ● 指定位置に移動 [alias]
  55.   #--------------------------------------------------------------------------
  56.   alias _moveto_calt moveto
  57.   def moveto(x, y)
  58.     @jump_count = 0 # ジャンプ状態も初期化
  59.     _moveto_calt(x, y)
  60.   end
  61. end

  62. #==============================================================================
  63. # ■ Game_Player
  64. #------------------------------------------------------------------------------
  65. #  プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの
  66. # 機能を持っています。このクラスのインスタンスは $game_player で参照されます。
  67. #==============================================================================
  68. class Game_Player < Game_Character
  69.   attr_writer   :jump_point   # ジャンプ記憶変数
  70.   attr_reader   :jump_count
  71.   #--------------------------------------------------------------------------
  72.   # ● ジャンプ記憶変数の取得 [new]
  73.   #--------------------------------------------------------------------------
  74.   def jump_point
  75.     return @jump_point ||= []
  76.   end
  77.   #--------------------------------------------------------------------------
  78.   # ● 場所移動の実行 [alias]
  79.   #--------------------------------------------------------------------------
  80.   alias _perform_transfer_calt perform_transfer
  81.   def perform_transfer
  82.     @jump_point = [] if transfer? # ジャンプ記憶変数の初期化
  83.     _perform_transfer_calt
  84.   end
  85.   #--------------------------------------------------------------------------
  86.   # ● 追従と同期を禁止 [alias]
  87.   #--------------------------------------------------------------------------
  88.   if $imported["CanariAlternate_Overwrite_Follower"]
  89.     alias _follow_disable_calt follow_disable
  90.     def follow_disable
  91.       _follow_disable_calt
  92.       @jump_point = [] # ジャンプ記憶変数の初期化
  93.     end
  94.   end
  95.   #--------------------------------------------------------------------------
  96.   # ● ジャンプが実行されるか判定 [new]
  97.   #     x_plus : X 座標加算値
  98.   #     y_plus : Y 座標加算値
  99.   #--------------------------------------------------------------------------
  100.   def jump_judge(x_plus, y_plus)
  101.     x_plus != 0 || y_plus != 0
  102.   end
  103.   #--------------------------------------------------------------------------
  104.   # ● ジャンプ [alias]
  105.   #     x_plus : X 座標加算値
  106.   #     y_plus : Y 座標加算値
  107.   #--------------------------------------------------------------------------
  108.   alias _jump_calt jump
  109.   def jump(x_plus, y_plus)
  110.     @duplication = true if jump_point.size == 0 # 重複実行防止
  111.    
  112.     @followers.move if jump_judge(x_plus, y_plus) # 隊列の追従を呼出
  113.    
  114.     _jump_calt(x_plus, y_plus) # 再定義前の処理
  115.    
  116.     if $imported["CanariAlternate_Overwrite_Follower"] # 隊列強制認識を実装
  117.       return if @followers.follow_disable # 追従が禁止されている時
  118.     end
  119.     return if @followers.visible_last_follower_index == 0 # 可視状態の隊員がいない
  120.     @jump_point.push([1, @x, @y]) if jump_judge(x_plus, y_plus) # ジャンプ情報を記憶
  121.   end
  122.   #--------------------------------------------------------------------------
  123.   # ● ダッシュ状態判定 [alias]
  124.   #--------------------------------------------------------------------------
  125.   alias _dash_calt? dash?
  126.   def dash?
  127.     # 可視状態の隊員全員がジャンプ終了するまでダッシュ禁止
  128.     if jump_point.size > 0 || @followers.visible_folloers.any? {|follower| follower.jumping? }
  129.       if $imported["CanariAlternate_Overwrite_Follower"] # 隊列強制認識を実装
  130.         return false unless @followers.follow_disable # 追従が禁止されていない時
  131.       else
  132.         return false
  133.       end
  134.     end
  135.     _dash_calt?
  136.   end
  137.   #--------------------------------------------------------------------------
  138.   # ● フレーム更新 [alias]
  139.   #--------------------------------------------------------------------------
  140.   alias _update_calt update
  141.   def update
  142.     if jump_point.size > 0
  143.       @followers.move if moving? && !@duplication # 移動中かつ重複実行でない
  144.       
  145.       @duplication = false if @duplication # 重複実行防止を偽を代入
  146.     end
  147.     _update_calt
  148.   end
  149.   #--------------------------------------------------------------------------
  150.   # ● 移動に関する計算式の取得 [new]
  151.   #--------------------------------------------------------------------------
  152.   def move_speed_formula
  153.     2 ** get_move_speed
  154.   end
  155.   #--------------------------------------------------------------------------
  156.   # ● 移動に必要なフレーム数の取得 [new]
  157.   #--------------------------------------------------------------------------
  158.   def real_move_frame
  159.     256 / move_speed_formula
  160.   end
  161.   #--------------------------------------------------------------------------
  162.   # ● 移動速度の取得 [new]
  163.   #--------------------------------------------------------------------------
  164.   def get_move_speed
  165.     @move_speed
  166.   end
  167.   #--------------------------------------------------------------------------
  168.   # ● ジャンプ時間の計算 [new]
  169.   #      cnt : 計算途中のデータ,  char : 計算対象
  170.   #--------------------------------------------------------------------------
  171.   def jump_frame_formula(cnt, char)
  172.     jump_point.size.times do |i| # ジャンプ時間計算
  173.       if jump_point[i][0] == char.member_index
  174.         # 基準座標からの移動距離を計算
  175.         px = jump_point[i][1] - cnt[1]
  176.         py = jump_point[i][2] - cnt[2]
  177.         # ジャンプ時間を加算
  178.         cnt[0] += 2 * (10 + Math.sqrt(px * px + py * py).round - get_move_speed)
  179.         cnt[1] = jump_point[i][1] # 基準X座標を更新
  180.         cnt[2] = jump_point[i][2] # 基準Y座標を更新
  181.       end
  182.     end
  183.    
  184.     sx = char.preceding_character.x - cnt[1]
  185.     sy = char.preceding_character.y - cnt[2]
  186.     if char.member_index > 1
  187.       # 先導キャラがプレイヤーでない
  188.       if sx != 0 || sy != 0
  189.         cnt[0] += real_move_frame
  190.         cnt[1] = char.preceding_character.x
  191.         cnt[2] = char.preceding_character.y
  192.       end
  193.       # 先導キャラを対象に計算を行う
  194.       cnt = jump_frame_formula(cnt, char.preceding_character) # 再帰的に
  195.     else
  196.       # 先導がプレイヤー
  197.       if sx != 0 || sy != 0
  198.         # 実座標から移動済みフレーム数を逆算
  199.         rx = char.preceding_character.real_x - cnt[1]
  200.         ry = char.preceding_character.real_y - cnt[2]
  201.         fx = rx.abs / (move_speed_formula / 256.0)
  202.         fy = ry.abs / (move_speed_formula / 256.0)
  203.         cnt[0] += fx > fy ? fx : fy # 移動済フレーム数を加算
  204.       elsif char.preceding_character.jumping?
  205.         # ジャンプ未終了フレーム数を減算
  206.         cnt[0] -= char.preceding_character.jump_count
  207.       end
  208.     end
  209.    
  210.     return cnt
  211.   end
  212.   #--------------------------------------------------------------------------
  213.   # ● ジャンプ処理中の追従処理の実行判定 [new]
  214.   #      char : 実行判定の対象
  215.   #--------------------------------------------------------------------------
  216.   def jump_follower_move?(char)
  217.     return true if jump_point.size == 0 # ジャンプ記憶変数が空なら実行
  218.    
  219.     @duplication = true unless moving? # 停止中なら重複実行防止に真を代入
  220.    
  221.     # 先頭キャラとのフレーム数の差, 計算用基準座標x, 計算用基準座標y
  222.     cnt = [0, char.x, char.y]
  223.     if char.jumping? # ジャンプ中
  224.       cnt[0] += char.jump_count # ジャンプ未終了フレーム数を加算
  225.     elsif char.moving? # 移動している
  226.       # 実座標から移動未終了フレーム数を逆算
  227.       rx = char.real_x - cnt[1]
  228.       ry = char.real_y - cnt[2]
  229.       fx = rx.abs / (move_speed_formula / 256.0)
  230.       fy = ry.abs / (move_speed_formula / 256.0)
  231.       cnt[0] += fx > fy ? fx : fy # 移動未終了フレーム数を加算
  232.     end
  233.       
  234.     cnt = jump_frame_formula(cnt, char) # ジャンプ時間の計算
  235.       
  236.     # 先頭とのフレーム数の差が必要な間隔以上なら実行
  237.     return (cnt[0] >= real_move_frame * char.member_index) ? true : false
  238.   end
  239. end

  240. #==============================================================================
  241. # ■ Game_Follower
  242. #------------------------------------------------------------------------------
  243. #  フォロワーを扱うクラスです。フォロワーとは、隊列歩行で表示する、先頭以外の
  244. # 仲間キャラクターのことです。Game_Followers クラスの内部で参照されます。
  245. #==============================================================================
  246. class Game_Follower < Game_Character
  247.   attr_reader   :preceding_character
  248.   attr_reader   :member_index
  249.   attr_reader   :jump_count
  250.   #--------------------------------------------------------------------------
  251.   # ● 先導キャラクターを追う [override]
  252.   #--------------------------------------------------------------------------
  253.   def chase_preceding_character
  254.     unless moving?
  255.       return unless $game_player.jump_follower_move?(self) # 実行判定
  256.       
  257.       sx = distance_x_from(@preceding_character.x)
  258.       sy = distance_y_from(@preceding_character.y)
  259.       
  260.       # ジャンプ処理
  261.       if $game_player.jump_point.size > 0
  262.         jp_exe = false # 実行判定結果
  263.         jpdel = false # 記憶用済み判定結果
  264.         $game_player.jump_point.size.times do |i|
  265.           if $game_player.jump_point[i][0] == @member_index && !jp_exe
  266.             $game_player.jump_point[i][0] += 1
  267.             jp_exe = i
  268.             # 用済み判定
  269.             jpdel = i if $game_player.jump_point[i][0] > $game_player.followers.visible_last_follower_index
  270.           end
  271.         end
  272.         if jp_exe
  273.           x_plus = $game_player.jump_point[jp_exe][1] - x
  274.           y_plus = $game_player.jump_point[jp_exe][2] - y
  275.           jump(x_plus, y_plus)
  276.           $game_player.jump_point.delete_at jpdel if jpdel # 用済みなら消去
  277.           return
  278.         end
  279.       end
  280.       
  281.       # 衝突判定(先導キャラの移動先には進入しない)
  282.       # ※この機能はジャンプとは関連が無いので消去しても全体に影響は無い。
  283.       if (sx.abs > 1 || sy.abs > 1) && @member_index > 1
  284.         # 自己の移動予定座標の演算
  285.         plan_x = @x # 移動予定座標X
  286.         plan_y = @y # 移動予定座標Y
  287.         if sx != 0 && sy != 0
  288.           plan_x += sx > 0 ? -1 : 1
  289.           plan_y += sy > 0 ? -1 : 1
  290.         elsif sx != 0
  291.           plan_x += sx > 0 ? -1 : 1
  292.         elsif sy != 0
  293.           plan_y += sy > 0 ? -1 : 1
  294.         end
  295.         # 先導キャラの移動予定座標の演算
  296.         p_sx = @preceding_character.distance_x_from(@preceding_character.preceding_character.x)
  297.         p_sy = @preceding_character.distance_y_from(@preceding_character.preceding_character.y)
  298.         p_plan_x = @preceding_character.x # 移動予定座標X
  299.         p_plan_y = @preceding_character.y # 移動予定座標Y
  300.         if p_sx != 0 && p_sy != 0
  301.           p_plan_x += p_sx > 0 ? -1 : 1
  302.           p_plan_y += p_sy > 0 ? -1 : 1
  303.         elsif p_sx != 0
  304.           p_plan_x += p_sx > 0 ? -1 : 1
  305.         elsif p_sy != 0
  306.           p_plan_y += p_sy > 0 ? -1 : 1
  307.         end
  308.         # 同座標へ移動予定の場合は向き変更のみ行い終了
  309.         if plan_x == p_plan_x && plan_y == p_plan_y
  310.           if sx.abs > sy.abs
  311.             set_direction(sx > 0 ? 4 : 6)
  312.           else
  313.             set_direction(sy > 0 ? 8 : 2)
  314.           end
  315.           return
  316.         end
  317.       end
  318.       
  319.       # プリセット処理
  320.       if sx != 0 && sy != 0
  321.         move_diagonal(sx > 0 ? 4 : 6, sy > 0 ? 8 : 2)
  322.       elsif sx != 0
  323.         move_straight(sx > 0 ? 4 : 6)
  324.       elsif sy != 0
  325.         move_straight(sy > 0 ? 8 : 2)
  326.       end
  327.     end
  328.   end
  329. end

  330. #==============================================================================
  331. # ■ Game_Followers
  332. #------------------------------------------------------------------------------
  333. #  フォロワーの配列のラッパーです。このクラスは Game_Player クラスの内部で使
  334. # 用されます。
  335. #==============================================================================
  336. class Game_Followers
  337.   #--------------------------------------------------------------------------
  338.   # ● 可視状態隊員の最後尾の member_index を取得 [new]
  339.   #--------------------------------------------------------------------------
  340.   def visible_last_follower_index
  341.     v_folloers = visible_folloers
  342.     return v_folloers.size == 0 ? 0 : v_folloers[-1].member_index
  343.   end
  344. end

  345. 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