HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2013
1028
HSP初心者マップチップの当たり判定について8解決


HSP初心者

リンク

2013/10/28(Mon) 19:50:57|NO.57855

前に、マップチップのことを質問させていただきました。
そのときにはCSVファイルについて教えていただいたり、
おかしくなった原因まで教えてくださりました。感謝しています。

今回、マップチップを作ってみたのですが、当たり判定で行き詰ってしまいました。
まず現在キャラクターがどの位置にいるかを

キャラの座標÷チップ一枚の大きさ=キャラのチップ位置を表す変数
の式で求めました。
そして
キャラのチップ位置をあらわす変数の
右、左、下、上を調べ数値によって判定します。(数値とはマップチップの番号です)
ですがこの計算式(右、左、上、下を調べてどの数値かを確認する)
がどのようになるかがわかりません。
ぜひ教えてください。
よろしくお願いします。



この記事に返信する


Ve

リンク

2013/10/28(Mon) 19:54:04|NO.57856

ジャンルはアクションでしたっけ?(記憶違いだったらごめんなさい)

見下ろし形か、落下やジャンプありの横スクロールかで判定方法が少し変わります。



HSP初心者

リンク

2013/10/28(Mon) 19:59:08|NO.57857

Ve様
回答ありがとうございます!
ジャンルはアクションゲームです!
書き忘れていました。すみません。
内容はスクロールしない、ジャンプアクションゲームです。
考えているのは、
チップを配置するだけで当たり判定がつくものです。



HSP初心者

リンク

2013/10/28(Mon) 20:01:08|NO.57858

追伸:見下ろし形ではなく、横から見たような感じのものです。



Ve

リンク

2013/10/28(Mon) 21:11:31|NO.57859

横でしたら、落下を中心に当たり判定を作ったほうが良いです。


当たり判定計算は主に点で求める物、
円で求める物、矩形で求める物とあって、
初心者でも分かりやすいのは「左上の座標」と「幅と高さ」求める矩形の計算式ですかね。


randomize #define MAX 16 dim bx,MAX ;ボックスX座標 dim by,MAX ;ボックスY座標 dim bw,MAX ;ボックス幅 dim bh,MAX ;ボックス高さ dim bhit,MAX ;ボックスヒットチェック ;初期値 repeat MAX bx(cnt)=rnd(600) by(cnt)=rnd(300) bw(cnt)=10+rnd(100) bh(cnt)=10+rnd(100) loop ;プレイヤー用IDみたいなもの i=MAX-1 *メイン ;操作 stick key,15,1 ;1 : カーソルキー左(←) ;2 : カーソルキー上(↑) ;4 : カーソルキー右(→) ;8 : カーソルキー下(↓) if key!=0{ if key&1:bx(i)-=1 if key&2:by(i)-=1 if key&4:bx(i)+=1 if key&8:by(i)+=1 } ;当たり判定 repeat MAX ;ヒットチェック初期化 bhit(cnt)=0 ;プレイヤーは除外 if (cnt!=i)and(bx(i)<bx(cnt)+bw(cnt))and(bx(i)+bw(i)>bx(cnt))and(by(i)<by(cnt)+bh(cnt))and(by(i)+bh(i)>by(cnt)) { ;接触していたら実行 bhit(cnt)=1 } loop ;描画 redraw 0 color 255,255,255 boxf repeat MAX ;当たっていた時の描画 if bhit(cnt)=1{ ;画像がないのでボックスで color 255 boxf bx(cnt),by(cnt),bx(cnt)+bw(cnt),by(cnt)+bh(cnt) }else{ ;画像がないのでボックスで if cnt=i{ ;プレイヤーだけ色換 color ,,255 }else{ color } boxf bx(cnt),by(cnt),bx(cnt)+bw(cnt),by(cnt)+bh(cnt) } loop redraw 1 await 1 goto *メイン



Ve

リンク

2013/10/28(Mon) 21:18:18|NO.57860

当たり判定はこう記述しています。
(cnt!=i)は自キャラ以外の当たり判定を探っています

