まずは、画像認識が必要である。そして幸いなことに、アニマロッタの画像認識はかなり楽である。というのも、あるマスにバルーンがあるかどうかは、そのマスが赤っぽいかどうかで判別がつくからである。とはいえ、それを実践するのは一瞬ではない。
そこで、ちょっと練習を兼ねてみる。
下のような画像を作って、ちゃんと色の取得が行われているかをチェック。
関数によると、peekcolor(X,Y,オプション)という形でいいらしい。
これは=で結ぶと戻り値をそのまま変数に代入できる。
今回、赤色に近いかどうかの判定が必要なので、使うオプションはCOL_Rというものらしい。
また、出力されるのが16進数らしい。
16進数については、小学校のころからその存在と変換方法は改造コードの知識で知っているので問題ない。UWSCの語法では、前に$をつけるらしい。
while true
X=G_MOUSE_X
Y=G_MOUSE_Y
red=peekcolor(X,Y,COL_R)
test=$FF
MSGBOX(abs(red-test))
sleep(3.0)
wend
こんな感じで組んでみたところ、赤領域は18、オレンジ領域は0、青領域は192という値になった。いつの間にか16進数が10進数に変換されている。まあええか…。
なお画面外の白色は0とでた。
本来は赤色がもっとも0に近い値になるべきだが、こうなってしまうのは色の組み合わせによるものだろう。白はもっともかけ離れているが、RGBが全部MAX値だからだろう。
そういうわけで、このままでは純粋な紫色なども赤と判定されるので、一応青も取得して、青の割合が高く、赤が低いものが未HITとすることができる。
とりあえず実際にバルーンの画像判定ができるかを実践したい。
しかしそのためにはウィンドウを固定しなければいけないので、
ACWというコマンドで指定のウィンドウを動かせるらしいのでそれを行う。
ウィンドウの取得は確かGETIDでいけたはず。
実際に以下のコマンドでいけた。
id = GETID("コナステ クライアント ver.1.0.0")
Hnd = GETCTLHND(id, "CloudClientGameWindow")
ACW(id,0,0)
while true
sleep(3.0)
wend
実際にウィンドウを取得してACWというコマンドで左上にウィンドウを移動。
whiletrue以降は現時点では意味はない。
で、(442,88)という座標がウィンドウを固定したときの1マス目の中心の上のほうの座標。この位置を取得する理由は、中心だと番号がかぶって黄色っぽくなったり、そうかと思えば番号11などは中心がバルーンの赤色になったりなど判別しづらい。そして、座標が(31,31)分動けば別のマスに移動する、と考えてよいだろう。
すると、2マス目の判定の座標は1マス目から左下に移動するので(411,119)となる。
これら各25マスに対して色判定を行い、赤バルーンが存在するかどうかを特定する。
同じ作業を戻値(返り値)なしで行うため、functionというユーザー定義関数を使わないのかもしれないが、まあええか…。
返り値はresultというものをfunctionの関数の中で作るらしい。
functionが終了したことを明示するためにfendというものを最後に使用するらしい。
functionの後には引数を使用できるらしい。ここには各マスの座標を2つの引数とする。
あと、なんか関数の宣言は後ろのほうにしてもよいらしい…?がそうする理由はないので最初に定義することにする。
あと条件に関するのはたぶん慣例的にifなのでそれも初使用、ということで書式を確認しておく。不等号はそのまま使用可能らしい。ええやん
論理記号はどうすんねんと調べたら、ANDやORでいいらしい。
次に、25個のマスにバルーンがあるかどうかの判定を行いたいので、この25個の状況を一挙にまとめてくれるいわばベクトル的なものが欲しい。
これはdimのあとの[※]で、ここに配列数マイナス1を記入し、そのあと等号で結んで各要素を代入する感じらしい。
あと、集合の要素をどう扱うかは以下のテンプレで実践的に判別する。
//---シャッフル関数 |
Procedure shuffle( var list[]) |
Dim n = length(list) //配列の要素数 |
Dim i, r, tmp |
for i = 0 to n -1 |
r = random(n) |
tmp = list[r] //ランダムに選ばれたr番目の配列の値を取得 |
list[r] = list[i] //配列i番目の値をr番目に入れる |
list[i] = tmp //入替え完了 |
next |
Fend |
どうもシャッフルを行っているらしい。我も自作アニマロッタで番号配置をランダム化するとき、退避の変数を一つ用意して入れ替えを行っている。この操作は山ほどしてきたので、やりたいことがわかった。どうやらまず変数を持ってきてそのあとの[※]で位置を把握できるらしい。ただ、どうも0番目が最初になるらしいのでここ注意。
すると以下のような感じか…。よし名前をchkcorに使用
dim baloon[24]=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
X=442
Y=88
function chkcol(X,Y)
red=peekcolor(X,Y,COL_R)
blue=peekcolor(X,Y,COL_B)
if red>100 AND blue<100
then
baloon[0]=1
else
baloon[0]=0
fend
これで、R値が100より大きく(赤っぽく)、B値が100より小さい(青っぽくない)場合に、
そこには赤バルーンがあるとして25個のリストをもつbaloonという変数に1つ目の値として1を代入する、という操作になるはず。
あとはこれを25回繰り返す。これはおそらくforだろう。
とりあえず今の段階では各マスの判定に使う座標も手動で入力しておくか…。
するとこうか。
dim
X[24]=442,411,442,473,380,411,442,473,504,349,380,411,442,473,504,535,380,411,442,473,504,411,442,473,442
dim Y[24]=88,119,119,119,150,150,150,150,150,181,181,181,181,181,181,181,212,212,212,212,212,243,243,243,274
for a=1 to 25
dim baloon[24]=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
chkcol(X[a-1],Y[a-1])
next
MSGBOX(baloon)
これでどうや。この辺りのものをまとめてやっていくと…。
id = GETID("コナステ クライアント ver.1.0.0")
Hnd = GETCTLHND(id, "CloudClientGameWindow")
ACW(id,0,0)
dim X[24]=442,411,442,473,380,411,442,473,504,349,380,411,442,473,504,535,380,411,442,473,504,411,442,473,442
dim Y[24]=88,119,119,119,150,150,150,150,150,181,181,181,181,181,181,181,212,212,212,212,212,243,243,243,274
dim baloon[24]=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
function chkcol(X,Y)
red=peekcolor(X,Y,COL_R)
blue=peekcolor(X,Y,COL_B)
if red>100 AND blue<100
then
baloon[0]=1
else
baloon[0]=0
fend
for a=1 to 25
dim baloon[24]=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
chkcol(X[a-1],Y[a-1])
next
MSGBOX(baloon)
sleep(5.0)
while true
というプログラムでいざ実験。なお現在はシングルの1つのゲームのみ対応。
…
あっ文法エラーや
if red>100 AND blue<100
THEN
baloon[0]=1
ELSE
baloon[0]=0
fend
の部分がだめらしい。どうも1行で書かなければいけないらしい。
あとresultがないと言われた。これはprocedureか…。
他にはwendがないとでる。
どうも、procedureは最後におかなければいけないらしい…?
このようにいろいろやっているうちに、なんかいろいろ問題が発生したので結局は以下に落ち着いた。