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


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0301
べりー横スクロールのゲームのブロック判定について12未解決


べりー

リンク

2014/3/1(Sat) 23:41:48|NO.60376

たびたび質問すみません。実はまだブロックの当たり判定が直ってません。

質問内容はキャラだけ動かしているときは指定した場所にブロックが置けるのですが、
キャラを動かさずに画面をスクロールに変更したときにブロックが指定箇所に置けない
ということがおきました。

どのように対処すればよろしいでしょうか?
まずはキャラが動くタイプ(正常)
AWDS移動で矢印キーでブロックを配置です。

// ■重力加速度を「α_G」 // ■「キャラvy」を「vy_Char」 x1=0.0:y1=0.0 ; 画面左上の座標 x2=480.0:y2=480.0 ; 画面右下の座標 clrflag=0 ; クリアフラグ #define α_G 0.98 //重力加速度 blsize=16.0 ; ボールのサイズ blspd=5.0 ; ボールのスピード vy_Char = 0.0 //キャラの速度のy成分 blx=240.0:bly=300.0 ; ボールの座標 bpx=2.0:bpy=2.0 ; XY方向のボール座標加算値 bk=0 ; ブロックを崩すフラグ(1=崩す) mblsize=-blsize;ボール一点座標? IsBallJumping = 0 //ボールの滞空フラグ(0,1)=(false,true) // ●---head---● // |   | // |   | // |     | // |     | // ●---leg----● blhalf=blsize/2//ボールの中心? wpx=10.0:wpy=10.0 ; ブロック1個あたりのサイズ wx=0 :wy=0 ; ブロックの表示開始位置(左上) blnum_x=x2/wpx //ブロックのx方向の個数 blnum_y=y2/wpy //〃y〃 wsx=blnum_x:wsy=blnum_y ; ブロックの配置数(X,Y) dim wall,wsx,wsy ; ブロックを表示するフラグ //←「表示/非表示」というより、むしろ「存在する/しない」では? ; 0=表示、1=表示しない ←(※個人的には「(0,1)=(表示しない,する)」の方が本能的にしっくりくる...。(※あんまり気にしないで!)) ;< ブロックの存在の設定 > repeat blnum_x ;右端20列を穴にする cnt1 = cnt repeat 40 wall(cnt1,cnt) = 1 loop loop screen 0,x2,y2 title "キャラ移動" cls 4 *main redraw 0 gradf 0,0,x2,y2,1,0,128 ; 画面クリア ; ボール : X方向の移動 //stick key,15 //(=1+2+4+8) //左移動 getkey A_move,65 if A_move=1 :blx=blx-bpx //bpxは進行速度 //右移動 getkey D_move,68 if D_move=1 :blx=blx+bpx // //map離脱制御 if blx<=x1 : blx=x1 if blx>=(x2-blsize): blx=x2-blsize //スペースキーでジャンプ getkey spase_jump,32//スペースキー if spase_jump=1 and IsBallJumping=0{ vy_Char=-8.0 bly += vy_Char } /////////////////////////////////// //////矢印でブロック配置/////////// /////////////////////////////////// //set_bl でブロック座標指定してブロックを配置 getkey cleak_R,39//右 getkey cleak_L,37//左 getkey cleak_UP,38 getkey cleak_DOWN,40 getkey item_1,49:if item_1=1:item=0 getkey item_2,50:if item_2=1:item=1 /* getkey item_3,51:if item_3=1:item=2 getkey item_4,52:if item_4=1:item=3 getkey item_5,53:if item_5=1:item=4 getkey item_6,54:if item_6=1:item=5 getkey item_7,55:if item_7=1:item=6 */ if (cleak_R=1)&(cleak_UP=0)&(cleak_DOWN=0)&(cleak_DOWN=0) { set_blx=bl_legx+10:set_bly=bl_legy-1 repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_L=1)&(cleak_UP=0)&(cleak_DOWN=0)&(cleak_R=0){ set_blx=bl_legx-11:set_bly=bl_legy-1 repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_UP=1)&(cleak_L=0)&(cleak_R=0)&(cleak_DOWN=0){ set_blx=bl_legx:set_bly=bl_heady-10 repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_DOWN=1)&(cleak_L=0)&(cleak_R=0)&(cleak_UP=0){ set_blx=bl_legx:set_bly=bl_legy+1 repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_DOWN=0)&(cleak_L=0)&(cleak_R=1)&(cleak_UP=1){ set_blx=bl_legx+10:set_bly=bl_heady repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_DOWN=0)&(cleak_L=1)&(cleak_R=0)&(cleak_UP=1){ set_blx=bl_legx-10:set_bly=bl_heady repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_DOWN=1)&(cleak_L=1)&(cleak_R=0)&(cleak_UP=0){ set_blx=bl_legx-10:set_bly=bl_legy+1 repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_DOWN=1)&(cleak_L=0)&(cleak_R=1)&(cleak_UP=0){ set_blx=bl_legx+10:set_bly=bl_legy+1 repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } repeat blnum_x cntx=cnt if (cntx*10 <= blx) & (blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= bly) & (bly <= cnty*10+9){ } loop } loop ; ブロックの処理 colx=wpx+bsize;ブロックの大きさ + ボールのサイズ coly=wpy+bsize //< ブロックの描画 & ボールの足場吟味 > IsBallJumping = 1 ;フラグ初期化 repeat wsy cy = cnt y_check = wy + cnt*wpy color 200,200,200 repeat wsx cx = cnt x_check = wx + cnt*wpx if wall(cx,cy) = 0 { ;ブロックが存在するならば ;< 描画 > boxf x_check,y_check ,x_check+wpx-2.0,y_check+wpy-2.0 ;< 足場吟味 > ブロック開始座標 - ボール中心座標 <ボール座標 & ブロック開始座標+ブロックのサイズ-ボールの中心座標が >ボール座標 ときは・・・当たる bl_headx = blx+(blsize/2) : bl_heady = bly+0.0 bl_legx = blx+(blsize/2) : bl_legy = bly+blsize //頭がブロックに当たってないか、足がブロックに当たっていないか //の順番で判定を行う //頭がブロックに当たっているか判定 if (x_check <= bl_headx) & ( bl_headx <= x_check + wpx ){ if(y_check <= bl_heady) & ( bl_heady <= y_check + wpy ){ IsBallJumping = 1 //判定ボックスの点滅 if x_cheak+wpx/2 <= bl_headx{ color 0,0,0:boxf x_check,y_check ,x_check+wpx-2.0,y_check+wpy-2.0 blx=blx + 2 } } } //足がブロックに当たっているか判定 if (x_check<= bl_legx)&(bl_legx <= x_check+wpx){ if(y_check<= bl_legy)&(bl_legy <= y_check+wpy){ //いまフォーカスしているブロックがボールの足場であるなら、 //ボールは接地しているとみなせる。y座標についてはすり抜け現象を防ぐための緩衝値が必要。 IsBallJumping = 0 bly = y_check-blsize } } } loop loop //< 力学処理 > ;< 速度処理 > if IsBallJumping = 0 { ;接地しているならば vy_Char = 0.0 } else { ;接地していないならば vy_Char + α_G } ;< 移動処理 > bly + vy_Char //毎回速度成分を足しているけれど、速度が0なら座標が変わらないよね...。 //つまり、物理的に考えれば「速度」がボールの位置を操る鍵ってこと! //(※厳密には「初期位置」&「初速」&「力」が鍵だが、運動方程式を使わないこのゲームならそこまで対応する必要はない。)。 //これさえコントロールすればあとの処理はいかなる場合でも同じ形の手続きで記述してよい。 //⇒コードすっきり! ; ボールを表示 pos blx,bly:color 255,255,255 font msgothic,blsize mes "●" pos 0,20:color 255,255,255 mes "x_head:"+bl_headx pos 0,40:color 255,255,255 mes "y_head:"+bl_heady redraw 1 await 16 goto *main *gameover objsize 180,32 pos 150,330:button "終わり",*owari stop *owari end

