FC2ブログ
TOP > 一から始めるAI講座~第10回:~改造を始めよう~
 ← 続・わっかの受難 | TOP | Gv戦果:3/26

リストマーク 一から始めるAI講座~第10回:~改造を始めよう~ 

【重要】新しいBlogに移転していますあるネットゲーマーの日常
このAI講座も10回目にして、ついに具体的な改造に入ります

とはいえ、一から書くのは大変ですから、
デフォルトのAIを流用しつつ、
目的を達成するように書き直していくのが基本となります
恐れずにチャレンジしてみてください

  ~2章~ 攻撃パターンを改造する

 2-1:そんな遠くまで行かないで・・・

皆さんは普段、先攻・非先攻のどちらを使っているでしょうか?
弱い敵を大量に倒したい時は先攻が便利だと思いますが、
使っていると、いろいろ問題が出てきますよね・・・

 ・はるか遠くの敵を追いかけてしまう
 ・攻撃されているのに、他の敵を攻撃する(敵を増やしてしまう)

もう一度、GetMyEnemyB関数を思い出しましょう
あの関数は、画面内全てのモンスターを認識するために、
画面の端にいる敵まで追いかけてしまうわけです

かといって、GetMyEnemyA関数は、
自分を攻撃する敵だけ攻撃するものの、
ノンアクティブへの攻撃は指示が必要で面倒です

そこで、GetMyEnemy関数をこんな風に書き換えてみました


function  GetMyEnemy (myid)
  local result = 0
  local owner = GetV (V_OWNER,myid)
  local actors = GetActors ()
  local enemys = {}
  local index = 1
  local target
  local get_flg = 0 -- 敵発見フラグ

-- 自分を攻撃する敵を探す
  for i,v in ipairs(actors) do
    if (v ~= owner and v ~= myid) then
      target = GetV (V_TARGET,v)
      if (target == myid) then
        enemys[index] = v
        index = index+1
        get_flg = 1 -- 敵発見
      end
    end
  end

-- 他の敵を探す
  if (get_flg == 0) then -- 自分を攻撃する敵がいない?
    local max_dis = 10 -- 索敵範囲
    local target_dis
    for i,v in ipairs(actors) do -- 敵を探す
      if (v ~= owner and v ~= myid) then
        target_dis = GetDistance2 (myid,v) -- 距離計算
        if (target_dis < max_dis) then -- 近いところにいる?
          if (1 == IsMonster(v))  then
            enemys[index] = v
            index = index+1
            get_flg = 1
          end
        end
      end
    end
  end

-- 一番近い敵を探す
  if (get_flg == 1) then -- 敵がいる
    local min_dis = 100
    local dis
    for i,v in ipairs(enemys) do
      dis = GetDistance2 (myid,v)
      if (dis < min_dis) then
        result = v
        min_dis = dis
      end
    end
  end

  return result
end

※タブを変換してますので、このままコピーできません
 全角2つをタブに置換して貼り付けてください


基本的にはA+Bといった感じですが、
順番に見ていきましょう

まず、前者の問題ですが、GetMyEnemyAで敵が見つかったらそちら、
見つからなかったらGetMyEnemyBを実行する、
という感じにしたいわけです

そこで、「get_flg」という変数を導入し、
最初のブロック=自分を攻撃する敵が見つかったらフラグを立て、
次の索敵を行わないようにしています

続いて第2ブロックですが、
ここは最初のif文により、第1ブロックで敵が見つからなかった場合、
つまり自分が攻撃されてない時だけ実行されます

ポイントは「max_dis」という定数を導入したことです

GetMyEnemyB同様、全てのIDを検査するのですが、
ここでホムと対象との距離を計算し、
max_disより小さい時だけ、モンスターであるかの判定を行っています

つまり、max_disを大きくすれば索敵範囲が広がり、
小さくするとごく近くの敵しか狙わないようになるわけです
これにより、第2の問題が解決します

最後のブロックはほとんどいじってませんが、
効率化のため、敵がいるときだけループに入るように修正しました


いかがでしょうか?
基本はGetMyEnemyA/Bなのに、ほんの数行加えるだけで、
非常にホムの動きが良くなります

次回もホムの攻撃部分に修正を加えていく予定ですが、
「こんな動きをさせたい!」という要望がありましたら、
コメントをお寄せください
[2006.03.28(Tue) 05:31] ホムンクルスAI考察Trackback(0) | Comments(3)
↑TOPへ


COMMENT

A+Bについて by えび
この機能を導入したところ
受身型になってしまい、
ホムが攻撃しなくなりました。
主人が攻撃されているとき、自分が攻撃されているときは攻撃してくれるのですがね。

もしかして、AとBを全部消してこれだけにするのがまずかったのですか?

A+Bについて by えび
0のところに1が入っていたようで直りました。
しかし、索敵時ゴキのようにルートモンスターだった場合、
敵移動とともに索敵をする場面があるため、結局画面外にでることがありました。ただたんに私の運が悪いんでしょうね・・・
最初から、いろいろと解説をありがとうございます。とても分かりやすく参考になります。

by パロット
コメントありがとうございます^^

> 受身型
この講座を最後まで見ていくと、
「コマンド」で切り替え可能にできます
参考にしてみてください

> 際限なく追いかける
それがこの次の回の修正対象になりますね

コメントを閉じる▲

 ← 続・わっかの受難 | TOP | Gv戦果:3/26

COMMENT

この機能を導入したところ
受身型になってしまい、
ホムが攻撃しなくなりました。
主人が攻撃されているとき、自分が攻撃されているときは攻撃してくれるのですがね。

もしかして、AとBを全部消してこれだけにするのがまずかったのですか?
[ 2007.04.11(Wed) 03:12] えび #tg9VduSM | EDIT |

0のところに1が入っていたようで直りました。
しかし、索敵時ゴキのようにルートモンスターだった場合、
敵移動とともに索敵をする場面があるため、結局画面外にでることがありました。ただたんに私の運が悪いんでしょうね・・・
最初から、いろいろと解説をありがとうございます。とても分かりやすく参考になります。
[ 2007.04.11(Wed) 03:17] えび #lAVqpxXQ | EDIT |

コメントありがとうございます^^

> 受身型
この講座を最後まで見ていくと、
「コマンド」で切り替え可能にできます
参考にしてみてください

> 際限なく追いかける
それがこの次の回の修正対象になりますね
[ 2007.04.11(Wed) 12:41] パロット #kJeoJ8/Y | EDIT |

COMMENT POST











管理者にだけ表示

Trackback

この記事のURL:
http://parrot.blog21.fc2.com/tb.php/248-9bd8336d
 ← 続・わっかの受難 | TOP | Gv戦果:3/26

プロフィール

Categories

Recent Entries

Recent Comments

Archives

AdSense

Calander

ブログ内検索

RO Search

Links

Copylights

Amazon