VX 스크립트

스크립트

=begin

■移動ルート機能ぱわーあっぷ RGSS2 DAIpage■ v0.6


●機能と使い方●

 移動ルートの設定に

  ・最短距離移動(障害物も考慮)

  ・指定エリア内ランダム移動(マップ機能のエリアを使用)

 などを追加します。

 また、移動タイプが「ランダム」でトリガーが「決定ボタン」、プライオリティが

 「通常キャラと同じ」のイベントがプレイヤーに押されていると、

 押された方向に動きます。町中など、狭いところでプレイヤーの通行を邪魔している

 場合などに使えます。


 移動ルートの設定、または自律移動の「カスタム」内のスクリプトで指定します。


【指定位置に向けて最短移動ルートで一歩移動】

 ※ x, yに目標座標を指定。


  target_p_move_auto(x, y)

  

【指定エリア内ランダム移動】お前ここから出てくるなって時に。

 ※ idでエリアを指定。


  move_type_area_random(id)

  

【指定キャラクターに近づく】

 ※ idに目標キャラクターIDを指定。0でプレイヤー。


  target_c_move_auto(id)


  

【通行可能な限り前進、通行不可でランダムに方向転換】


  search_front


  

●再定義している箇所●

  Game_Character、Game_Playerをエイリアス。


 ※同じ箇所を変更するスクリプトと併用した場合は競合する可能性があります。


●参考●

このスクリプトの一部の機能は以下のサイト様のものを参考にVX用に再構築しております。


RPGツクールシステム研究室

http://suppy1632.hp.infoseek.co.jp/


=end

#============================================================================

# カスタマイズポイント

#============================================================================

module DAI_Move

  

  # 指定位置へ最短距離移動時の再計算間隔歩数。

  # 少ないほど精度は高いが重くなる。

  P = 2

  

  # ランダム移動イベントがプレイヤーから遠ざかる機能を使用。

  E = true

  

end


#==============================================================================

# ■ Game_Character

#==============================================================================