次のプログラムは画面がスクロールします、するとブロックがうまくおけなくなります。


// ■重力加速度を「α_G」 // ■「キャラvy」を「vy_Char」 x1=0.0:y1=0.0 ; 画面左上の座標 x2=480.0:y2=480.0 ; 画面右下の座標 clrflag=0 ; クリアフラグ #define α_G 0.98 //重力加速度 blsize=16.0 ; ボールのサイズ blspd=5.0 ; ボールのスピード vy_Char = 0.0 //キャラの速度のy成分 blx=240.0:bly=300.0 ; ボールの座標 bpx=2.0:bpy=2.0 ; XY方向のボール座標加算値 bk=0 ; ブロックを崩すフラグ(1=崩す) mblsize=-blsize;ボール一点座標? IsBallJumping = 0 //ボールの滞空フラグ(0,1)=(false,true) // ●---head---● // |   | // |   | // |     | // |     | // ●---leg----● blhalf=blsize/2//ボールの中心? wpx=10.0:wpy=10.0 ; ブロック1個あたりのサイズ wx=0 :wy=0 ; ブロックの表示開始位置(左上) blnum_x=x2/wpx //ブロックのx方向の個数 blnum_y=y2/wpy //〃y〃 wsx=blnum_x:wsy=blnum_y ; ブロックの配置数(X,Y) dim wall,wsx,wsy ; ブロックを表示するフラグ //←「表示/非表示」というより、むしろ「存在する/しない」では? ; 0=表示、1=表示しない ←(※個人的には「(0,1)=(表示しない,する)」の方が本能的にしっくりくる...。(※あんまり気にしないで!)) ;< ブロックの存在の設定 > repeat blnum_x ;右端20列を穴にする cnt1 = cnt repeat 40 wall(cnt1,cnt) = 1 loop loop screen 0,x2,y2 title "キャラ移動" cls 4 *main redraw 0 gradf 0,0,x2,y2,1,0,128 ; 画面クリア ; ボール : X方向の移動 //stick key,15 //(=1+2+4+8) //左移動 getkey A_move,65 if A_move=1 :wx=wx+bpx //bpxは進行速度 //右移動 getkey D_move,68 if D_move=1 :wx=wx-bpx // //map離脱制御 if blx<=x1 : blx=x1 if blx>=(x2-blsize): blx=x2-blsize //スペースキーでジャンプ getkey spase_jump,32//スペースキー if spase_jump=1 and IsBallJumping=0{ vy_Char=-8.0 bly += vy_Char } /////////////////////////////////// //////矢印でブロック配置/////////// /////////////////////////////////// //set_bl でブロック座標指定してブロックを配置 getkey cleak_R,39//右 getkey cleak_L,37//左 getkey cleak_UP,38 getkey cleak_DOWN,40 getkey item_1,49:if item_1=1:item=0 getkey item_2,50:if item_2=1:item=1 /* getkey item_3,51:if item_3=1:item=2 getkey item_4,52:if item_4=1:item=3 getkey item_5,53:if item_5=1:item=4 getkey item_6,54:if item_6=1:item=5 getkey item_7,55:if item_7=1:item=6 */ if (cleak_R=1)&(cleak_UP=0)&(cleak_DOWN=0)&(cleak_DOWN=0) { set_blx=bl_legx+10:set_bly=bl_legy-1 repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_L=1)&(cleak_UP=0)&(cleak_DOWN=0)&(cleak_R=0){ set_blx=bl_legx-11:set_bly=bl_legy-1 repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_UP=1)&(cleak_L=0)&(cleak_R=0)&(cleak_DOWN=0){ set_blx=bl_legx:set_bly=bl_heady-10 repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_DOWN=1)&(cleak_L=0)&(cleak_R=0)&(cleak_UP=0){ set_blx=bl_legx:set_bly=bl_legy+1 repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_DOWN=0)&(cleak_L=0)&(cleak_R=1)&(cleak_UP=1){ set_blx=bl_legx+10:set_bly=bl_heady repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_DOWN=0)&(cleak_L=1)&(cleak_R=0)&(cleak_UP=1){ set_blx=bl_legx-10:set_bly=bl_heady repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_DOWN=1)&(cleak_L=1)&(cleak_R=0)&(cleak_UP=0){ set_blx=bl_legx-10:set_bly=bl_legy+1 repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } if (cleak_DOWN=1)&(cleak_L=0)&(cleak_R=1)&(cleak_UP=0){ set_blx=bl_legx+10:set_bly=bl_legy+1 repeat blnum_x cntx=cnt if(cntx*10 <= set_blx) & (set_blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= set_bly) & (set_bly <= cnty*10+9){ wall(cntx,cnty) = item } loop } loop } repeat blnum_x cntx=cnt if (cntx*10 <= blx) & (blx <= cntx*10+9){ repeat blnum_y cnty=cnt if (cnty*10 <= bly) & (bly <= cnty*10+9){ } loop } loop ; ブロックの処理 colx=wpx+bsize;ブロックの大きさ + ボールのサイズ coly=wpy+bsize //< ブロックの描画 & ボールの足場吟味 > IsBallJumping = 1 ;フラグ初期化 repeat wsy cy = cnt y_check = wy + cnt*wpy color 200,200,200 repeat wsx cx = cnt x_check = wx + cnt*wpx if wall(cx,cy) = 0 { ;ブロックが存在するならば ;< 描画 > boxf x_check,y_check ,x_check+wpx-2.0,y_check+wpy-2.0 ;< 足場吟味 > ブロック開始座標 - ボール中心座標 <ボール座標 & ブロック開始座標+ブロックのサイズ-ボールの中心座標が >ボール座標 ときは・・・当たる bl_headx = blx+(blsize/2) : bl_heady = bly+0.0 bl_legx = blx+(blsize/2) : bl_legy = bly+blsize //頭がブロックに当たってないか、足がブロックに当たっていないか //の順番で判定を行う //頭がブロックに当たっているか判定 if (x_check <= bl_headx) & ( bl_headx <= x_check + wpx ){ if(y_check <= bl_heady) & ( bl_heady <= y_check + wpy ){ IsBallJumping = 1 //判定ボックスの点滅 if x_cheak+wpx/2 <= bl_headx{ color 0,0,0:boxf x_check,y_check ,x_check+wpx-2.0,y_check+wpy-2.0 blx=blx + 2 } } } //足がブロックに当たっているか判定 if (x_check<= bl_legx)&(bl_legx <= x_check+wpx){ if(y_check<= bl_legy)&(bl_legy <= y_check+wpy){ //いまフォーカスしているブロックがボールの足場であるなら、 //ボールは接地しているとみなせる。y座標についてはすり抜け現象を防ぐための緩衝値が必要。 IsBallJumping = 0 bly = y_check-blsize } } } loop loop //< 力学処理 > ;< 速度処理 > if IsBallJumping = 0 { ;接地しているならば vy_Char = 0.0 } else { ;接地していないならば vy_Char + α_G } ;< 移動処理 > bly + vy_Char //毎回速度成分を足しているけれど、速度が0なら座標が変わらないよね...。 //つまり、物理的に考えれば「速度」がボールの位置を操る鍵ってこと! //(※厳密には「初期位置」&「初速」&「力」が鍵だが、運動方程式を使わないこのゲームならそこまで対応する必要はない。)。 //これさえコントロールすればあとの処理はいかなる場合でも同じ形の手続きで記述してよい。 //⇒コードすっきり! ; ボールを表示 pos blx,bly:color 255,255,255 font msgothic,blsize mes "●" pos 0,20:color 255,255,255 mes "x_head:"+bl_headx pos 0,40:color 255,255,255 mes "y_head:"+bl_heady redraw 1 await 16 goto *main *gameover objsize 180,32 pos 150,330:button "終わり",*owari stop *owari end



