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