|
|
2015/8/24(Mon) 03:04:30|NO.71020
○:自分 ×:敵だとして、○が通った道を×が後ろからたどる、もしくは○を×が追いかける、鬼ごっこみたいなのはどうすればいいですか?
できれば敵の動く速さを変えられる仕様にしたいです!
|
|
2015/8/24(Mon) 12:04:50|NO.71026
質問内容が抽象的でよくわかりませんが、要は追いかける方の座標を、追いかけられる方の座標より遅れた位置にすればいいのでは?
|
|
2015/8/24(Mon) 13:26:56|NO.71027
「○が通った道を×が後ろからたどる」と「○を×が追いかける」は異なるアルゴリズムになると思います。
とりあえず、「○が通った道を×が後ろからたどる」というのはこんな感じでしょうか?
size=32
xlen=640/size:ylen=480/size
pheromonesum=10
dim pstack,2,pheromonesum
px=10:py=10:pdelay=6 ;自分の位置と速度
ex=10:ey=10:edelay=12 ;敵の位置と速度
font msgothic,size
dim pheromonemap,xlen,ylen
tmp=py*xlen+px
repeat pheromonesum
pstack.0.cnt=tmp,pheromonesum-cnt
loop
gosub *pheromonerecord
repeat
getkey leftkey,37
getkey upkey,38
getkey rightkey,39
getkey downkey,40
if pwait<=0{
vx=(rightkey-leftkey)
vy=(downkey-upkey)
if vx!=0|vy!=0{
px+vx
py+vy
pwait=pdelay
vx=0:vy=0
gosub *pheromonerecord
}
}else{
pwait--
}
if ewait<=0{
vx=0:vy=0
nowep=pheromonemap(ex,ey)
if pheromonemap(ex-1,ey)>0&nowep<pheromonemap(ex-1,ey):vx--
if pheromonemap(ex,ey-1)>0&nowep<pheromonemap(ex,ey-1):vy--
if pheromonemap(ex+1,ey)>0&nowep<pheromonemap(ex+1,ey):vx++
if pheromonemap(ex,ey+1)>0&nowep<pheromonemap(ex,ey+1):vy++
ex+vx:ey+vy
ewait=edelay
}else{
ewait--
}
gosub *draw
redraw:await 16:redraw 0
loop
*draw
pget 3200:boxf
color 180,180,180
repeat pheromonesum
x=pstack(0,cnt)\xlen:y=pstack(0,cnt)/xlen
pos x*size,y*size:mes""+(pheromonesum-cnt)
pheromonemap.x.y=pheromonesum-cnt
loop
color
pos px*size,py*size:mes"○"
pos ex*size,ey*size:mes"×"
return
*pheromonerecord
x=pstack(0,(pheromonesum-1))\xlen:y=pstack(0,(pheromonesum-1))/xlen
pheromonemap.x.y=0
repeat pheromonesum-1,1
pstack.0.(pheromonesum-cnt)=pstack.0.(pheromonesum-cnt-1)
x=pstack(0,(pheromonesum-cnt))\xlen:y=pstack(0,(pheromonesum-cnt))/xlen
pheromonemap.x.y=pstack.1.(pheromonesum-cnt)
loop
pstack.0.0=py*xlen+px
pheromonemap.px.py=pstack.1.0
return
| |
|
2015/8/24(Mon) 13:51:22|NO.71028
>雪月夜さん
画面領域からはみ出そうとすると、「配列の要素が無効です」となりエラー。
|
|
2015/8/24(Mon) 14:17:02|NO.71029
追いかけるだけでしたらこんな感じでどうでしょうか?
///変数初期化
sx=640 ;ウィンドウサイズ
sy=480 ;ウィンドウサイズ
size=10 ;円の半径
fps=0.0
fps=60.0 ;描画速度
tx=0.0
ty=0.0
tx=double(sx/2) ;敵のx初期位置
ty=double(sy/2) ;敵のx初期位置
speed=0.0
speed=2.0
///ウィンドウ生成
screen 0,sx,sy
///メイン
repeat
redraw 0
;画面リセット
color 30,30,30
boxf
;自分描画
mx=mousex
my=mousey
color 0,128,198
circle mx-size,my-size,mx+size,my+size,1
;敵描画
tx=tx+sin(atan(mx-tx,my-ty))*speed
ty=ty+cos(atan(mx-tx,my-ty))*speed
color 240,0,0
circle tx-size,ty-size,tx+size,ty+size,1
redraw 1
await 1000.0/fps
loop
|
|
2015/8/24(Mon) 14:17:41|NO.71030
>Snakeさん
失礼。
24〜25行目を
px=limit(px+vx,0,xlen-1)
py=limit(py+vy,0,ylen-1)
36〜39行目を
if ex-1>=0{
if pheromonemap(ex-1,ey)>0&nowep<pheromonemap(ex-1,ey):vx--
}
if ey-1>=0{
if pheromonemap(ex,ey-1)>0&nowep<pheromonemap(ex,ey-1):vy--
}
if ex+1<xlen{
if pheromonemap(ex+1,ey)>0&nowep<pheromonemap(ex+1,ey):vx++
}
if ey+1<ylen{
if pheromonemap(ex,ey+1)>0&nowep<pheromonemap(ex,ey+1):vy++
}
とするとエラーが解消されます。
|
|
2015/8/25(Tue) 02:00:13|NO.71046
質問が抽象的すぎてすみませんf(^_^;)
自機の跡を辿るやつをお願いします。hsp初心者なのでできれば解説もお願いします!
|
|
2015/8/26(Wed) 12:08:26|NO.71065
ご希望の機能を実装するには、
・自分の足跡(座標)を順次記録する
・敵は、少し遅れて足跡の記録を順次たどる
という手順が必要になります。
足跡を変数で管理するには、変数内容のシフトなどが必要になってちょっと手間ですが、
メモリノートパッドを使えば簡単に実現できます。以下サムプル。
; 画面、変数の初期化
sx = 640 : sy = 480
screen 0, sx, sy, 0, (ginfo(20)-sx)/2, (ginfo(21)-sy)/2
mouse ginfo(20)/2, ginfo(21)/2
okure = 50 ; どのくらい遅れて追いかけるか
asiato = "" ; 足跡の記録
notesel asiato
*main
wait 1
; マウスの現座標を追記
; メモリノートに順次記録するため、x,y座標を各4文字の固定長テキストに変換
mx = " "+str(mousex) : mx = strmid(mx,-1,4)
my = " "+str(mousey) : my = strmid(my,-1,4)
noteadd mx+my
; メモリノートの大きさが遅れ以上になったら、追いかけ処理開始
if noteinfo(0)>okure {
; 座標を取り出し、表示
noteget a, 0
tx = int(strmid(a,0,4)) : ty = int(strmid(a,4,4))
redraw 0
color 255,255,255 : boxf
color 0, 0, 0 : pos tx, ty : mes "敵"
redraw 1
; メモリノートの先頭を削除
notedel 0
}
goto *main
ただ、メモリノートパッドは1つのプログラム中に同時に1つしか指定できない。
ほんとは、メモリノートを使わずに普通の変数で管理できればいいですよね。
上記の「固定長テキストに変換」の考え方を応用すれば、普通の文字列変数で実装できます。
そこはぜひ、お考えください。(´ω`)
|
|
2015/8/26(Wed) 13:18:23|NO.71066
>足跡を変数で管理するには、変数内容のシフトなどが必要になってちょっと手間
リングバッファの概念を使えば必要有りません。
配列によるキュー(queue)の実装でよく使う手法です。
内容のシフトをしていたのではCPUを無駄に食うだけです。。
とりあえずエッセンスだけ。
*mkwnds
#define wsx 640
#define wsy 480
screen 0,wsx,wsy,0
*init
/* カーソルの軌跡データの初期化 */
#define delay 25 //遅れ
readStartIdx_mLocus = 0 // "readStartIndex_mLocus" mLocus↓ の読み出し開始インデックス。
writeIdx_mLocus = delay // "writeIndex_mLocus" mLocus↓ の書き込みインデックス。readStartIdx_mLocus の一つ前。
dim mLocus,delay+1,2 //マウスカーソルの軌跡データ。リングバッファの要領で記録。
//要素(i,0),(i,1)は然るべき位置記録のx,y座標。
//読み出しは startIndex_mLocus から delay 個分。
*main
#define frmIntrvl 16 //[ms] "frameInterval" フレーム間隔
mpos_prev = mousex,mousey // "mousePosition_previous" 以前のマウスカーソルの座標
repeat
if mousex!mpos_prev | mousey!mpos_prev(1) { //カーソルが動いたら
gosub *hndlMLocus_add //軌跡点追加
mpos_prev = mousex,mousey
redraw 0
color : boxf
gosub *drawChaser //追跡者描画
redraw 1
}
await frmIntrvl
loop
*hndlMLocus_add //軌跡点追加
mLocus(writeIdx_mLocus,0) = mousex : mLocus(writeIdx_mLocus,1) = mousey //書き込み
if writeIdx_mLocus = delay : writeIdx_mLocus = 0 : else : writeIdx_mLocus ++ //インクリメント
return
*drawChaser
chaserPos = mLocus(readStartIdx_mLocus,0),mLocus(readStartIdx_mLocus,1) //追跡者の座標
color 255,128,64
circle chaserPos-5,chaserPos(1)-5, chaserPos+5,chaserPos(1)+5, 1 //追跡者
if readStartIdx_mLocus = delay : readStartIdx_mLocus = 0 : else : readStartIdx_mLocus ++ //インクリメント
return
| |
|