Project1

标题: 太诡异了。。战棋的攻击问题(附上工程了) [打印本页]

作者: 无心孤云    时间: 2009-5-13 01:07
标题: 太诡异了。。战棋的攻击问题(附上工程了)
在使用叶子前辈的战棋系统的时候出现。。。敌人离我很远的时候,在轮到敌人的回合的时候会出现错误。。。如果移动出对方的攻击范围太远野会出现这个问题,但是在敌人的视野范围那我明明已经设置到最高了。。。。打不过怪的时候跑远点,可能是超出怪的索敌范围了吧,然后也会出现错误。。。
脚本scene_slg(敌人AI)的196行发生NoMethodError undefined method 'setup_event'for nil:nilclass

对应脚本时这句          $path_finding.setup_event(index)

全部脚本如下。。。。

请来个前辈指导下{/ll}错误出现在哪呢。。。
如果把敌人距离调到我方旁边则一切正常。。。。
以下是问题工程。。。。我弄成很小的个小东西了。。。
请高手前辈测试下看看问题出在哪吧。。。。
http://g.zhubajie.com/urllink.php?id=5101281a2pn41pxxprm30dm


  1. class Scene_SLG
  2.   #==========================================================================
  3.   # ■ 敌人AI计算
  4.   #==========================================================================
  5.   def start_phaseAI
  6.     # 转移到回合 0
  7.     @phase = 0
  8.     # 生成敌人行动
  9.     if @active_battler.is_a?(Game_Enemy)
  10.       @active_battler.make_action
  11.       if enemy_decide_target(@active_battler) == false
  12.         # 寻找目标失败的话,不行动
  13.         @active_battler.current_action.kind = 0
  14.         @active_battler.current_action.basic = 3
  15.       end
  16.     end
  17.   end
  18.   # ◎刷新
  19.   def update_phaseAI
  20.     # 事件移动
  21.     $game_map.events[@active_battler.event_id].move_type_custom
  22.     # 镜头跟随
  23.     if $game_map.events[@active_battler.event_id].moving?
  24.       max_x = ($game_map.width - 20) * 128
  25.       max_y = ($game_map.height - 15) * 128
  26.       $game_map.display_x = [0, [
  27.       $game_map.events[@active_battler.event_id].real_x - CENTER_X, max_x].min].max
  28.       $game_map.display_y = [0, [
  29.       $game_map.events[@active_battler.event_id].real_y - CENTER_Y, max_y].min].max
  30.       return
  31.     end
  32.     # 开始行动回合
  33.     start_phase5
  34.   end
  35.   #==========================================================================
  36.   # ■ 算法
  37.   #==========================================================================
  38.   #--------------------------------------------------------------------------
  39.   # ◎确定目标
  40.   #--------------------------------------------------------------------------
  41.   def enemy_decide_target(battler)
  42.     # 检测视野
  43.     check_view_range(battler)
  44.     # 无仇恨就放弃行动
  45.     if battler.hate_list.compact == []
  46.       return false
  47.     end
  48.     case battler.current_action.kind
  49.     # 基本
  50.     when 0
  51.       # 攻击
  52.       if battler.current_action.basic == 0
  53.         battler.current_action.kind = 1
  54.         skill = $data_skills[battler.skill_of_attack]
  55.         battler.current_action.skill_id = skill.id
  56.         make_range_and_aoe(skill)
  57.         decide_damage_target
  58.       end
  59.     # 特技
  60.     when 1
  61.       # 记录
  62.       skill = $data_skills[battler.current_action.skill_id]
  63.       make_range_and_aoe(skill)
  64.       decide_damage_target
  65.     # 物品
  66.     when 2
  67.       # 敌人无物品
  68.       return false
  69.     end
  70.   end
  71.   #--------------------------------------------------------------------------
  72.   # ◎检测视野,force为true的话强行添加仇恨列表
  73.   #--------------------------------------------------------------------------
  74.   def check_view_range(battler, force=false)
  75.     # 已存在仇恨列表的话,不检测
  76.     if battler.hate_list != [] and !force
  77.       return
  78.     end
  79.     # 取得初始位置
  80.     ori_grid = Grid.new $game_map.events[battler.event_id].x,    $game_map.events[battler.event_id].y
  81.     view_grids = get_target_range(ori_grid, battler.view_range)
  82.     for grid in view_grids
  83.       for actor in @actors
  84.         # actor为nil就跳过
  85.         next if actor == nil
  86.         # 角色在其视野内,不隐身或死亡,对其无仇恨的话
  87.         if $game_map.events[actor.event_id].x == grid.x and
  88.           $game_map.events[actor.event_id].y == grid.y and
  89.           !actor.hp0? and battler.hate_list[actor.event_id] == nil
  90.           # 添加到仇恨列表
  91.           battler.hate_list[actor.event_id] = 0
  92.         end
  93.       end
  94.     end
  95.   end
  96.   #--------------------------------------------------------------------------
  97.   # ◎仇恨列表排序(仇恨列表理论上支持同时对1000个单位有仇恨)
  98.   #--------------------------------------------------------------------------
  99.   def sort_hate_list(battler)
  100.     # 获得列表
  101.     list = battler.hate_list.dup
  102.     # 在个位、十位和百位标记位置
  103.     for number in 0...list.size
  104.       # 不为nil的话,标记
  105.       if list[number] != nil
  106.         list[number] = list[number] * 1000 + number
  107.       end
  108.     end
  109.     # 排序(由小到大)
  110.     list.compact!
  111.     list.sort!
  112.     list.reverse!
  113.     #返回列表
  114.     return list
  115.   end
  116.   #--------------------------------------------------------------------------
  117.   # ◎确认敌人目标
  118.   #--------------------------------------------------------------------------
  119.   def decide_damage_target
  120.     battler = @active_battler
  121.     # 取得初始位置
  122.     ori_grid = Grid.new $game_map.events[battler.event_id].x,    $game_map.events[battler.event_id].y
  123.     # 取得排好序的仇恨列表
  124.     # 第一张是一次行动就能攻击用,第二张是长距离移动用
  125.     list1 = sort_hate_list(battler)
  126.     list2 = list1.dup
  127.     # 计算移动范围
  128.     @move_range_grids = get_move_range(ori_grid, battler.move_range)
  129.     # 一次行动可及距离
  130.     @available_range = battler.current_action.range +
  131.     battler.current_action.aoe - 1 + battler.move_range
  132.     # 攻击可及距离
  133.     @attack_range = battler.current_action.range +
  134.     battler.current_action.aoe - 1
  135.     # 不用AOE可及距离
  136.     @no_aoe_range = battler.current_action.range
  137.     # AOE可及距离
  138.     @aoe_range = battler.current_action.aoe
  139.     # 循环
  140.     loop do
  141.       # 取得列表排首位的角色
  142.       actor_id = list1.shift
  143.       # 找不到角色就进行移动处理
  144.       if actor_id != nil
  145.         # 还原角色ID
  146.         actor_id %= 1000
  147.         # 不打死人
  148.         next if @battlers[actor_id].death
  149.         # 取得角色坐标
  150.         actor_x = $game_map.events[actor_id].x
  151.         actor_y = $game_map.events[actor_id].y
  152.         actor_grid = Grid.new(actor_x, actor_y)
  153.         # 获得双方距离
  154.         @battler_range = (actor_x - ori_grid.x).abs + (actor_y - ori_grid.y).abs
  155.         # 一次行动就可以攻击到的话
  156.         if @battler_range <= @available_range
  157.           # 不用移动就可以攻击到的话
  158.           if @battler_range <= @attack_range
  159.             # 调用获得行动目标格子
  160.             decide_target_grid(ori_grid, actor_grid)
  161.             return
  162.           end
  163.           # 需要移动才攻击到
  164.           # 匹配格子
  165.           for grid in @move_range_grids
  166.             if (actor_x - grid.x).abs + (
  167.               actor_y - grid.y).abs <= @attack_range and
  168.               @battler_coordinate[grid.x, grid.y] == 0
  169.               # 设置移动路线(采用短距离算法)
  170.               index = battler.event_id
  171.               setup_path(index, grid)
  172.               start_event(index)
  173.               # 确定目标
  174.               decide_target_grid(grid, actor_grid)
  175.               return
  176.             end
  177.           end
  178.         end
  179.       # 找不到一次行动就可以攻击到的目标的话,移动
  180.       else
  181.         # 初始化对比路径
  182.         available_paths = []
  183.         # 移动到最近的战斗者
  184.         for actor_id in list2
  185.           next if actor_id == nil
  186.           # 还原角色ID
  187.           actor_id %= 1000
  188.           # 取得角色坐标
  189.           actor_x = $game_map.events[actor_id].x
  190.           actor_y = $game_map.events[actor_id].y
  191.           actor_grid = Grid.new(actor_x, actor_y)
  192.           # 采用长距离移动算法
  193.           index = battler.event_id
  194.           $path_finding.setup_event(index)
  195.           if $path_finding.add_paths_event(index, actor_grid.x, actor_grid.y,
  196.             [$game_map.events[actor_id]]) != false
  197.             available_paths.push $game_map.events[index].path.list
  198.           end
  199.         end
  200.         # 寻路失败就返回false
  201.         return false if available_paths == []
  202.         # 按照移动路径远近排序
  203.         available_paths.sort! do |a, b|
  204.           a.size <=> b.size
  205.         end
  206.         # 清空路径
  207.         $game_map.events[index].path.list = []
  208.         # 代入最短的路径(限制步数)
  209.         for step in 0...battler.move_range
  210.           $game_map.events[index].path.list.push(available_paths[0][step])
  211.         end
  212.         # 防止战斗者重叠
  213.         loop do
  214.           # 路径上所有格子都被阻挡的话就放弃移动
  215.           break if $game_map.events[index].path.list == []
  216.           end_grid = get_path_end_grid(ori_grid, $game_map.events[index].path.list)
  217.           if @battler_coordinate[end_grid.x, end_grid.y] == 0
  218.             # 开始行动
  219.             $path_finding.start_event(index)
  220.             # 休息
  221.             battler.current_action.kind = 0
  222.             battler.current_action.basic = 3
  223.             return
  224.           end
  225.           # 删除最后一步,继续检查
  226.           $game_map.events[index].path.list.pop
  227.         end
  228.         # 休息
  229.         battler.current_action.kind = 0
  230.         battler.current_action.basic = 3
  231.         return
  232.       end
  233.     end
  234.   end
  235.   #--------------------------------------------------------------------------
  236.   # ◎获得行动目标格子
  237.   #--------------------------------------------------------------------------
  238.   def decide_target_grid(start_grid, target_grid)
  239.     # 在射程内(不用AOE)的话,直接以角色的格子为目标
  240.     if @battler_range <= @no_aoe_range
  241.       @active_battler.current_action.target_grid = target_grid
  242.       return
  243.     # 需要AOE范围的话
  244.     else
  245.       # 从目标开始铺AOE范围
  246.       aoe_grids = get_target_aoe(target_grid, @aoe_range)
  247.       # 从自己开始铺射程范围
  248.       range_grids = get_target_range(start_grid, @no_aoe_range)
  249.       # 匹配格子
  250.       for grid in range_grids
  251.         if grid.compare_grids(aoe_grids) == true
  252.           @active_battler.current_action.target_grid = grid
  253.           return
  254.         end
  255.       end
  256.     end
  257.   end
  258. end   