class Game_Character

  #--------------------------------------------------------------------------

  # ● 公開インスタンス変数

  #--------------------------------------------------------------------------

  attr_reader   :move_type

  attr_reader   :stop_count

  attr_reader   :move_frequency

  #--------------------------------------------------------------------------

  # ● 目的地までの最短経路を作成

  #--------------------------------------------------------------------------

  def search_route(target_x, target_y, type = 0)

    @route_count = 0

    @target_route = []

    return false if target_x == @x and target_y == @y

    @openlist = [@x * 1000 + @y, target_x * 1000 + target_y]

    @closelist = {@x * 1000 + @y=>0, target_x * 1000 + target_y=>1}

    @lootlist = [[],[]]

    @pointer = 0

    while @pointer < @openlist.length

      for i in 1..4

        a = way(i)

        b = @openlist[@pointer]

        c = @lootlist[@pointer]

        if @closelist.include?(a)

          if @closelist[a] != @closelist[b] 

            if @closelist[a] == 0

              half_route = c

              half_route.push 5 - i

              perfect_route = @lootlist[@openlist.index(a)] 

            else

              half_route = @lootlist[@openlist.index(a)]

              perfect_route = c

              perfect_route.push i

            end

            half_route.reverse!

            perfect_route += half_route

            @target_route = perfect_route

            return @target_route

          end

        else

          if type == 0

            newloot(a, b, c, i) if dir_passable?(b / 1000, b % 1000, i * 2)

          else

            newloot(a, b, c, i) if dir_e_passable?(b / 1000, b % 1000, i * 2)

          end

        end

      end

      @pointer += 1

    end

    return false

  end

  #--------------------------------------------------------------------------

  # ● 座標変換

  #--------------------------------------------------------------------------

  def way(i)

    case i

    when 1 ; a = @openlist[@pointer] + 1

    when 2 ; a = @openlist[@pointer] - 1000

    when 3 ; a = @openlist[@pointer] + 1000

    when 4 ; a = @openlist[@pointer] - 1

    end

    return a

  end

  #--------------------------------------------------------------------------

  # ● 経路追加

  #--------------------------------------------------------------------------

  def newloot(a, b, c, i)

    @openlist.push a

    @closelist[a] = @closelist[b]

    loot = c.dup

    if @closelist[a] == 0

      loot.push i

    else

      loot.push 5 - i

    end

    @lootlist.push loot

  end

  #--------------------------------------------------------------------------

  # ● 指定座標から指定方向への通行可能判定

  #--------------------------------------------------------------------------

  def dir_passable?(x, y, d)

    case d

    when 2 ; a = passable?(x, y + 1)

    when 4 ; a = passable?(x - 1, y)

    when 6 ; a = passable?(x + 1, y)

    when 8 ; a = passable?(x, y - 1)

    end

    return a

  end

  #--------------------------------------------------------------------------

  # ● キャラクターとの衝突を考えない指定方向への通行可能判定

  #--------------------------------------------------------------------------

  def dir_e_passable?(x, y, d)

    case d

    when 2 ; a = e_passable?(x, y + 1)

    when 4 ; a = e_passable?(x - 1, y)

    when 6 ; a = e_passable?(x + 1, y)

    when 8 ; a = e_passable?(x, y - 1)

    end

    return a

  end

  #--------------------------------------------------------------------------

  # ● キャラクターとの衝突を考えない通行可能判定

  #--------------------------------------------------------------------------

  def e_passable?(x, y)

    x = $game_map.round_x(x)

    y = $game_map.round_y(y)

    return false unless $game_map.valid?(x, y)

    return true if @through or debug_through?

    return false unless map_passable?(x, y)

    return true

  end

  #--------------------------------------------------------------------------

  # ● 最短移動ルートの配列に従い移動(イベントコマンド:スクリプト専用)

  #--------------------------------------------------------------------------

  def target_route_move(x, y)

    if search_route(x, y, 0) == false

      search_route(x, y, 1)

    else

      search_route(x, y)

    end

    move_route = RPG::MoveRoute.new

    for i in 0...@target_route.length

      move_route.list[i] = RPG::MoveCommand.new

      move_route.list[i].code = @target_route[i]

    end

    force_move_route(move_route)

    @target_route = []

    return

  end

  #--------------------------------------------------------------------------

  # ● 最短移動ルートの配列に従い一歩だけ移動(移動ルートの指定専用)

  #--------------------------------------------------------------------------

  def target_p_move_auto(x, y)

    if @route_count == DAI_Move::P or @target_route == nil

      if search_route(x, y, 0) == false

        search_route(x, y, 1)

      else

        search_route(x, y)

      end

    end

    case @target_route[@route_count]

    when 1 ; move_down

    when 2 ; move_left

    when 3 ; move_right

    when 4 ; move_up

    end

    @route_count += 1

    return

  end

  #--------------------------------------------------------------------------

  # ● 指定キャラクターに近づく(移動ルートの指定専用)

  #--------------------------------------------------------------------------

  def target_c_move_auto(id)

    if id == 0

      target = $game_player

    else

      target = $game_map.events[id]

    end

    return if target == nil

    target_p_move_auto(target.x, target.y)

  end

  #--------------------------------------------------------------------------

  # ● 通行可能な限り前進、通行不可でランダムに方向転換

  #--------------------------------------------------------------------------

  def search_front

    unless moving?

      if dir_passable?(@x, @y, @direction)

        move_forward

      else

        turn_random

      end

    end

  end

  #--------------------------------------------------------------------------

  # ● 移動タイプ : エリア内ランダム

  #--------------------------------------------------------------------------

  def move_type_area_random(id)

    case rand(6)

    when 0..1;  move_area_random(id)

    when 2..4;  move_forward if dir_passable_in_area?(@direction, id)

    when 5;     @stop_count = 0

    end

  end

  #--------------------------------------------------------------------------

  # ● エリア内をランダムに移動

  #--------------------------------------------------------------------------

  def move_area_random(id)

    a = in_area_passable?(id)

    return if a.empty?

    b = rand(a.size)

    case a[b]

    when 2 ; move_down(false)

    when 4 ; move_left(false)

    when 6 ; move_right(false)

    when 8 ; move_up(false)

    end

  end

  #--------------------------------------------------------------------------

  # ● エリア内の通行可能な方向を取得

  #--------------------------------------------------------------------------

  def in_area_passable?(id)

    a = []

    a.push 2 if dir_passable_in_area?(2, id)

    a.push 4 if dir_passable_in_area?(4, id)

    a.push 6 if dir_passable_in_area?(6, id)

    a.push 8 if dir_passable_in_area?(8, id)

    return a

  end

  #--------------------------------------------------------------------------

  # ● 指定方向がエリア内で通行可能か?

  #--------------------------------------------------------------------------

  def dir_passable_in_area?(d, id)

    case d

    when 2 

      return $game_map.in_area?(id, @x, @y + 1) && dir_passable?(@x, @y, 2)

    when 4 

      return $game_map.in_area?(id, @x - 1, @y) && dir_passable?(@x, @y, 4)

    when 6 

      return $game_map.in_area?(id, @x + 1, @y) && dir_passable?(@x, @y, 4)

    when 8 

      return $game_map.in_area?(id, @x, @y - 1) && dir_passable?(@x, @y, 8)

    end

  end

  #--------------------------------------------------------------------------

  # ● 移動タイプ : カスタム

  #--------------------------------------------------------------------------

  alias dai_custom_move_move_type_custom move_type_custom

  def move_type_custom

    return if @move_route.list[@move_route_index] == nil

    dai_custom_move_move_type_custom

  end

end

#==============================================================================

# ■ Game_Player