この記事に返信する


YSR

リンク

2014/3/2(Sun) 00:24:08|NO.60386

・ソースコード長すぎだろ……ここまでの大きさだと、外部のアップローダに上げるか
 codepad等に貼ってURL上げるかの方が見やすいと思う
・「正常に動く」方でも□に○がめり込めて、その際□が■になるのはどういうこっちゃ?
 (と言うかブロック1個ってボールより明らかに狭いのにボールが通るのが納得いかない)
・スペースを押している間ぴょんぴょんし続けるのは仕様なのか?
・「テンキーじゃない方の"2"を押す、方向キーでブロックを消せる」
 テンキーの方が押しやすいんじゃないですかね……
・ブロック接地処理部分が冗長すぎる気がする。工夫したら大きく削れそう
・スクロール版の方だが、ブロックに阻まれた途端にボールの画面に対する位置が
 中央でなくなるのが気持ち悪い。ヘタするとボールがどんどん画面端に追いやられて
 操作しづらくなるし……。ブロックの置き場所がおかしくなるのは、
 置き場所を置く際にボールの相対的な位置だけずらしていないからでは?



Tetr@pod

リンク

2014/3/2(Sun) 00:50:38|NO.60388

スクロールの分が考慮されていないのが原因です。

答えだけのせると、
set_blx=bl_legx

set_bly=bl_legy
をそれぞれ
set_blx=-wx+bl_legx

set_bly=-wy+bl_legy
に置換。

その他のツッコミは他の方に任せます。



べりー

リンク

2014/3/2(Sun) 20:17:01|NO.60415

最近HPSを始めたので暗黙のルール的なのを知らずにすみません。

今度からソースが長い場合は外部アップローダにあげます。ご忠告有難うございます。
□が■になるのは当たり判定が行われているか目でみてわかるようにしたものです。
これも誤解を生むようでしたらすみません。

スクロール分を考えていなかったのですね・・・
本当に有難うございます!
その他の突っ込みも教えていただければ幸いです。。。



暇人

リンク

2014/3/4(Tue) 02:10:06|NO.60436

ブロックを総当りで判定してるのをボールの周辺だけの判定に変更
ブロックを作る時にボールと重ならない様に変更

ここで使ってる判定は完璧では無い
特定の条件下で不自然な動きになる可能性はある