if (cnt!=i)and(bx(i)<bx(cnt)+bw(cnt))and(bx(i)+bw(i)>bx(cnt))and(by(i)<by(cnt)+bh(cnt))and(by(i)+bh(i)>by(cnt)) {

砕いて解説するとこうなります。

bx(i) < bx(cnt) + bw(cnt)
自分のX座標 < 相手のX座標+相手の幅
bx(i)+bw(i)>bx(cnt)
自分のX座標+自分の幅 > 相手のX座標
by(i)<by(cnt)+bh(cnt)
自分のY座標 < 相手のY座標+相手の幅
by(i)+bh(i)>by(cnt)
自分のY座標+自分の高さ > 相手のY座標

要するに自キャラの矩形の四隅が相手の矩形に入ってるかどうかを見ています。



暇人

リンク

2013/10/29(Tue) 00:17:12|NO.57864

>ですがこの計算式(右、左、上、下を調べてどの数値かを確認する)
キャラの大きさを足してから
>キャラの座標÷チップ一枚の大きさ=キャラのチップ位置を表す変数
この計算をすれば良い

「どの数値かを確認する」って言うのはマップを表示する時に使ったマップデータを参照する事


#define CHIPSIZE 64 #define MAPMAXX 10 #define MAPMAXY 8 mysizex=CHIPSIZE //自分のサイズ mysizey=CHIPSIZE mycsx=mysizex-1 //自分の左上を基点にして右下端の判定をする時キャラサイズをそのまま使うと隣のブロックを最小してしまうので-1(キャラがウィンドウ座標0にいてキャラ右端を64としたら64で割ると1になってしまう) mycsy=mysizey-1 myspx=4 //自分の速度 myspy=4 //4が障害物、100以上が自分 map_txt={" 1,4,4, 1,1,1,1,1,1,1 1,4,1, 1,1,1,1,4,1,1 2,4,2, 2,2,2,4,2,2,2 2,2,2, 2,4,2,4,2,4,4 2,2,2, 2,4,2,4,2,2,4 3,3,3,103,3,3,3,3,3,4 4,3,3, 4,4,4,3,3,3,4 4,4,3, 3,3,3,3,4,4,4"} dim map,MAPMAXX,MAPMAXY buffer 1 //テキストデータをそのまま判定にも使うと面倒(個人的にだが)なので配列に入れなおす。ついでにbufferに背景を作成 split map_txt,"\n",map_y_txt repeat MAPMAXY split map_y_txt(cnt),",",map_x_txt mapy=cnt repeat MAPMAXX map(cnt,mapy)=int(map_x_txt(cnt)) if map(cnt,mapy)=4 {//障害物 gradf cnt*CHIPSIZE,mapy*CHIPSIZE,CHIPSIZE,CHIPSIZE,((cnt+mapy)\2),$444444,$888888 }else{//障害物以外 if map(cnt,mapy)>=100 {//自分 mypx=cnt*CHIPSIZE:mypy=mapy*CHIPSIZE map(cnt,mapy)=map(cnt,mapy)\100 //座標をセットしたらクリア(100未満を背景マップチップとして指定できる) } gradf cnt*CHIPSIZE,mapy*CHIPSIZE,CHIPSIZE-1,CHIPSIZE-1,1,$880077-$220000*map(cnt,mapy),$880055-$220000*map(cnt,mapy) } loop loop gsel 0 repeat redraw 0 pos 0,0 celput 1,0 stick stk,$F //移動量を求めるための準備(判定後の処理に必要になってくる) mypx_old=mypx mypy_old=mypy if stk&1 {mypx-myspx} if stk&4 {mypx+myspx} if stk&2 {mypy-myspy} if stk&8 {mypy+myspy} //マップデータ外に出さない処理 mypx=limit(mypx,0,CHIPSIZE*MAPMAXX-CHIPSIZE) mypy=limit(mypy,0,CHIPSIZE*MAPMAXY-CHIPSIZE) //自分の左上のグリッド座標(マップ左上が0,0で右下最大がMAPMAXX-1,MAPMAXY-1 、0からなので使用チップ数-1になる) myg_lx=mypx/CHIPSIZE myg_uy=mypy/CHIPSIZE //自分の右下のグリッド座標(myg_lx,myg_dyで左下、myg_rx,myg_uyが右上になる) myg_rx=(mypx+mycsx)/CHIPSIZE myg_dy=(mypy+mycsy)/CHIPSIZE color 255,255,255 pos 0,0 if map(myg_lx,myg_uy)=4 {mes strf("X=%d,Y=%d",myg_lx,myg_uy):gradf myg_lx*CHIPSIZE,myg_uy*CHIPSIZE,CHIPSIZE,CHIPSIZE,1,$aa4444,$aa8888}//左上 if map(myg_rx,myg_uy)=4 {mes strf("X=%d,Y=%d",myg_rx,myg_uy):gradf myg_rx*CHIPSIZE,myg_uy*CHIPSIZE,CHIPSIZE,CHIPSIZE,1,$aa4444,$aa8888}//右上 if map(myg_lx,myg_dy)=4 {mes strf("X=%d,Y=%d",myg_lx,myg_dy):gradf myg_lx*CHIPSIZE,myg_dy*CHIPSIZE,CHIPSIZE,CHIPSIZE,1,$aa4444,$aa8888}//左下 if map(myg_rx,myg_dy)=4 {mes strf("X=%d,Y=%d",myg_rx,myg_dy):gradf myg_rx*CHIPSIZE,myg_dy*CHIPSIZE,CHIPSIZE,CHIPSIZE,1,$aa4444,$aa8888}//右下 gradf mypx,mypy,mysizex,mysizey,1,$55ddee,$55ddee redraw 1 await 16 loop
判定が出来れば思い通りにキャラを動かせる訳じゃない
シューティングみたいに当たったらどちらか消せば済む物じゃないので
判定は一回じゃ済まない事が多い

判定も判定後の処理も色々方法があるので色々試してみると良い



HSP初心者

リンク

2013/10/29(Tue) 17:21:44|NO.57879

Ve様
わかりやすい説明をありがとうございます!
色々方法があるんですね。
覚えておきます!
暇人様
ご回答ありがとうございます!
僕は一度シューティングを作ったことがあり、
同じように考えていました。
でも、判定は一回じゃすまないということがわかったので、
考えながらたくさん試してみます。



HSP初心者

リンク

2013/11/2(Sat) 10:44:21|NO.57947

皆さんありがとうございました!
がんばります!



ONION software Copyright 1997-2023(c) All rights reserved.