#==============================================================================

class Game_Player < Game_Character

  #--------------------------------------------------------------------------

  # ● 接触イベントの起動判定

  #--------------------------------------------------------------------------

  alias dai_custom_move_check_event_trigger_touch check_event_trigger_touch

  def check_event_trigger_touch(x, y)

    for event in $game_map.events_xy(x, y)

      if event.trigger == 0 && event.priority_type == 1 && DAI_Move::E &&

      event.move_type == 1 && event.stop_count > 30 * (4 - event.move_frequency)

        event.move_away_from_player

      end

    end

    dai_custom_move_check_event_trigger_touch(x, y)

  end

end

#==============================================================================

# ■ Game_Map

#==============================================================================

class Game_Map

  #--------------------------------------------------------------------------

  # ● エリア内判定

  #--------------------------------------------------------------------------

  def in_area?(id, x, y)

    area = $data_areas[id]

    return false if area == nil

    return false if $game_map.map_id != area.map_id

    return false if x < area.rect.x

    return false if y < area.rect.y

    return false if x >= area.rect.x + area.rect.width

    return false if y >= area.rect.y + area.rect.height

    return true

  end

end

여기까지




사용법:

K-3.pngK-2.png  동작반복 해주셔야 합니다

적용하시면 최단루트로 장애물을 피하며 오시는 인공지능을 맞보시게 될껍니다


명령어:target_c_move_auto(0)

Comment '5'
  • ?
    Abangarde 2014.02.25 20:04
    그동안 노가다로 해야했는데... 해보고나서 된다면 이건 혁명...
  • ?
    DP망치 2014.04.21 15:08
    line 79: SyntaxError occurred.
    라고 79번째 줄이 이상하다고 나오는데요..ㄷ
  • ?
    위키니트러 2014.06.20 22:53
    !!! 이건 혁명입니다. 저는 오류없이 잘 되네요. 테스트 결과 60x60 의 판에 복잡한 미로를 설치해도 잘 찾아 오네요. (중간에 위치가 바뀌어도 바뀐 위치를 기준으로 다시 쫓아오더군요.) 잘 쓸게요~
  • ?
    히리 2014.12.12 14:28
    우와 ㅠㅠ 감사합니다!!
  • ?
    JunseoGG 2019.05.04 23:07
    감사용

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
공지 스크립트 자료 게시물 작성시 주의사항 3 습작 2012.12.24 5398
317 기타 경험치 백분율 계산 2 허걱 2009.06.30 3093
316 기타 그림을 각도로 회전시키기 1 허걱 2009.06.30 2327
315 메시지 조합한글 21 file 허걱 2009.06.27 4409
314 전투 ATB전투방식.(사이드뷰X 백발의카임전투방식O) 14 file 이피쿤 2009.06.24 9035
313 전투 Requiem ABS 8 - 액션 배틀 시스템 8 36 아방스 2009.06.24 8540
312 메뉴 전투승리시 아이템 경험치팝업창 스크립트 18 file 카르와푸딩의아틀리에 2009.06.23 3760
311 온라인 VX Phoenix 온라인 스크립트 1.3버전 12 아방스 2009.06.18 3486
310 전투 카운트배틀 시스템(스크립트 한글살짝번역) 10 file 카르와푸딩의아틀리에 2009.06.17 5520
309 타이틀/게임오버 맵 타이틀 스크립트 48 아방스 2009.06.17 5547
308 메뉴 스테이터스 화면 개조 - 커스텀 버전 13 file 훈덕 2009.06.15 4932
307 기타 적 선택시 스킬창 비표시 + 타겟 플래쉬 7 훈덕 2009.06.14 2094
306 기타 좀 뭐랄까... 어이없는 "비행선 더 높게 날아오르게 하기!"스크립트.... 8 루시페르 2009.06.06 2426
305 기타 문장의 스크롤! 13 루시페르 2009.06.06 2524
304 기타 던전에 적정 레벨이 어떤건지 스크린에 표시해주는 스크립트! 5 file 루시페르 2009.06.06 2907
303 기타 (좀 이상한 or 쓸모없을 듯 한)화면상에 몬스터와 만나려면 몇걸음 남았는지 표시하는 스크립트! 2 루시페르 2009.06.06 2318
302 메뉴 시스템 옵션 스크립트의 사용방법 6 아방스 2009.06.04 2832
301 기타 KGC 스크립트 라이브러리 7 훈덕 2009.05.31 2611
300 기타 <중수이상>RPG VX의 대표적 참조값 6 까까까 2009.05.31 3236
299 전투 에너미를 아이템으로 변화하는 스킬 8 Evangelista 2009.05.27 2849
298 기타 능력치에 따른 스테이트변화 / 능력치한계지정 5 Evangelista 2009.05.26 2479
Board Pagination Prev 1 ... 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ... 32 Next
/ 32