复制代码
[LINE]1,#dddddd[/LINE]版务信息:本贴由楼主自主结贴~
作者: 无心孤云    时间: 2009-5-13 01:53
奇怪。。。我想上传工程。。。。怎么上传不了呢。。。。 [LINE]1,#dddddd[/LINE]版主对此帖的评论:『连贴。未说完的话编辑原帖即可。』,积分『-30』。这些被扣积分的一半会用于对本帖正确答案的悬赏。
作者: 凌辰    时间: 2009-5-13 01:54
以下引用xcyog于2009-5-12 17:53:24的发言:
奇怪。。。我想上传工程。。。。怎么上传不了呢。。。。
目前论坛附件处于抽风状态,可以上传至其它网盘。
作者: 无心孤云    时间: 2009-5-13 02:05
版主老大好狠啊{/ll}我只是发表了下我对上传不了得疑惑。。。但是不是疑问啊{/ll}30分啊{/dk}
作者: 霜冻之狼    时间: 2009-5-13 02:11
以下引用xcyog于2009-5-12 18:05:11的发言:
版主老大好狠啊我只是发表了下我对上传不了得疑惑。。。但是不是疑问啊30分啊

楼主没看版规嘛?
如果有话要说编辑原帖就行,不可以重贴....

作者: 无心孤云    时间: 2009-5-13 02:17
上面这个问题之前也出现过几次了。。。后来弄了几个方法避免了。。。但是现在发现不解决实在不行了。。。。和怪打打打不过了。。。跑远点就出现错误退出。。。。郁闷啊。。。。
作者: 蓝の星辰    时间: 2009-5-13 02:19
提示: 作者被禁止或删除 内容自动屏蔽
作者: 无心孤云    时间: 2009-5-13 02:22
请问下蓝前辈
这句东西的作用是????
用到哪??
作者: 蓝の星辰    时间: 2009-5-13 02:25
提示: 作者被禁止或删除 内容自动屏蔽
作者: 无心孤云    时间: 2009-5-13 02:29
前辈。。。这办法似乎不行。。。。
作者: 叶子    时间: 2009-5-13 09:44
压缩包损坏,打开不能

1.可能你没有复制 Near Fantastica-寻路脚本 这个脚本
2.可能你复制了你那个脚本,但用了其他标题脚本。这样的话,要在游戏开始的时候加上 $path_finding = Path_Finding.new [LINE]1,#dddddd[/LINE]系统信息:本贴由楼主认可为正确答案,66RPG感谢您的热情解答~
作者: 无心孤云    时间: 2009-5-13 21:42
果然是少了个Near Fantastica-寻路脚本。。。。我复制脚本的时候复制到这个的时候拿个ctrl键有问题。。导致复制失败。。。。然后就这样了。。。。我说呢。。。。怎么会总是出错。。。。还好有叶子前辈在呀。。。谢谢叶子前辈指导。。。{/cy}




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1