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
557 키입력 마우스 시스템 Simple Mouse System (수정) 42 Incubus 2008.05.24 5693
556 HUD HUD HP / MP 게이지바 스크립트 29 file 아방스 2009.07.02 5677
555 타이틀/게임오버 타이틀 업그레이드 byMOG 16 *ps인간 2009.01.26 5658
554 전투 KGC]전투형태 오버드라이브(턴알) 13 찌나 2008.03.08 5656
553 ((대박!)) 게임상의 모든 글자에 효과 주기.. 33 미카엘 2008.08.20 5583
552 메시지 소설풍(노벨풍) 문자 스크립트 31 file 맛난호빵 2011.01.03 5551
551 타이틀/게임오버 맵 타이틀 스크립트 48 아방스 2009.06.17 5547
550 전투 카운트배틀 시스템(스크립트 한글살짝번역) 10 file 카르와푸딩의아틀리에 2009.06.17 5520
549 온라인 VX Phoenix 온라인 스크립트 Ver 1.5 36 아방스 2009.07.02 5510
548 퀘스트 [패치]오메가 퀘스트 시스템 확장판 v.1.1 72 file 레오 2010.09.25 5474
547 전투 RPG Tankentai SBS 3.3 Kaduki Eng 2 아방스 2009.02.05 5467
546 파티 최대 파티 늘리는 스크립트 59 file 아방스 2008.03.09 5431
545 스킬 스킬 사용시 컷인 연출 (번역) 26 file 훈덕 2009.02.05 5387
544 장비 [스크립트]무기에 옵션을 부가하자 18 아방이 2008.01.29 5380
543 메시지 여러항목 선택지 ... Scene처리.. 23 file 허걱 2009.02.14 5277
542 HUD 맵이름 띄우는 스크립트 입니다. 33 시에란 2008.08.16 5271
541 Side View CBS 사이드뷰배틀 블리치버젼 13 RPGbooster 2008.10.11 5232
540 상점 보관함 스크립트 43 file 허걱 2009.02.02 5161
539 VX 주석액알 PR코더즈의ABS보다 않좋다고생각할수있지만 더좋음 34 배군 2008.08.17 5145
538 Tankentai SBS 2.8 업데이트 [사이드뷰 배틀시스템 ] 42 file RPGbooster 2008.10.08 5140
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 32 Next
/ 32