// ■重力加速度を「α_G」 // ■「キャラvy」を「vy_Char」 x1=0.0:y1=0.0 ; 画面左上の座標 x2=480.0:y2=480.0 ; 画面右下の座標 clrflag=0 ; クリアフラグ #define α_G 0.98 //重力加速度 blsize=16.0 ; ボールのサイズ blspd=5.0 ; ボールのスピード vy_Char = 0.0 //キャラの速度のy成分 blx=240.0:bly=300.0 ; ボールの座標 bpx=2.0:bpy=2.0 ; XY方向のボール座標加算値 bk=0 ; ブロックを崩すフラグ(1=崩す) mblsize=-blsize;ボール一点座標? IsBallJumping = 0 //ボールの滞空フラグ(0,1)=(false,true) blhalf=blsize/2//ボールの中心? wpx=10.0:wpy=10.0 ; ブロック1個あたりのサイズ wx=0 :wy=0 ; ブロックの表示開始位置(左上) blnum_x=x2/wpx //ブロックのx方向の個数 blnum_y=y2/wpy //〃y〃 wsx=blnum_x:wsy=blnum_y ; ブロックの配置数(X,Y) dim wall,wsx,wsy ; ブロックを表示するフラグ //←「表示/非表示」というより、むしろ「存在する/しない」では? ; 0=表示、1=表示しない ←(※個人的には「(0,1)=(表示しない,する)」の方が本能的にしっくりくる...。(※あんまり気にしないで!)) ;< ブロックの存在の設定 > repeat blnum_x ;右端20列を穴にする cnt1 = cnt repeat 40 wall(cnt1,cnt) = 1 loop loop screen 0,x2,y2 title "キャラ移動" cls 4 *main redraw 0 gradf 0,0,x2,y2,1,0,128 ; 画面クリア /////////////////////////////////// //////矢印でブロック配置/////////// /////////////////////////////////// //set_bl でブロック座標指定してブロックを配置(スクリーン座標じゃなくグリッド座標に変更) getkey cleak_R,39//右 getkey cleak_L,37//左 getkey cleak_UP,38 getkey cleak_DOWN,40 getkey item_1,49:if item_1=1:item=0 : title "item="+item getkey item_2,50:if item_2=1:item=1 : title "item="+item if (cleak_L or cleak_R ) {//左右の位置設定 if cleak_L {set_blx=int(blx-wpx+1)/wpx}else{set_blx=int(blx+blsize-1)/wpx+1} }else{//X座標は中央に設定 set_blx=int(blx+blhalf)/wpx } if (cleak_UP or cleak_DOWN ) {//上下の位置設定 if cleak_UP {//上の位置設定 if (cleak_L or cleak_R ) {set_bly=int(bly)/wpy}else{set_bly=int(bly-wpy)/wpy}//左右入力がある時と無い時で位置を変える }else{//ボール下のグリッド座標 set_bly=int(bly+blsize-1)/wpy+1 } }else{//左右入力があるときのY座標はボールの下部と重なるグリッド座標 set_bly=int(bly+blsize-1)/wpy } if (cleak_L or cleak_R or cleak_UP or cleak_DOWN) {wall(set_blx,set_bly) = item} ; ボール : X方向の移動 //stick key,15 //(=1+2+4+8) blx_old=blx //前回の座標を保存 bly_old=bly //左移動 getkey A_move,65 if A_move=1 :blx=blx-bpx //bpxは進行速度 //右移動 getkey D_move,68 if D_move=1 :blx=blx+bpx // //map離脱制御 if blx<=x1 : blx=x1 if blx>=(x2-blsize): blx=x2-blsize //スペースキーでジャンプ getkey spase_jump,32//スペースキー if spase_jump=1 and IsBallJumping=0{ IsBallJumping=1//衝突判定前に上下移動させるのでフラグセット vy_Char=-8.0-α_G ;bly += vy_Char } //< ブロックの描画 > repeat wsy cy = cnt y_check = wy + cnt*wpy color 200,200,200 repeat wsx cx = cnt x_check = wx + cnt*wpx if wall(cx,cy) = 0 { ;ブロックが存在するならば ;< 描画 > boxf x_check,y_check ,x_check+wpx-2.0,y_check+wpy-2.0 } loop loop //< 力学処理 > ;< 速度処理 > if IsBallJumping = 0 { ;接地しているならば vy_Char = 0.0 } else { ;接地していないならば vy_Char + α_G vy_Char=limitf(vy_Char,-wpy,wpy) //最大速度をブロックサイズ以内に設定(超えるとブロックを飛び越す) } ;< 移動処理 > bly + vy_Char //< ボールの衝突判定&移動 > //stickのと同じような感じでdirに移動方向を代入 dir= (blx<blx_old)*1 or (blx>blx_old)*4 dir|= (bly<bly_old)*2 or (bly>bly_old)*8 if dir {//移動してる //colxyにボールの周囲の座標を0〜7に代入(ブロックよりボールの判定が大きいので一つの判定がブロックの判定以下になるよいに分割して8方向で判定) //0 1 2 //0がボールの左上、2が右上の位置にあるブロックと判定するための座標 //7 * 3 //6 5 4 colxy=0,int(blhalf),int(blsize)-1,int(blsize)-1,int(blsize)-1,int(blhalf),0,0//サイズから-1してるのはサイズ16は座標で0〜15になるので if dir&10 {//上下に移動した repeat 8 cx=(colxy(cnt)+blx)/wpx cy=(colxy((6+cnt)\8)+bly)/wpy //Y座標はXを6個ずらして使用 if(wall(cx, cy) = 0){//ボールが接触 if dir&8 {//下に移動中 if (int(bly_old+blsize-1)/wpy)< cy {//前回の座標が接触したブロックより上ならボールの下が当たった bly_test = wy + (int(bly+blsize-1)/wpy)*wpy-blsize//とりあえず下のブロックに載った時の座標を算出 if(wall(cx, (bly_test+blsize-1)/wpy) = 0) or (wall(cx, bly_test/wpy) = 0){//ブロックの上に移動してもまだ接触してる //bly_testを次の左右に移動した時の当たり判定に持ち越し }else{//上に移動したら接触しなかった bly = 1.0*bly_test //とりあえず算出しといた座標を実際の座標に使用 } break } }else{ if (int(bly_old)/wpy)> cy { bly_test = wy + (int(bly)/wpy)*wpy+wpy//とりあえず上のブロックの下の座標を算出 if(wall(cx, bly_test/wpy) = 0) or (wall(cx, (bly_test+blsize-1)/wpy) = 0){//ブロックの上に移動してもまだ接触してる //bly_testを次の左右に移動した時の当たり判定に持ち越し }else{ bly = 1.0*bly_test //とりあえず算出しといた座標を実際の座標に使用 } break } } } loop } if dir&5 {//左右に移動した repeat 8 cx=(colxy(cnt)+blx)/wpx cy=(colxy((6+cnt)\8)+bly)/wpy if(wall(cx, cy) = 0){//ボールの左下が接触 if dir&1 {//左に移動中 blx_test = wx + (int(blx)/wpx)*wpx+wpx//とりあえず左側ブロックの右に位置した時の座標を算出 }else{ blx_test = wx + cx*wpx-blsize//とりあえず右側ブロックの左に位置した時の座標を算出 } if(wall(blx_test/wpx, cy) = 0) or (wall((blx_test+blsize-1)/wpx, cy) = 0){//横に移動しただけじゃ接触してる blx = 1.0*blx_test //とりあえず算出しといた座標を実際の座標に使用 bly = 1.0*bly_test //上下に移動した時判定で算出して持ち越した座標を実際の座標に使用 }else{//横に移動すれば接触しないのでblx_testを実際の座標にする blx = 1.0*blx_test } break } loop } } //足元チェック if(wall(int(blx)/wpx, int(bly+blsize)/wpy) = 0) or (wall(int(blx+blsize/2)/wpx, int(bly+blsize)/wpy) = 0) or (wall(int(blx+blsize-1)/wpx, int(bly+blsize)/wpy) = 0) { //足元にブロックがあった IsBallJumping = 0 bly = 1.0*wy + (int(bly+blsize)/wpy)*wpy-blsize }else{//足元にブロックが無かった IsBallJumping = 1 } ; ボールを表示 pos blx,bly:color 255,255,255 font msgothic,blsize mes "●" pos 0,20:color 255,255,255 mes "x_head:"+bl_headx pos 0,40:color 255,255,255 mes "y_head:"+bl_heady redraw 1 await 16 goto *main *gameover objsize 180,32 pos 150,330:button "終わり",*owari stop *owari end
落下速度をブロックサイズより大きくしたい場合は工夫が必要



暇人

リンク

2014/3/4(Tue) 20:12:38|NO.60452

色々いじってたのを戻すの忘れてた部分があった

>bly_test = wy + (int(bly+blsize-1)/wpy)*wpy-blsize//とりあえず下のブロックに載った時の座標を算出
これを

bly_test = cy*wpy-blsize//とりあえず下のブロックに載った時の座標を算出
に修正

>bly_test = wy + (int(bly)/wpy)*wpy+wpy//とりあえず上のブロックの下の座標を算出
これを

bly_test = cy*wpy+wpy//とりあえず上のブロックの下の座標を算出
に修正

>blx_test = wx + (int(blx)/wpx)*wpx+wpx//とりあえず左側ブロックの右に位置した時の座標を算出
これを

blx_test = cx*wpx+wpx; cx*wpx+wpx//とりあえず左側ブロックの右に位置した時の座標を算出
に修正

まぁ、多分実行結果は変らないんだけど・・・



べりー

リンク

2014/3/5(Wed) 00:15:34|NO.60459

暇人さん本当に有難うございます。
ですが今の私に全部理解できそうにないです・・・

//stickのと同じような感じでdirに移動方向を代入
dir= (blx<blx_old)*1 or (blx>blx_old)*4
dir|= (bly<bly_old)*2 or (bly>bly_old)*8

