コース上の色検出
irons 2013/4/28(Sun) 13:04:13|NO.53670
二日連続で失礼します
先の質問で頂いた解答を元に製作を続けていましたが
■を黒線に追跡させる点で再びぶつかりました
進行方向にある黒線(0,0,0)を検出するために■の左上から1dotずつ取得するのですが
// テキトーなサンプル開始(初期化)
ax = 1
ay = 1
x = 40
y = 150
// テキトーなサンプル終了(初期化)
screen 0,500,400
title "こっちがスクリーン"// 判別用タイトルをつける。bufferにするときは消す
buffer 1, ginfo(12), ginfo(13)// 同じ大きさのバッファを作成。今は、動作の様子を示すためscreenを使用。
//title "こっちがバッファー"// 判別用タイトルをつける。bufferにするときは消す
;赤色=ゲームオーバー
;青色=ゴール
color 255,0,0
boxf
course_x=0
course_y=100
;コース生成
repeat 10
color 255,255,255
boxf course_x,course_y,course_x+100,course_y+100
course_x+100
loop
color 0,0,0
gsel 0, 1// スクリーンを操作先にする。screen 1をbufferにするときはgsel 0だけにする。
gcopy 1, 0, 0, ginfo(12), ginfo(13)// 一応コースもコピー
;メインループ
repeat
;線引き
getkey keys,1
_mousex = mousex// バッファーだとmousexが使えないと思うので、変数に退避
_mousey = mousey// バッファーだとmouseyが使えないと思うので、変数に退避
if keys=1:{
gsel 1// 操作先をバッファにして
line mx,my,_mousex,_mousey// 線を描く
gsel 0// 操作先をスクリーンに
mx=_mousex
my=_mousey
}else{
mx=_mousex
my=_mousey
}
;追跡
;redraw 0
pos 0, 0
gcopy 1, 0, 0, ginfo(12), ginfo(13)
// テキトーなサンプル開始(描画)
xa=x-5
ya=y-5
repeat
pget xa+xc,ya+yc
if ginfo_r=0 & ginfo_g=0 & ginfo_b=0:{
x=xa+xc
y=ya+yc
xc=0:yc=0:break
}
;color 0,255,0
;pset xa+xc,ya+yc
if xc>=10:{xc=0:yc+1}
if yc>=10:{xc=0:yc=0:break}
xc+1
loop
x+1
color 0,0,0
boxf x - 5, y - 5, x + 5, y + 5
// テキトーなサンプル終了(描画)
;redraw 1
wait 1
loop
引用させていただき、以上のようなスクリプトを作ってみたもののいくつか問題が発生しました。
解決したいのは
・同じX座標のドットが2つ以上続くと同じ個所のドットを検出し続けてしまい止まってしまう
・同様に現在のY座標より下に行くと同様に止まってしまう
・検出後にその座標へ直接移動させてしまうために当初よりスピードが速くなってしまう
の三点です。
上に点に関しては左上からでなく逆方向から取得するというのも考えましたがまた同じ問題が起こりますし
同一座標の場合の例外を設定しても身動きが取れなくなる結果になってしまいました。
なにか良い方法がありますでしょうか?
暇人 2013/4/30(Tue) 18:59:03|NO.53723
一応止まらずに動くようにしてみたが想定してるルールが
はっきり分からないので使えるかは分からない
// テキトーなサンプル開始(初期化)
x = 40
y = 150
//黒ドット検出順(中心と隣接するドット)//左上が優先度高くなり黒ドットと接触したら右回り優先
//0 1 2
//7 3
//6 5 4
Direction=3 //進行方向を右に設定
gcx=-1,0,1,1,1,0,-1,-1
gcy=-1,-1,-1,0,1,1,1,0
//黒ドット検出順(更に1ドット外側のドット)
//0 1 2 3 4
//F 5
//E 6
//D 7
//C B A 9 8
Direction2=6
gcx2=-2,-1,0,1,2,2,2,2,2,1,0,-1,-2,-2,-2,-2
gcy2=-2,-2,-2,-2,-2,-1,0,1,2,2,2,2,2,1,0,-1
// テキトーなサンプル終了(初期化)
screen 0,500,400
title "こっちがスクリーン"// 判別用タイトルをつける。bufferにするときは消す
buffer 1, ginfo(12), ginfo(13)// 同じ大きさのバッファを作成。今は、動作の様子を示すためscreenを使用。
//title "こっちがバッファー"// 判別用タイトルをつける。bufferにするときは消す
;赤色=ゲームオーバー
;青色=ゴール
color 255,0,0
boxf
course_x=0
course_y=100
;コース生成
repeat 10
color 255,255,255
boxf course_x,course_y,course_x+100,course_y+100
course_x+100
loop
color 0,0,0
gsel 0, 1// スクリーンを操作先にする。screen 1をbufferにするときはgsel 0だけにする。
gcopy 1, 0, 0, ginfo(12), ginfo(13)// 一応コースもコピー
;メインループ
repeat
;線引き
getkey keys,1
_mousex = mousex// バッファーだとmousexが使えないと思うので、変数に退避
_mousey = mousey// バッファーだとmouseyが使えないと思うので、変数に退避
if keys=1:{
gsel 1// 操作先をバッファにして
color
line mx,my,_mousex,_mousey// 線を描く
gsel 0// 操作先をスクリーンに
mx=_mousex
my=_mousey
}else{
mx=_mousex
my=_mousey
}
;追跡
redraw 0
pos 0, 0
gcopy 1, 0, 0, ginfo(12), ginfo(13)
// テキトーなサンプル開始(描画)
dot=0
//中心と隣接するドット検査
repeat 8,Direction
Direction_cnt=cnt\8
pget x+gcx(Direction_cnt),y+gcy(Direction_cnt)
if (ginfo_r | ginfo_g | ginfo_b)=0 {
dot=1
Direction=Direction_cnt//黒があった方向をセット
break
}
loop
if dot=0 {//中心と隣接するドットに黒が無かった
//更に1ドット外側のドット
repeat $f,Direction*2
Direction_cnt=cnt\$f
pget x+gcx2(Direction_cnt),y+gcy2(Direction_cnt)
if (ginfo_r | ginfo_g | ginfo_b)=0 {
dot=1
Direction=Direction_cnt/2//黒があった方向を8方向に変換してセット
break
}
loop
}
x+gcx(Direction)
y+gcy(Direction)
if dot {//一度通ったところの色を変える
gsel 1
color 0,255,255
pset x,y
gsel 0
}
color 0,0,0
boxf x - 5, y - 5, x + 5, y + 5
// テキトーなサンプル終了(描画)
await 16
redraw 1
loop
中心から近いドットを優先させる
左上から右周りに検査するので先に検査する方向が優先される
ラインの途中だった場合右回り優先になる
面倒だったので最大で5*5(中心を除く)のドットを検査
一度通った黒ドットの色を変える(黒ラインを残したい場合は他の方を考える必要がある)