ぺんちゃん日記

食と歴史と IT と。 Web の旅人ぺんじろうが好奇心赴くままに彷徨います 。

ゲーム画面の特徴的な画像でゲームの状態を判定する【AutoHotkey】。

f:id:yasushiito:20190403184928p:plain

これまでのあらすじ。

ゲームのプレイをアシストしてくれるツールを使いやすくするために、ゲーム画面の特徴的な色を吸い取って、 ゲーム画面にステータスが表示されているかどうかを判定することにチャレンジしてみました。
Auto HOT key には特定の座標のカラーコードを取得する関数があるので、ステータスエリアだけ表示されるボタンの色が指定の座標に見つかればステータス表示中と判定できます。
ところが、そのボタンは単色塗りつぶしではなく微妙なグラデーションがかかっていて、曖昧な座標指定では判定できないことが判明しました。
カラーコードに多少の幅を持たせたところで、色を取得する座標がピンポイントでは動作チェックがしづらくて仕方ありません。
AutoHotkeyにはピクセルのカラーコードを吸い取るだけでなく、画像を見比べて似ているか似ていないかを判定する機能もあります。
そちらは判定エリアと色合いに幅を持たせることができるので、柔軟な関係ができると思います。

ImageSearch関数を使ってみる。

まずは比較対象となる画像を用意しなければなりません。
今回はボタンの青い部分をペイントなどで小さく切り取って BMP ファイルで保存します。
png などでも判定できますが、圧縮の最後に色合いが少々変わることもあるので、 BMP の方が正確です。

f:id:yasushiito:20190617142447j:plain

この画像ファイルをスクリプトと同じディレクトリに用意します。

ImageSearch, , , 9,0,1955,1110,*20 blue.bmp

第3パラメータから第6パラメータで画像探したいエリアの左上と右下の座標を指定します。
第5パラメータが比較対象となる画像のファイル名です。
ファイル名はディレクトリを指定しなければ、スクリプトと同じディレクトリを探します。
ファイル名の前にスペースで区切ってオプションを与えることができます。
アスタリスクの直後に数値を記入すれば、色合いに幅を持たせることができます。
数値は0から255を取ることができます。
数値が大きいほど曖昧に判定できます。
もちろん大きすぎるとガバガバでチェックをすり抜けます。
最初は大きめで設定して徐々に小さくするのが良いと思います。
監視対象とする範囲の座標も、初めは広めにとって狭くしていくと良いでしょう。
あまりに広い範囲を対象としてしまうと処理速度が余計にかかってしまいます。
ところでこの座標ですが、CoordModeの指定によってアクティブウインドウからの相対距離またはスクリーン上での絶対座標のどちらかを変更することができます。
通常はアクティブウィンドウからの相対距離です。
今回はゲームの画面を絶対座標で捉えているのでスクリーン上での座標としたかったのですが、指定するのをうっかり忘れて2時間ほど悩みました。
画像の探索結果は errorlevel で返します。
0の時には見つかった。
1の時には見つからなかった。
2の時には何らかの問題が発生した。
のいずれかです。
画像が見つかった場合は第1パラメータと第2パラメータで発見した座標を受け取ることができます。
まずはサンプルの青いべた塗りの画像をスクリーンのほぼ全体から探してメッセージボックス結果を表示します。

画像のとこから撤退ボタンを表示させておけば見つけてくれるはずです。

f:id:yasushiito:20190616100009p:plain

画像探索をゲームに組み込む。

簡単なサンプルで確認できたところでゲームに組み込みます。
マウスポインターを一定時間滞在させた時に一度だけ左ボタンをクリックしていますが、それを一定時間ごとに左クリックするように変更します。
滞在時間を6で割った余りを求めることで6回ごとに条件を成立させることができます。
ただし、ゲーム画面の左下の方に撤退ボタンを確認できた時はクリックしません。
この条件によって、ステータスを表示するまでクリック連打できます。
これで完成したように思われますが、このままだと一度ステータスを表示してしまうと二度とステータス表示をキャンセル出来なくなってしまいます。
ステータスが表示されている間はユニットを出撃させられません。
これでは困るので、マウスポインター滞在の一発目は必ずクリックするようにします。
フィールドの何もないところをクリックさせることでステータスをキャンセルできますね。
出来上がったスクリプトはこんな感じ。


動かしてみて。

スキルの発動はスムーズになりました。
副作用としてスピードアップのボタンをクリック連打してしまいます。
画像チェックの処理を頻繁に呼び出すとディスクにアクセスしっぱなしなりそうなのが心配なところです。
キャッシュが効いてくれれば良いのですが、どうなんでしょうね。

この記事に登場するAutohotkey スクリプトについて

この記事の中で私が作成したプログラムは、全て自由に使うことができます。
詳しくはこちら