|
|
2015/7/10(Fri) 22:10:59|NO.70030
screen 0,800,500,0 :cls 4
repeat
redraw 0
color 255,255,255
boxf
// 斜線
color 0,0,0
line 300,250,500,100
// 縦線
line 000,200,400,200
// 横線
line 200,100,200,400
pget charx+16,chary+33
r=ginfo(16) : g=ginfo(17) : b=ginfo(18)
pos 0,0:color 0,0,0
mes "R:"+str(r)+"G:"+str(g)+"B:"+str(b)
getkey lk,37
getkey rk,39
if rk{
charx+3
}
if lk{
charx-3
}
//スペースキーでジャンプ
getkey key,32//スペースキー
if key=1 and jump=0{
jump=1
chary-50
}
color 255,0,0
boxf charx,chary,charx+32,chary+32
if r=255 and g=255 and b=255{
chary+1
}
if r=0 and g=0 and b=0{
chary-1
jump=0
}
redraw
wait 1
loop
[操作方法]
→ :右移動
← :左移動
スペース:ジャンプ(問題あり)
上記のプログラムで一応黒いところが床という設定で動けているのですが、
・重力がおかしい
・地面ではずっとキャラがガタガタしている
・壁を貫通
・斜めを上がれない
・ジャンプがおかしい
などと問題が多すぎるのですが、どうすればいいですか?
漠然としていてすいません。
お願いします!!
|
|
2015/7/11(Sat) 13:05:56|NO.70040
多少修正。斜め上がれないのは判定の問題。
screen 0,800,500,0 :cls 4
repeat
redraw 0
color 255,255,255
boxf
// 斜線
color 0,0,0
line 300,250,500,100
line 301,250,501,100
// 縦線
line 000,200,400,200
// 横線
line 200,100,200,400
pget charx+16,chary+33
r=ginfo(16) : g=ginfo(17) : b=ginfo(18)
pos 0,0:color 0,0,0
mes "R:"+str(r)+"G:"+str(g)+"B:"+str(b)
getkey lk,37
getkey rk,39
if rk{
charx+3
}
if lk{
charx-3
}
//スペースキーでジャンプ
getkey key,32//スペースキー
if key=1 and keyBac=0{
上昇フラグ=1
上昇カウント=0
}
if 上昇フラグ=1:{
上昇カウント+1
chary-10//上昇速度
if 上昇カウント=5:上昇フラグ=0
}
color 255,0,0
boxf charx,chary,charx+32,chary+32
if r=255 and g=255 and b=255 and 上昇フラグ=0{
chary+1
}
keyBac=key
redraw
wait 1
loop
|
|
2015/7/11(Sat) 15:06:24|NO.70045
床と判定される範囲が狭すぎるのが原因です。
横線の部分をこの様にすることで、解決できます。
// 縦線
boxf 0,200,800,500
|
|
2015/7/11(Sat) 16:06:04|NO.70046
おお!
できました!
でも、そうすると、ジャンプの着地点の座標が毎回変わってしまいます。
回避はできないのですかね?
|
|
2015/7/11(Sat) 17:17:55|NO.70051
あまりこういうことをすると、他の人に怒られそうですけど、今後の勉強になればと思い、
少々、リファクタリングをば。
まず、repeat-loop の最初から最後までを redraw でくくるのは余りおすすめできません。
難しい考え方ですけど、できるだけ処理は分けたほうが、
バグの早期発見などにも役に立ちますし、
何よりも処理を書き足すときにラクです。
screen 0,800,500,0 :cls 4
repeat
// 移動判定
getkey lk, 37
getkey rk, 39
if rk :charx += 3
if lk :charx -= 3
// 上昇判定
getkey key, 32 // スペースキー
if 1 == key and 0 == keyBac {
// スペースキーでジャンプ
上昇フラグ = 1
上昇カウント = 0
}
if 1 == 上昇フラグ {
上昇カウント++
chary -= 10 // 上昇速度
if 5 == 上昇カウント :上昇フラグ = 0
}
keyBac = key
// 下降判定
if 0 == 上昇フラグ {
// 下降
repeat 10 // ここの数字が下降速度
pget charx+16, chary+33
r=ginfo_r :g=ginfo_g :b=ginfo_b
if 255 != r or 255 != g or 255 != b {
break
}
chary++
loop
}
// 描画
redraw 0
// 背景
color 255,255,255
boxf
pos :color
mes "R:"+str(r)+"G:"+str(g)+"B:"+str(b)
// 斜線
color
line 300,250,500,100
line 301,250,501,100
// 縦線
line 000,200,400,200
// 横線
line 200,100,200,400
// 移動対象
color 255
boxf charx, chary, charx+32, chary+32
redraw
wait 1
loop
参考になるといいのですけど……
|
|
2015/7/11(Sat) 17:23:44|NO.70052
補足ですけど、
斜め上がりたいのなら
if rk :charx += 3
if lk :charx -= 3
ここらへんの処理を変更するとできると思います。
|
|
2015/7/11(Sat) 20:45:24|NO.70054
具体的にどのように変えればよいのでしょうか?
もう1つif文を作るのでしょうか?
教えてください!!
|
|
2015/7/12(Sun) 01:39:28|NO.70061
自分が作ったプログラムの動きは完全に把握できていますか?
|
|
2015/7/12(Sun) 14:31:21|NO.70064
そうですね、スペースさんの言うとおり、
なぜ、左右に進むと上がれないかを調べるとその対処法もわかると思います。
|
|
2015/7/12(Sun) 15:20:57|NO.70066
pget charx+18, chary+33
r=ginfo_r :g=ginfo_g :b=ginfo_b
if r=0{
chary-1
}
これを追加して、斜面を太くすれば、ある程度の傾きまでは上るのですが、
45°とかになると上がらないで貫通します。
どうすればいいのでしょうか?
|
|
2015/7/12(Sun) 18:01:27|NO.70072
その当たり判定でゲームを作ることは出来なくはないですが、
初心者にはこっちの処理方法の方がやりやすいと思う。
30分ほどで作った物なのでバグあるかもしれません。
winX=200
winY=200
ブロック数x=10
ブロック数y=10
ブロックサイズx=double(winx)/double(ブロック数y)
ブロックサイズy=double(winy)/double(ブロック数y)
Screen 0,winX,winY
dim マップ,ブロック数x,ブロック数y
//0が空宙、1が地面、2が壁
マップ.0.0=2,2,2,2,2,2,2,2,2,2
マップ.0.1=2,0,0,0,0,0,0,0,2,2
マップ.0.2=2,0,0,0,0,0,0,1,1,2
マップ.0.3=2,0,0,0,0,0,1,1,1,2
マップ.0.4=2,0,0,0,1,1,1,1,1,2
マップ.0.5=2,0,0,0,0,0,0,0,0,2
マップ.0.6=2,0,0,0,0,0,0,0,0,2
マップ.0.7=2,0,0,0,2,1,1,1,1,2
マップ.0.8=2,0,0,0,2,0,0,0,0,2
マップ.0.9=2,1,1,1,1,1,1,1,1,2
CpX=1:CpY=1//キャラの位置。キャラクターポジションの略
repeat//メインループ
getkey 左key,37//キー入力チェック。上キーでジャンプもいいけど今回はスペースでジャンプ
getkey 右key,39
getkey 上key,38
getkey 下key,40
getkey スペースkey,32
//現在地のマップの状況を判定
移動済みフラグ=0
if マップ.CpX.Cpy=0:{//次キャラが空宙に居る時
if マップ.CpX.(Cpy+1)=0{//かつ下も空宙の時
if ジャンプフラグ=0:Cpy+1//下に移動(重力)
}
if 右key=1:{//右に移動しようとした時
if マップ.(CpX+1).Cpy=0 and 移動済みフラグ=0:CpX+1:移動済みフラグ=1//右が空宙=何もなかった時
if マップ.(CpX+1).Cpy=1 and 移動済みフラグ=0:CpX+1:CpY-1:移動済みフラグ=1//右に地面があった時。
if マップ.(CpX+1).Cpy=2 and 移動済みフラグ=0:移動済みフラグ=1//右が壁だった時。今回は特に処理無し
}
if 左key=1:{//左に移動しようとした時
if マップ.(CpX-1).Cpy=0 and 移動済みフラグ=0:CpX-1:移動済みフラグ=1//右が空宙=何もなかった時
if マップ.(CpX-1).Cpy=1 and 移動済みフラグ=0:CpX-1:CpY-1:移動済みフラグ=1//右に地面があった時。
if マップ.(CpX-1).Cpy=2 and 移動済みフラグ=0:移動済みフラグ=1//右が壁だった時。今回は特に処理無し
}
if スペースkey=1 and スペースkeyBac=0:ジャンプフラグ=1
if ジャンプフラグ=1:{
if マップ.CpX.(Cpy-1)=0:Cpy-1//上が空宙である事を判定
ジャンプカウント+1
if ジャンプカウント=4:ジャンプフラグ=0:ジャンプカウント=0//ジャンプの高さ
}
}
redraw 0
Color 255,255,255:boxf//画面初期化
repeat ブロック数x//空宙・地面・壁をわかりやすく描画
ct=cnt
repeat ブロック数y
if マップ.ct.cnt=0:Color 255,200,200
if マップ.ct.cnt=1:Color 200,255,200
if マップ.ct.cnt=2:Color 200,200,50
pos ct*ブロックサイズx,cnt*ブロックサイズy:mes "■"
loop
loop
pos Cpx*ブロックサイズx,Cpy*ブロックサイズy:Color 0,0,255:mes "●"//次キャラを●で描画
redraw 1
await 100//await 17-(cnt\3=0)//60fpsを維持
左keyBac=左key
右keyBac=右key
上keyBac=上key
下keyBac=下key
スペースkeyBac=スペースkey
loop
| |
|
2015/7/12(Sun) 19:49:33|NO.70074
ふと思ったんですけど、
hspで日本語の変数名って使えるんですか?
使えたとしても推奨されるものではないと思いますが
|
|
2015/7/12(Sun) 20:05:59|NO.70077
一応日本語の変数名も使えますけど、なるべくローマ字を使ったほうがよいと思います。
ですが、変に分かりづらくなるくらいなら日本語でもかまわないと私は思います。
burokkusuux = 0
と書くくらいなら
ブロック数x = 0
のほうがいいです
|
|
2015/7/12(Sun) 20:09:34|NO.70078
なるべくこのままの方法にしたいのですが、、、
|
|
2015/7/12(Sun) 20:17:12|NO.70080
わからないなら徐々に覚えていくでいいと思います。
たいていexeにする際に変数名なんてどっかに消えてしまいますw
|
|
2015/7/13(Mon) 23:44:22|NO.70113
点の色で判定は、移動経路を縦横1ドット毎に、接触するまで繰り返す事が必要(と言うか結局一番楽)。
通過できない部分を、塗りつぶして、移動先の点だけ判定しても結局接触しなくなるところを、探す必要が出るし
壁の厚さを、速度が上回れば通り抜けてしまう
screen 0,800,500,0 :cls 4
csx=32 //キャラサイズ
csy=32
ccx=csx-1 //キャラコリジョンサイズ(当り判定は0〜サイズなので32にすると範囲33になる)
ccy=csy-1
charx=10
charx=10
repeat
redraw 0
color 255,255,255
boxf
// 斜線
color 0,0,0
line 300,250,500,100
// 縦線
line 000,200,400,200
// 横線
line 200,100,200,400
line 550,100,500,100
line 550,100,600,200
line 600,200,800,250
line 200,100,300,100
line 200,100,300,200
line 200,200,300,100
getkey lk,37
getkey rk,39
char_vx=0
if rk {char_vx+3} //移動速度
if lk {char_vx-3}
if jump { //ジャンプ中なら
if char_vy<25 {char_vy+1}//25を限度に速度加算(最初はマイナスなので徐々に減速し頂点で逆転する)
}
//スペースキーでジャンプ
key_bak=key
getkey key,32//スペースキー
if key=1 and jump=0 {jump=1 : char_vy=-16}//ジャンプフラグとジャンプ速度をセット
nx=abs(char_vx) //移動速度を判定ループ総回数にする
ny=abs(char_vy)
_charx=charx+ccx/2 //判定用座標
_chary=chary+ccy
if char_vx > 0 {svx=1}else{svx=-1} //判定ループ一回の移動量
if char_vy >= 0 {svy=1}else{svy=-1}
if nx>ny {//横のループ回数のほうが多い
if ny {
vx=nx/ny //縦に1ドット進んだ時の横の判定ループ回数
repeat ny+((nx\vx)>0) //余りがあるなら1回分加算
repeat limit(nx,0,vx)
pget _charx+svx,_chary //仮座標で色取得
if ginfo_r | ginfo_g | ginfo_b {
_charx+svx
}else{break}//接触無しなので実際に移動
loop
if ny=cnt {break} //1回分追加されたのは横移動のためなので縦移動は終了
nx-vx //判定ループ総回数から今回の判定ループ回数を減算して残りを次のループ回数にする
pget _charx,_chary+svy //仮座標で色取得
if (ginfo_r | ginfo_g | ginfo_b) {_chary+svy}//接触無しなので実際に移動
loop
}else{//縦移動無し(傾斜対応)
repeat nx
pget _charx+svx,_chary
if ginfo_r | ginfo_g | ginfo_b {
_charx+svx
}else{//横移動で接触した
pget _charx,_chary-1 //真上の色取得
if (ginfo_r | ginfo_g | ginfo_b)=0 {break}//真上に天井があるので抜ける
_chary_bak=_chary //上れなかったら戻せるように
repeat 2 //縦2ドットまで上る
_chary-- //とりあえず上に移動
pget _charx+svx,_chary //上に移動した場合の色を取得
if ginfo_r | ginfo_g | ginfo_b {//接触無しなので
ystop=0 //上りストップフラグクリアして抜ける
break
}else{ystop++} //上がっても接触してるので上りストップフラグセット
loop
if ystop {_chary=_chary_bak:ystop=0:break}//上っても接触してるのでY座標を戻して横移動を抜ける
_charx+svx
}
//下り坂を地面として対応させる(45度以上の傾斜は落下になる)
if jump=0 {//地上にいる
pget _charx,_chary+1
if ginfo_r | ginfo_g | ginfo_b {_chary+1}//接触して無いなら下に移動
}
loop
}
}else{//縦のループ回数のほうが多い
if ny {
if nx {
vy=ny/nx
repeat nx+((ny\vy)>0)
repeat limit(ny,0,vy)
pget _charx,_chary+svy
if ginfo_r | ginfo_g | ginfo_b {_chary+svy}else{break}
loop
if nx=cnt {break}
ny-vy
pget _charx+svx,_chary
if ginfo_r | ginfo_g | ginfo_b {_charx+svx}//else{if svy<0 {char_vy=0:break}}
loop
}else{//横移動無し
repeat ny
pget _charx,_chary+svy
if ginfo_r | ginfo_g | ginfo_b {_chary+svy}else{break}
loop
}
}
}
if svy>0 {//落下か縦移動無し
pget _charx,_chary+1 //足元の座標の色取得
if ginfo_r | ginfo_g | ginfo_b {//無いのでジャンプ中フラグセット
jump=1
}else{//接触したのでジャンプ中フラグとジャンプ速度クリア
jump=0
char_vy=0
}
}else{//上昇中
pget _charx,_chary-1 //真上の色を取得
if (ginfo_r | ginfo_g | ginfo_b)=0 {char_vy=0}//天井が有るのでジャンプ速度クリア
}
charx=_charx-ccx/2
chary=_chary-ccy
color 255,0,0
gradf charx,chary,csx,csy //boxfはサイズと思って座標を指定すると1ドット大きくなってドット単位の判定してる場合見た目がややこしいのでgradfを使用
redraw
await 16
loop
足元1ドットしか判定してないので頭上とかキャラの幅に合う壁の判定するなら
更に判定回数は増える
| |
|
2015/7/14(Tue) 01:36:40|NO.70115
暇人さん、あなたは天才なんですか!?!?
僕の持っていた疑問が完全にすべて解決されました!!
ほかの方たちも本当にありがとうございました!!
またよろしくお願いします!!
|
|
2015/7/14(Tue) 01:42:37|NO.70117
メカニズムのわかりやすい説明もありがとうございます!!
きちんと理解していきたいと思います!
これからもプログラミングがんばります!!
|
|
2015/7/23(Thu) 00:44:01|NO.70201
モジュール内の命令として作れば
複数キャラにも間単に対応できる
#module
#deffunc bgcol var charx,var chary,var char_vx,var char_vy,var jump,int ccx,int ccy
nx=abs((charx+char_vx)-charx) //移動速度を判定ループ総回数にする
ny=abs((chary+char_vy)-chary)
_charx=(charx+ccx/2) //判定用座標
_chary=(chary+ccy)
if char_vx >= 0 {svx=1}else{svx=-1} //判定ループ一回の移動量
if char_vy >= 0 {svy=1}else{svy=-1}
if nx>ny {//横のループ回数のほうが多い
if ny {
vx=nx/ny //縦に1ドット進んだ時の横の判定ループ回数
repeat ny+((nx\vx)>0) //余りがあるなら1回分加算
repeat limit(nx,0,vx)
pget _charx+svx,_chary //仮座標で色取得
if ginfo_r | ginfo_g | ginfo_b {
_charx+svx
}else{break}//接触無しなので実際に移動
loop
if ny=cnt {break} //1回分追加されたのは横移動のためなので縦移動は終了
nx-vx //判定ループ総回数から今回の判定ループ回数を減算して残りを次のループ回数にする
pget _charx,_chary+svy //仮座標で色取得
if (ginfo_r | ginfo_g | ginfo_b) {_chary+svy}//接触無しなので実際に移動
loop
}else{//縦移動無し(傾斜対応)
repeat nx
pget _charx+svx,_chary
if ginfo_r | ginfo_g | ginfo_b {
_charx+svx
}else{//横移動で接触した
pget _charx,_chary-1 //真上の色取得
if (ginfo_r | ginfo_g | ginfo_b)=0 {break}//真上に天井があるので抜ける
_chary_bak=_chary //上れなかったら戻せるように
repeat 2 //縦2ドットまで上る
_chary-- //とりあえず上に移動
pget _charx+svx,_chary //上に移動した場合の色を取得
if ginfo_r | ginfo_g | ginfo_b {//接触無しなので
ystop=0 //上りストップフラグクリアして抜ける
break
}else{ystop++} //上がっても接触してるので上りストップフラグセット
loop
if ystop {_chary=_chary_bak:ystop=0:break}//上っても接触してるのでY座標を戻して横移動を抜ける
_charx+svx
}
//下り坂を地面として対応させる(45度以上の傾斜は落下になる)
if jump=0 {//地上にいる
pget _charx,_chary+1
if ginfo_r | ginfo_g | ginfo_b {_chary+1}//接触して無いなら下に移動
}
loop
}
}else{//縦のループ回数のほうが多い
if ny {
if nx {
vy=ny/nx
repeat nx+((ny\vy)>0)
repeat limit(ny,0,vy)
pget _charx,_chary+svy
if ginfo_r | ginfo_g | ginfo_b {_chary+svy}else{break}
loop
if nx=cnt {break}
ny-vy
pget _charx+svx,_chary
if ginfo_r | ginfo_g | ginfo_b {_charx+svx}//else{if svy<0 {char_vy=0:break}}
loop
}else{//横移動無し
repeat ny
pget _charx,_chary+svy
if ginfo_r | ginfo_g | ginfo_b {_chary+svy}else{break}
loop
}
}
}
if svy>0 {//落下か縦移動無し
pget _charx,_chary+1 //足元の座標の色取得
if ginfo_r | ginfo_g | ginfo_b {//無いのでジャンプ中フラグセット
jump=1
}else{//接触したのでジャンプ中フラグとジャンプ速度クリア
jump=0
char_vy=0
}
}else{//上昇中
pget _charx,_chary-1 //真上の色を取得
if (ginfo_r | ginfo_g | ginfo_b)=0 {char_vy=0}//天井が有るのでジャンプ速度クリア
}
charx=_charx-ccx/2
chary=_chary-ccy
return
#global
screen 0,800,500,0 :cls 4
csx=32 //キャラサイズ
csy=32
ccx=csx-1 //キャラコリジョンサイズ(当り判定は0〜サイズなので32にすると範囲33になる)
ccy=csy-1
charx=10.0
chary=10.0
esx=32
esy=32
ecx=esx-1
ecy=esy-1
enemy_max=10 //敵の数
dim enemyx,enemy_max
dim enemyy,enemy_max
dim enemy_vx,enemy_max
dim enemy_vy,enemy_max
dim enemy_jump,enemy_max
repeat
redraw 0
color 255,255,255
boxf
// 斜線
color 0,0,0
line 300,250,500,100
// 縦線
line 000,200,400,200
// 横線
//color 200
line 200,100,200,400
line 550,100,500,100
line 550,100,600,200
line 600,200,800,250
line 200,100,300,100
line 200,100,300,200
line 200,200,300,100
getkey lk,37
getkey rk,39
char_vx=0
if rk {char_vx=3} //移動速度
if lk {char_vx=-3}
if jump { //ジャンプ中なら
if char_vy<25 {char_vy+1}//25を限度に速度加算(最初はマイナスなので徐々に減速し頂点で逆転する)
}
//スペースキーでジャンプ
key_bak=key
getkey key,32//スペースキー
if key=1 and jump=0 {jump=1 : char_vy=-16}//ジャンプフラグとジャンプ速度をセット
repeat enemy_max
if rnd(150)=0 {enemy_vx(cnt)*-1}
if enemyx(cnt)<100 {enemy_vx(cnt)=2}
if enemyx(cnt)>ginfo_sx-100 {enemy_vx(cnt)=-2}
if enemy_jump(cnt) { //ジャンプ中なら
if enemy_vy(cnt)<25 {enemy_vy(cnt)+1}//25を限度に速度加算(最初はマイナスなので徐々に減速し頂点で逆転する)
}
if rnd(100)=0 and enemy_jump(cnt)=0 {enemy_jump(cnt)=1 : enemy_vy(cnt)=-16}//ジャンプフラグとジャンプ速度をセット
bgcol enemyx(cnt), enemyy(cnt), enemy_vx(cnt), enemy_vy(cnt), enemy_jump(cnt), ecx, ecy
loop
bgcol charx, chary, char_vx, char_vy, jump, ccx, ccy
color 128,0,128
repeat enemy_max
color 128,0,128
gradf enemyx(cnt),enemyy(cnt),esx,esy
color 0,128,0
gradf enemyx(cnt)+4,enemyy(cnt)+4,esx-8,esy-8
loop
color 255,0,0
gradf charx,chary,csx,csy //boxfはサイズと思って座標を指定すると1ドット大きくなってドット単位の判定してる場合見た目がややこしいのでgradfを使用
redraw
await 16
loop
| |
|