if dir {//移動してる
特にこの当たりが分かりませんでした。

いま書いていただいたソースを見ながら勉強していきます。



暇人

リンク

2014/3/5(Wed) 00:16:21|NO.60460

スクロール対応版
縦横2画面分のマップ

// ■重力加速度を「α_G」 // ■「キャラvy」を「vy_Char」 x1=0.0:y1=0.0 ; 画面左上の座標 x2=480.0:y2=480.0 ; 画面右下の座標 scntx=2 //横の画面数 scnty=2 //縦の画面数 max_srx=(scntx-1)*x2 //横の最大スクロール値 max_sry=(scnty-1)*y2 //縦の最大スクロール値 Scrollx=0.0 //スクロール値 Scrolly=0.0 //スクロール値 clrflag=0 ; クリアフラグ #define α_G 0.98 //重力加速度 blsize=16.0 ; ボールのサイズ blspd=5.0 ; ボールのスピード vy_Char = 0.0 //キャラの速度のy成分 blx=240.0:bly=300.0 ; ボールの座標 bpx=2.0:bpy=2.0 ; XY方向のボール座標加算値 bk=0 ; ブロックを崩すフラグ(1=崩す) mblsize=-blsize;ボール一点座標? IsBallJumping = 0 //ボールの滞空フラグ(0,1)=(false,true) blhalf=blsize/2//ボールの中心? wpx=10.0:wpy=10.0 ; ブロック1個あたりのサイズ wx=0 :wy=0 ; ブロックの表示開始位置(左上) blnum_x=x2*scntx/wpx //ブロックのx方向の個数 blnum_y=y2*scnty/wpy //〃y〃 wsx=blnum_x:wsy=blnum_y ; ブロックの配置数(X,Y) //自動スクロール開始位置 srst_L=x2/2-wpx*5 //左スクロール開始位置 srst_R=x2/2 //右スクロール開始位置 srst_U=y2-wpy*10 //上スクロール開始位置 srst_D=y2-wpy*5 //下スクロール開始位置 dim wall,wsx,wsy ; ブロックを表示するフラグ //←「表示/非表示」というより、むしろ「存在する/しない」では? ; 0=表示、1=表示しない ←(※個人的には「(0,1)=(表示しない,する)」の方が本能的にしっくりくる...。(※あんまり気にしないで!)) ;< ブロックの存在の設定 > repeat blnum_x ;右端20列を穴にする cnt1 = cnt repeat 40 wall(cnt1,cnt) = 1 loop loop screen 0,x2,y2 title "キャラ移動" cls 4 *main redraw 0 gradf 0,0,x2,y2,1,0,128 ; 画面クリア /////////////////////////////////// //////矢印でブロック配置/////////// /////////////////////////////////// //set_bl でブロック座標指定してブロックを配置(スクリーン座標じゃなくグリッド座標に変更) getkey cleak_R,39//右 getkey cleak_L,37//左 getkey cleak_UP,38 getkey cleak_DOWN,40 getkey item_1,49:if item_1=1:item=0 : title "item="+item getkey item_2,50:if item_2=1:item=1 : title "item="+item bl_setf=cleak_L | cleak_R | cleak_UP | cleak_DOWN if cleak_L and blx<wpx {bl_setf=0} //画面の左端ならブロック設置キャンセル if cleak_R and blx>(x2-blsize-wpx) {bl_setf=0} //画面の右端ならブロック設置キャンセル if cleak_UP and bly<wpy {bl_setf=0} if cleak_DOWN and bly>(y2-blsize-wpy) {bl_setf=0} if bl_setf { if (cleak_L or cleak_R ) {//左右の位置設定 if cleak_L {set_blx=int(blx-wx-wpx+1)/wpx}else{set_blx=int(blx-wx+blsize-1)/wpx+1} }else{//X座標は中央に設定 set_blx=int(blx-wx+blhalf)/wpx } if (cleak_UP or cleak_DOWN ) {//上下の位置設定 if cleak_UP {//上の位置設定 if (cleak_L or cleak_R ) {set_bly=int(bly-wy)/wpy}else{set_bly=int(bly-wy-wpy)/wpy}//左右入力がある時と無い時で位置を変える }else{//ボール下のグリッド座標 set_bly=int(bly-wy+blsize-1)/wpy+1 } }else{//左右入力があるときのY座標はボールの下部と重なるグリッド座標 set_bly=int(bly-wy+blsize-1)/wpy } wall(set_blx,set_bly) = item } ; ボール : X方向の移動 //stick key,15 //(=1+2+4+8) blx_wx_old=blx-wx //前回のワールド座標を保存 bly_wy_old=bly-wy //左移動 getkey A_move,65 if A_move=1 { if (blx<srst_L) and Scrollx<0.0 {//blxがsrst_Lより左にボールが来たら左にスクロール(Scrollxが0なら位置に関係なくボール移動) Scrollx+bpx }else{//blxがsrst_Lになるまでボールを移動(Scrollxが0なら位置に関係なくボール移動) blx-bpx //bpxは進行速度 } } //右移動 getkey D_move,68 if D_move=1 { if blx>srst_R and Scrollx>-max_srx {//blxがsrst_Rより右にボールが来たら左にスクロール(Scrollxが-max_srx以上なら位置に関係なくボール移動) Scrollx-bpx }else{//blxがsrst_Rになるまでボールを移動(Scrollxが-max_srx以上なら位置に関係なくボール移動) blx+bpx //bpxは進行速度 } } //縦方向自動スクロール if (bly>srst_D) and Scrolly>-max_sry {//blyがsrst_Dより下にボールが来たら下にスクロール(Scrollyが-max_sry以上なら位置に関係なくスクロール無し) Scrolly-=bly-srst_D bly=1.0*srst_D } if (bly<srst_U) and Scrolly<0.0 {//blyがsrst_Uより上にボールが来たら下にスクロール(Scrollyが0なら位置に関係なくスクロール無し) Scrolly-=bly-srst_U bly=1.0*srst_U } Scrollx=limitf(Scrollx,-max_srx,0.0) //スクロール値を制限 wx=int(Scrollx) Scrolly=limitf(Scrolly,-max_sry,0.0) //スクロール値を制限 wy=int(Scrolly) //スペースキーでジャンプ getkey spase_jump,32//スペースキー if spase_jump=1 and IsBallJumping=0{ IsBallJumping=1//衝突判定前に上下移動させるのでフラグセット vy_Char=-8.0-α_G } //< 力学処理 > ;< 速度処理 > if IsBallJumping = 0 { ;接地しているならば vy_Char = 0.0 } else { ;接地していないならば vy_Char + α_G vy_Char=limitf(vy_Char,-wpy,wpy) //最大速度をブロックサイズ以内に設定(超えるとブロックを飛び越す) } ;< 移動処理 > bly + vy_Char //map離脱制御 if blx<x1 :blx=x1 if blx>=(x2-blsize): blx=x2-blsize if bly<y1 :bly=y1 if bly>=(y2-blsize): bly=y2-blsize //< ブロックの描画 > index_x=abs(wx)/wpx //スクロール分をrepeat開始位置にする index_y=abs(wy)/wpy blcntx=wsx/scntx //一画面分のブロック数 if (blcntx+index_x)<wsx {blcntx+1}//スクロールするには画面分+1が必要だが、スクロール最後でマップ配列を超えないように制御 blcnty=wsy/scnty //一画面分のブロック数 if (blcnty+index_y)<wsy {blcnty+1}//スクロールするには画面分+1が必要だが、スクロール最後でマップ配列を超えないように制御 repeat blcnty,index_y cy = cnt y_blp = cy*wpy+wy //cy*wpyはワールド座標になるのでスクロール分を省いてスクリーン座標にする x_blp = index_x*wpx+wx //横方向の描画開始位置 color 200,200,200 repeat blcntx,index_x if wall(cnt,cy) = 0 { ;ブロックが存在するならば ;< 描画 > boxf x_blp,y_blp ,x_blp+wpx-2.0,y_blp+wpy-2.0 } x_blp+wpx //1ブロック移動 loop loop //< ボールの衝突判定&移動 > //stickのと同じような感じでdirに移動方向を代入 dir= ((blx-wx)<blx_wx_old)*1 or ((blx-wx)>blx_wx_old)*4 dir|= ((bly-wy)<bly_wy_old)*2 or ((bly-wy)>bly_wy_old)*8 if dir {//移動してる //colxyにボールの周囲の座標を0〜7に代入(ブロックよりボールの判定が大きいので一つの判定がブロックの判定以下になるよいに分割して8方向で判定) //0 1 2 //0がボールの左上、2が右上の位置にあるブロックと判定するための座標 //7 * 3 //6 5 4 colxy=0,int(blhalf),int(blsize)-1,int(blsize)-1,int(blsize)-1,int(blhalf),0,0//サイズから-1してるのはサイズ16は座標で0〜15になるので if dir&10 {//上下に移動した blx_wx=blx-wx //スクロール済み座標を先に出しとく bly_wy=bly-wy repeat 8 cx=(colxy(cnt)+blx_wx)/wpx cy=(colxy((6+cnt)\8)+bly_wy)/wpy //Y座標はXを6個ずらして使用 if(wall(cx, cy) = 0){//ボールが接触 if dir&8 {//下に移動中 if (int(bly_wy_old+blsize-1)/wpy)< cy {//前回の座標が接触したブロックより上ならボールの下が当たった bly_test = cy*wpy-blsize//とりあえず下のブロックに載った時の座標を算出 if(wall(cx, (bly_test+blsize-1)/wpy) = 0) or (wall(cx, bly_test/wpy) = 0){//ブロックの上に移動してもまだ接触してる //bly_testを次の左右に移動した時の当たり判定に持ち越し }else{//上に移動したら接触しなかった bly = 1.0*bly_test+wy //とりあえず算出しといた座標からスクロール分を省いてスクリーン座標で使用 } break } }else{//上に移動中 if (int(bly_wy_old)/wpy)> cy { bly_test = cy*wpy+wpy//とりあえず上のブロックの下の座標を算出 if(wall(cx, bly_test/wpy) = 0) or (wall(cx, (bly_test+blsize-1)/wpy) = 0){//ブロックの上に移動してもまだ接触してる //bly_testを次の左右に移動した時の当たり判定に持ち越し }else{ bly = 1.0*bly_test+wy //とりあえず算出しといた座標からスクロール分を省いてスクリーン座標で使用 } break } } } loop } if dir&5 {//左右に移動した blx_wx=blx-wx //スクロール済み座標を先に出しとく bly_wy=bly-wy repeat 8 cx=(colxy(cnt)+blx_wx)/wpx cy=(colxy((6+cnt)\8)+bly_wy)/wpy //Y座標はXを6個ずらして使用 if(wall(cx, cy) = 0){//ボールの左下が接触 if dir&1 {//左に移動中 blx_test = cx*wpx+wpx//とりあえず左側ブロックの右に位置した時の座標を算出 }else{//右に移動中 blx_test = cx*wpx-blsize//とりあえず右側ブロックの左に位置した時の座標を算出 } if(wall((blx_test)/wpx, cy) = 0) or (wall((blx_test+blsize-1)/wpx, cy) = 0){//横に移動しただけじゃ接触してる blx = 1.0*blx_test+wx //とりあえず算出しといた座標からスクロール分を省いてスクリーン座標で使用 bly = 1.0*bly_test+wy //上下に移動した時判定で算出して持ち越した座標からスクロール分を省いてスクリーン座標で使用 }else{//横に移動すれば接触しないのでblx_testを実際の座標にする blx = 1.0*blx_test+wx//とりあえず算出しといた座標からスクロール分を省いてスクリーン座標で使用 } break } loop } } //足元チェック if bly<(y2-blsize) {//マップ配列を超えていないので足元チェック wx_blx=-wx+blx wy_bly=-wy+bly if(wall(wx_blx/wpx, int(wy_bly+blsize)/wpy) = 0) or (wall(int(wx_blx+blhalf)/wpx, int(wy_bly+blsize)/wpy) = 0) or (wall(int(wx_blx+blsize-1)/wpx, int(wy_bly+blsize)/wpy) = 0) { //足元にブロックがあった IsBallJumping = 0 bly = 1.0*wy + (int(wy_bly+blsize)/wpy)*wpy-blsize }else{//足元にブロックが無かった IsBallJumping = 1 } }else{//マップ配列を超えてるので画面下に着地したとして処理 bly=1.0*y2-blsize IsBallJumping = 0 } bl_headx = blx+blhalf bl_heady = bly ; ボールを表示 pos blx,bly:color 255,255,255 font msgothic,blsize mes "●" pos 0,20:color 255,255,255 mes "x_head:"+bl_headx pos 0,40:color 255,255,255 mes "y_head:"+bl_heady pos 0,60:color 255,255,0 mes "Scrollx:"+Scrollx mes "Scrolly:"+Scrolly mes "ワールドX座標:"+int(blx-wx) mes "ワールドY座標:"+int(bly-wy) redraw 1 await 16 goto *main *gameover objsize 180,32 pos 150,330:button "終わり",*owari stop *owari end



暇人

リンク

2014/3/5(Wed) 00:30:13|NO.60461

>dir= (blx<blx_old)*1 or (blx>blx_old)*4

(blx<blx_old)*1で前回の座標(blx_old)より今回の座標(blx)が小さければ1
(blx>blx_old)*4で前回の座標(blx_old)より今回の座標(blx)が大きければ4
なので、結果が1なら左、4なら右に移動してる事になる

>dir|= (bly<bly_old)*2 or (bly>bly_old)*8
こっちはY座標で同じ事をやってて、上に動いてたら2、下に動いてたら8になる
dir|= の | は or と同じ意味

この1,2,4,8がstickの方向キー情報と同じような意味になってるって事
1なら左
3なら左上に移動してる事になる



暇人

リンク

2014/3/6(Thu) 01:37:00|NO.60475

NO.60460のはシューティングとかのキャラはスクリーン座標に張り付いて
マップスクロールにキャラは影響受けないようなゲームに向いてる気がする
キャラの方をスクロールに合わせる感じ

こっちはキャラをマップに貼り付けて、スクリーンに収まる部分を描画処理する感じ

// ■重力加速度を「α_G」 // ■「キャラvy」を「vy_Char」 x1=0.0:y1=0.0 ; 画面左上の座標 x2=480.0:y2=480.0 ; 画面右下の座標 scntx=2 //横の画面数 scnty=2 //縦の画面数 max_srx=(scntx-1)*x2 //横の最大スクロール値 max_sry=(scnty-1)*y2 //縦の最大スクロール値 Scrollx=0.0 //スクロール値(これを整数化してwxに入れる) Scrolly=0.0 //スクロール値 map_sx=x2*scntx //マップサイズ map_sy=y2*scnty clrflag=0 ; クリアフラグ #define α_G 0.98 //重力加速度 blsize=16.0 ; ボールのサイズ blspd=5.0 ; ボールのスピード vy_Char = 0.0 //キャラの速度のy成分 blx=240.0:bly=300.0 ; ボールのワールド座標 bpx=2.0:bpy=2.0 ; XY方向のボール座標加算値 bk=0 ; ブロックを崩すフラグ(1=崩す) mblsize=-blsize;ボール一点座標? IsBallJumping = 0 //ボールの滞空フラグ(0,1)=(false,true) blhalf=blsize/2//ボールの中心? wpx=10.0:wpy=10.0 ; ブロック1個あたりのサイズ wx=0 :wy=0 ; ブロックの表示開始位置(左上)[blx-wxでスクリーン座標になる] blnum_x=x2*scntx/wpx //ブロックのx方向の個数 blnum_y=y2*scnty/wpy //〃y〃 wsx=blnum_x:wsy=blnum_y ; ブロックの配置数(X,Y) //スクロール開始位置 srst_L=x2/2-wpx*5 //左スクロール開始位置 srst_R=x2/2 //右スクロール開始位置 srst_U=y2-wpy*18 //上スクロール開始位置 srst_D=y2-wpy*13 //下スクロール開始位置 //colxyにボールの周囲の座標を0〜7に代入(ブロックよりボールの判定が大きいので一つの判定がブロックの判定以下になるよいに分割して8方向で判定) //0 1 2 //0がボールの左上、2が右上の位置にあるブロックと判定するための座標 //7 * 3 //6 5 4 colx=0,int(blhalf),int(blsize)-1,int(blsize)-1,int(blsize)-1,int(blhalf),0,0//サイズから-1してるのはサイズ16は座標で0〜15になるので coly=0,0,0,int(blhalf),int(blsize)-1,int(blsize)-1,int(blsize)-1,int(blhalf) dim wall,wsx,wsy ; 0=表示、1=表示しない ;< ブロックの存在の設定 > //適当にブロック配置 randomize 123 repeat 40 cnty = cnt repeat blnum_x wall(cnt,cnty) = rnd(100)<98 loop loop repeat blnum_y-40,40 cnty = cnt repeat blnum_x wall(cnt,cnty) = rnd(100)>45 loop loop screen 0,x2,y2 title "キャラ移動" cls 4 *main redraw 0 gradf 0,0,x2,y2,1,0,128 ; 画面クリア /////////////////////////////////// //////矢印でブロック配置/////////// /////////////////////////////////// //set_bl でブロック座標指定してブロックを配置(スクリーン座標じゃなくグリッド座標に変更) getkey cleak_R,39//右 getkey cleak_L,37//左 getkey cleak_UP,38 getkey cleak_DOWN,40 getkey item_1,49:if item_1=1:item=0 : title "item="+item getkey item_2,50:if item_2=1:item=1 : title "item="+item bl_setf=cleak_L | cleak_R | cleak_UP | cleak_DOWN if cleak_L and blx<wpx {bl_setf=0} //マップの左端ならブロック設置キャンセル if cleak_R and blx>(map_sx-blsize-wpx) {bl_setf=0} //マップの右端ならブロック設置キャンセル if cleak_UP and bly<wpy {bl_setf=0} if cleak_DOWN and bly>(map_sx-blsize-wpy) {bl_setf=0} if bl_setf {//ブロック配置 if (cleak_L or cleak_R ) {//左右の位置設定 if cleak_L {set_blx=int(blx-wpx+1)/wpx}else{set_blx=int(blx+blsize-1)/wpx+1} }else{//X座標はボールの中央に設定 set_blx=int(blx+blhalf)/wpx } if (cleak_UP or cleak_DOWN ) {//上下の位置設定 if cleak_UP {//上の位置設定 if (cleak_L or cleak_R ) {set_bly=int(bly)/wpy}else{set_bly=int(bly-wpy)/wpy}//左右入力がある時と無い時で位置を変える }else{//ボール下のグリッド座標 set_bly=int(bly+blsize-1)/wpy+1 } }else{//左右入力があるときのY座標はボールの下部と重なるグリッド座標 set_bly=int(bly+blsize-1)/wpy } wall(set_blx,set_bly) = item } ; ボール : X方向の移動 //stick key,15 //(=1+2+4+8) blx_old=blx //前回のワールド座標を保存 bly_old=bly //左移動 getkey A_move,65 if A_move=1 {blx-bpx}//bpxは進行速度 //右移動 getkey D_move,68 if D_move=1 {blx+bpx} //スペースキーでジャンプ getkey spase_jump,32//スペースキー if spase_jump=1 and IsBallJumping=0{ IsBallJumping=1//衝突判定前に上下移動させるのでフラグセット vy_Char=-8.0-α_G } //< 力学処理 > ;< 速度処理 > if IsBallJumping = 0 { ;接地しているならば vy_Char = 0.0 } else { ;接地していないならば vy_Char + α_G vy_Char=limitf(vy_Char,-wpy*3,wpy*2) //最大速度をブロックサイズ以内に設定(超えるとブロックを飛び越す場合がある) } ;< 移動処理 > bly + vy_Char //map離脱制御 if blx<x1 :blx=x1 if blx>=(map_sx-blsize): blx=map_sx-blsize if bly<y1 :bly=y1 if bly>=(map_sx-blsize): bly=map_sx-blsize //< ボールの衝突判定&移動 > //stickのと同じような感じでdirに移動方向を代入 dir= (blx<blx_old)*1 or (blx>blx_old)*4 dir|= (bly<bly_old)*2 or (bly>bly_old)*8 if dir {//移動してる if dir&10 {//上下に移動した repeat 8 cx=(colx(cnt)+blx)/wpx cy=(coly(cnt)+bly)/wpy if(wall(cx, cy) = 0){//ボールが接触 if dir&8 {//下に移動中 if (int(bly_old+blsize-1)/wpy) < cy {//前回の座標が接触したブロックより上ならボールの下が当たった bly_test = cy*wpy-blsize//とりあえず下のブロックに載った時の座標を算出 if(wall(cx, (bly_test+blsize-1)/wpy) = 0) or (wall(cx, bly_test/wpy) = 0){//ブロックの上に動かしてもまだ接触してる //bly_testを次の左右に移動した時の当たり判定に持ち越し }else{//上に動かしたら接触しなかった bly=1.0*bly_test //とりあえず算出しといた座標を実際の座標に使用 } break } }else{//上に移動中 if (int(bly_old)/wpy) > cy { bly_test = cy*wpy+wpy//とりあえず上のブロックの下の座標を算出 if(wall(cx, bly_test/wpy) = 0) or (wall(cx, (bly_test+blsize-1)/wpy) = 0){//ブロックの下に動かしてもまだ接触してる //bly_testを次の左右に移動した時の当たり判定に持ち越し }else{//下に動かしたら接触しなかった bly=1.0*bly_test //とりあえず算出しといた座標を実際の座標に使用 } break } } } loop } if dir&5 {//左右に移動した repeat 8 cx=(colx(cnt)+blx)/wpx cy=(coly(cnt)+bly)/wpy //Y座標はXを6個ずらして使用 if(wall(cx, cy) = 0){//ボールが接触 if dir&1 {//左に移動中 blx_test = cx*wpx+wpx//とりあえず左側ブロックの右に位置した時の座標を算出 }else{//右に移動中 blx_test = cx*wpx-blsize//とりあえず右側ブロックの左に位置した時の座標を算出 } if(wall((blx_test)/wpx, cy) = 0) or (wall((blx_test+blsize-1)/wpx, cy) = 0){//横に動かしただけじゃ接触してる blx=1.0*blx_test //とりあえず算出しといた座標を実際の座標に使用 bly=1.0*bly_test //上下に移動した時に持ち越した座標を実際の座標に使用 }else{//横に移動すれば接触しないのでblx_testを実際の座標にする blx=1.0*blx_test } break } loop } } //足元チェック if bly<(map_sx-blsize) {//マップ配列を超えていないので足元チェック if(wall(int(blx)/wpx, int(bly+blsize)/wpy) = 0) or (wall(int(blx+blhalf)/wpx, int(bly+blsize)/wpy) = 0) or (wall(int(blx+blsize-1)/wpx, int(bly+blsize)/wpy) = 0) { //足元にブロックがあった IsBallJumping = 0 bly = 1.0*(int(bly+blsize)/wpy)*wpy-blsize }else{//足元にブロックが無かった IsBallJumping = 1 } }else{//マップ配列を超えてるので画面下に着地したとして処理 bly=map_sx-blsize IsBallJumping = 0 } //ボールの位置を機順にスクロールさせるのでボールの位置が確定してからスクロールとマップ処理をする blctx=blx+blhalf //ボールのワールド中心座標 blcty=bly+blhalf //横方向スクロール if ((blctx-Scrollx)<srst_L) and (Scrollx>0.0) {Scrollx=blctx-srst_L}//blctxとScrollxの差がsrst_Lより小さいなら左スクロール(Scrollxが0なら位置に関係なくボール移動) if ((blctx-Scrollx)>srst_R) and (Scrollx<max_srx) {Scrollx=blctx-srst_R}//blctxとScrollxの差がsrst_Rより大きいなら右スクロール(Scrollxがmax_srx以上なら位置に関係なくボール移動) //縦方向スクロール if ((blcty-Scrolly)>srst_D) and (Scrolly<max_sry) {Scrolly=blcty-srst_D} if ((blcty-Scrolly)<srst_U) and (Scrolly>0.0) {Scrolly=blcty-srst_U} Scrollx=limitf(Scrollx,0.0,max_srx) //スクロール値を制限 wx=int(Scrollx) //スクロール値を整数化して実際の計算に使用 Scrolly=limitf(Scrolly,0.0,max_sry) //スクロール値を制限 wy=int(Scrolly) //< ブロックの描画 > index_x=wx/wpx //スクロール分をrepeat開始位置にする index_y=wy/wpy blcntx=wsx/scntx //一画面分のブロック数 if (blcntx+index_x)<wsx {blcntx+1}//スクロールするには画面分+1が必要だが、スクロール最後でマップ配列を超えないように制御 blcnty=wsy/scnty //一画面分のブロック数 if (blcnty+index_y)<wsy {blcnty+1}//スクロールするには画面分+1が必要だが、スクロール最後でマップ配列を超えないように制御 repeat blcnty,index_y cy = cnt y_blp = cy*wpy-wy //cy*wpyはワールド座標になるのでスクロール分を省いてスクリーン座標にする x_blp = index_x*wpx-wx //横方向の描画開始位置 color 200,200,200 repeat blcntx,index_x if wall(cnt,cy) = 0 { ;ブロックが存在するならば ;< 描画 > boxf x_blp,y_blp ,x_blp+wpx-2.0,y_blp+wpy-2.0 } x_blp+wpx //1ブロック移動 loop loop bl_headx = (blx+blhalf)-wx //スクリーン座標 bl_heady = bly-wy ; ボールを表示 pos blx-wx,bly-wy:color 255,255,255 font msgothic,blsize mes "●" pos 0,20:color 255,255,255 mes "x_head:"+bl_headx pos 0,40:color 255,255,255 mes "y_head:"+bl_heady pos 0,60:color 255,255,0 mes "Scrollx:"+Scrollx mes "Scrolly:"+Scrolly mes "ワールドX座標:"+blx mes "ワールドY座標:"+bly //スクロールする境界線を表示 pos srst_L,srst_U :color 0,255,0 line srst_R,srst_U line srst_R,srst_D line srst_L,srst_D line srst_L,srst_U redraw 1 await 16 goto *main



暇人

リンク

2014/3/6(Thu) 02:21:18|NO.60476

実験して戻すの忘れてた
> vy_Char=limitf(vy_Char,-wpy*3,wpy*2) //最大速度をブロックサイズ以内に設定(超えると
これを

vy_Char=limitf(vy_Char,-wpy,wpy) //最大速度をブロックサイズ以内に設定(超えると
に修正



暇人

リンク

2014/3/7(Fri) 23:07:34|NO.60503

もっと簡単な方法もあるNO.60475のを、その方法にすると

> //左移動
> getkey A_move,65
> if A_move=1 {blx-bpx}//bpxは進行速度
> //右移動
> getkey D_move,68
> if D_move=1 {blx+bpx}
これを

//左移動 getkey A_move,65 if A_move=1 { blx-bpx //bpxは進行速度 //ボールの左側と接触してるか判定 //int(blx)/wpxで横方向のマップ配列インデック(グリッド座標)になる //wall(int(blx)/wpx, int(bly)/wpy)が左上、wall(int(blx)/wpx,int(bly+blhalf)/wpy)が左中、wall(int(blx)/wpx,int(bly+blsize-1)/wpy)が左下 if (wall(int(blx)/wpx,int(bly)/wpy) = 0) or (wall(int(blx)/wpx,int(bly+blhalf)/wpy) = 0) or (wall(int(blx)/wpx,int(bly+blsize-1)/wpy) = 0) { //int(blx/wpx)でグリッド座標にしてブロックサイズを掛ける事でワールドマップ上の座標になる blx=1.0*int(blx/wpx)*wpx+wpx //当たったブロックの右側にボールを移動 } } //右移動 getkey D_move,68 if D_move=1 { blx+bpx //ボールの右側と接触してるか判定 if (wall(int(blx+blsize-1)/wpx, int(bly)/wpy) = 0) or (wall(int(blx+blsize-1)/wpx, int(bly+blhalf)/wpy) = 0) or (wall(int(blx+blsize-1)/wpx, int(bly+blsize-1)/wpy) = 0) { blx=1.0*int((blx+blsize-1)/wpx)*wpx-blsize//当たったブロックの左側にボールを移動 } }
に置換え

>//< ボールの衝突判定&移動 >
から
>//足元チェック
までの判定処理を

//< 縦方向のボールの衝突判定&移動 > //頭上チェック if (bly<bly_old) { //ボールが上に移動してたらボールの上側と接触してるか判定 if(wall(int(blx)/wpx, int(bly)/wpy) = 0) or (wall(int(blx+blhalf)/wpx, int(bly)/wpy) = 0) or (wall(int(blx+blsize-1)/wpx, int(bly)/wpy) = 0) { bly = 1.0*(int(bly)/wpy)*wpy+wpy } }
と置換え

この方法はNO.60475のと違い横と縦を別々に動かして判定をしてる
仕組みは簡単になるが、弱点が出来る
弱点とは、1キャラ分ぐらいの空間が空いてる横穴に入り難くなる事
ジャンプや落下中に横穴に入れない時があると不味い場合は使えない

操作キャラには、あまりお勧めできない感じ
敵キャラ移動時に簡単な判定で済ませたい時には良いかも



べりー

リンク

2014/3/10(Mon) 13:34:12|NO.60544

すみません、また体調を崩してしまい手をつけれませんでした・・・

拝見させていただきます。



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