|
|
2008/12/14(Sun) 17:29:41|NO.21556
//ボールのブロックに対する当たり判定//
repeat BROYKAZU
RCNT = cnt
repeat BROXKAZU
if bro_map.cnt.RCNT = 0 : continue ;0ならブロックが存在しないのでスキップする
if((by+bsize)>=broy.cnt.RCNT) & (by<=(broy.cnt.RCNT+broysize)) & ((bx+bsize)>=brox.cnt.RCNT) & (bx<=(brox.cnt.RCNT+broxsize)) { ;ボールがブロックに当たったら
if((bbx+bsize)>=brox.cnt.RCNT) & (bbx<=(brox.cnt.RCNT+broxsize)) { ;ブロックの上か下にボールが当たった場合の処理
bmy=-bmy ;ボールの縦移動の反転
bro_map.cnt.RCNT = 0 ;当たったブロックを消す
gosub *kasan ;得点の加算
brokazu-- ;ブロックの数を一つ減らす
continue ;スキップする
}
if((bby+bsize)>=broy.cnt.RCNT) & (bby<=(broy.cnt.RCNT+broysize)) { ;ブロックの左か右にボールが当たった場合の処理
bmx=-bmx ;ボールの横移動の反転
bro_map.cnt.RCNT = 0 ;当たったブロックを消す
gosub *kasan ;得点の加算
brokazu-- ;ブロックの数を1つ減らす
continue ;スキップする
}
//端にあたったら両方反転//
bmx=-bmx
bmy=-bmy
brokazu--
bro_map.cnt.RCNT = 0 ;当たったブロックを消す
}
loop
loop
return
ブロックとボールの当たり判定がうまくいかないんですけど誰か教えていただけませんか?
横からボールが当たった時になぜかブロックを貫通してしまうんです
よろしくお願いします
|
|
2008/12/14(Sun) 19:18:16|NO.21558
前後の処理も変数の意味もわからない、スクリプトの一部分からバグを探せというのは、あまりにも無茶ですよう。
|
|
2008/12/14(Sun) 20:05:30|NO.21559
では、全て貼り付けさせていただきます
#define BROXSIZE 48 ;ブロックの横サイズ
#define BROYSIZE 20 ;ブロックの縦サイズ
#define RAKETSIZEX 80 ;ラケットの横サイズ
#define RAKETSIZEY 20 ;ラケットの縦サイズ
#define BROXKAZU 10 ;ブロックの横の数
#define BROYKAZU 8 ;ブロックの縦の数
#define BSIZE 15 ;ボールのサイズ
#define WINX 640 ;ウィンドウの横サイズ
#define WINY 480 ;ウィンドウの縦サイズ
#define mm 8 ;間隔
rx=200 ;ラケットのX座標
ry=400 ;ラケットのY座標
*stage1
//ブロックのマップ//
dim bro_map,BROXKAZU,BROYKAZU
bro_map.0.00 = 0,0,0,0,0,0,0,0,0,0
bro_map.0.01 = 0,1,2,1,2,1,2,1,2,0
bro_map.0.02 = 0,2,1,2,1,2,1,2,1,0
bro_map.0.03 = 0,1,2,1,2,1,2,1,2,0
bro_map.0.04 = 0,2,1,2,1,2,1,2,1,0
bro_map.0.05 = 0,1,2,1,2,1,2,1,2,0
bro_map.0.06 = 0,2,1,2,1,2,1,2,1,0
bro_map.0.07 = 0,1,2,1,2,1,2,1,2,0
//ブロックの配置座標の初期化//
dim BROX,BROXKAZU,BROYKAZU
dim BROY,BROXKAZU,BROYKAZU
repeat BROYKAZU
RCNT = cnt
repeat BROXKAZU
BROX.cnt.RCNT = cnt*BROXSIZE ;ブロックの左座標
BROY.cnt.RCNT = RCNT*BROYSIZE ;ブロックの上座標
brokazu++ ;ブロックの数
loop
loop
brokazu=56
screen 0,winx,winy ;ウィンドウのサイズ
*main
stick ky,$1f ;キーの情報を取得 16進数表記 「 $ 」
if ky&128 :goto *owari ;[ESC]中断チェック
redraw 0
color:boxf
gosub *blockdraw
gosub *raket
gosub *tama
gosub *clear
gosub *joho
redraw 1
await 15
goto *main
*blockdraw //ブロックの配置//
repeat BROYKAZU ;ブロックの縦の数
RCNT = cnt
repeat BROXKAZU ;ブロックの横の数
if bro_map.cnt.RCNT = 0 : continue ;0なら何もしない
if bro_map.cnt.RCNT = 1 : color 0,255,0 ;緑色のブロック
if bro_map.cnt.RCNT = 2 : color 0,0,255 ;青色のブロック
if bro_map.cnt.RCNT = 3 : color 100,100,100 : ;ねずみ色のブロック
boxf BROX.cnt.RCNT,BROY.cnt.RCNT,BROX.cnt.RCNT+BROXSIZE,BROY.cnt.RCNT+BROYSIZE ;ブロックの配置
loop
loop
return
*raket //ラケットの移動//
color 255,0,255:boxf rx,ry,rx+RAKETSIZEX,ry+RAKETSIZEY ;ラケットの描画
stick ky,21
if ky&1 : rx-raketspeed ;ラケットが左移動する
if ky&4 : rx+raketspeed ;ラケットが右移動する
if (rx<0){
rx=0
}
if (rx>(480-raketsizex)){
rx=480-raketsizex
}
if startflg=0 { ;スタートフラグが0なら
if ky&16 { ;スペースキーを押したらスタートする
startflg=1 ;スタートフラグを1にする
bx=rx + 16 ;ボールのX座標
by=380 ;ボールのY座標
bmx=5 ;ボールの横移動量
bmy=5 ;ボールの縦移動量
raketspeed=10 ;ラケットの移動量設定
}
}
return
*tama //玉の移動//
if startflg=0 : return
bbx=bx ;1つ前の玉のX座標
bby=by ;1つ前の玉のY座標
bx+bmx ;玉のX移動
by+bmy ;玉のY移動
if bx<0 : bx=0 : bmx=-bmx ;ウィンドウの一番左端にぶっかったら横移動の反転
if bx+bsize>=480 : bmx=-bmx ;ウィンドウの一番右端にぶったったら横移動の反転
if by+bsize>=480 : startflg=0 ;ウィンドウの一番下に落ちたらフラグを0にする
if by<0 : by=0 : bmy=-bmy ;ウィンドウの一番上にぶっかったら縦移動の反転
if (ry<=(by+bsize)) & ((ry+raketsizey)>by) & (rx<=(bx+bsize)) & ((rx+raketsizex)>bx) { ;ラケットとボールの当たり反転
if (ry<(by+bsize)) & ((ry+raketsizey)>by){
bmx=-bmx
} else {
bmy=-bmy
}
}
color 255,0,0
circle bx,by,bx+bsize,by+bsize,1
//ボールのブロックに対する当たり判定//
repeat BROYKAZU
RCNT = cnt
repeat BROXKAZU
if bro_map.cnt.RCNT = 0 : continue ;0ならブロックが存在しないのでスキップする
if((by+bsize)>=broy.cnt.RCNT) & (by<=(broy.cnt.RCNT+broysize)) & ((bx+bsize)>=brox.cnt.RCNT) & (bx<=(brox.cnt.RCNT+broxsize)) {
if((bbx+bsize)>=brox.cnt.RCNT) & (bbx<=(brox.cnt.RCNT+broxsize)) {
bmy=-bmy ;ボールの縦移動の反転
bro_map.cnt.RCNT = 0 ;当たったブロックを消す
gosub *kasan ;得点の加算
brokazu-- ;ブロックの数を一つ減らす
continue ;スキップする
}
if((bby+bsize)>=broy.cnt.RCNT) & (bby<=(broy.cnt.RCNT+broysize)) {
bmx=-bmx ;ボールの横移動の反転
bro_map.cnt.RCNT = 0 ;当たったブロックを消す
gosub *kasan ;得点の加算
brokazu-- ;ブロックの数を1つ減らす
continue ;スキップする
}
//端にあたったら両方反転//
bmx=-bmx
bmy=-bmy
brokazu--
bro_map.cnt.RCNT = 0 ;当たったブロックを消す
}
loop
loop
return
*kasan
hit=0
tokuten + 10 ;得点加算
hit++ ;打ち返しカウント
if tokuten = 1000 : ball = ball + 1 ;ボール加算
gosub *joho ;情報領域表示
return
| |
|
2008/12/14(Sun) 20:47:52|NO.21560
貫通する(ように見える)理由は分かります。
ボールの移動 1 回で、同じ方向にある 2 個のブロックを同時に破壊したとき、速度の反転を 2 回してしまっているからですね。
|
|
2008/12/14(Sun) 20:51:55|NO.21561
・スクリプトの整形に全角スペースを使ってはいけません。tabや半角スペースを使ってください。
・スクリプトを貼り付けるときは、preタグで囲むとタブや半角スペースが使えるのでレイアウトが崩れません。
> では、全て貼り付けさせていただきます
> #ラベルが存在しません [owari]
> #ラベルが存在しません [clear]
> #ラベルが存在しません [joho]
存在しないラベルがいくつかあるようです。
スクリプトを貼り付けるときは
・出来るだけそのままで動くもの。(問題が確認できるもの。)
・明らかな不要部分(問題とは関係ない部分)を削除したもの。
にするよう心がけていただけると助かります。
|
|
2008/12/14(Sun) 22:20:32|NO.21563
SYAMさん
つまり、ボール速度の反転を1回だけにすればいいという事ですか?
|
|
2008/12/14(Sun) 22:40:21|NO.21565
私に聞くまでもなく、2 回反転したら元の方向に戻っちゃいますからね…。
反転は 1 回でないといけません。
|
|
2008/12/14(Sun) 23:02:30|NO.21567
SYAMさん
何処の反転を修正すればうまくいきますか?
|
|
2008/12/14(Sun) 23:34:58|NO.21572
「ボールの移動 1 回で、同じ方向にある 2 個のブロックを同時に破壊したとき、速度の反転を 2 回してしまっている」
の意味はわかったのですか?
伝わっていたらどこが悪いのかはすぐわかると思うのですが……。
ボールがブロックを破壊したときの、ボールの速度を反転している箇所です。
ついでに。
ちなみに、あまりちゃんと読んでないので細かいことは分かりませんが…
もしかして、ブロックの角にななめにぶつかったとき、点数が入らないんじゃないでしょうか?
|
|
2008/12/14(Sun) 23:49:03|NO.21574
もうひとつついでに。
角に当たったときに進行方向を180度反転させようとしていますが、
これだとまっすぐ並んだブロックの境界線付近にボールが当たったときに不自然な反射をすることがあります。
角の処理は無いほうがよいかもしれませんね。
|
|
2008/12/15(Mon) 18:26:40|NO.21584
以下のように変更すれば うまくいくようです
//ボールのブロックに対する当たり判定//
repeat BROYKAZU
RCNT = cnt
repeat BROXKAZU
xx=0
if bro_map.cnt.RCNT = 0 : continue ;0ならブロックが存在しないのでスキップする
if((by+bsize)>=broy.cnt.RCNT) & (by<=(broy.cnt.RCNT+broysize)) & ((bx+bsize)>=brox.cnt.RCNT) & (bx<=(brox.cnt.RCNT+broxsize)) {
if((bbx+bsize)>=brox.cnt.RCNT) & (bbx<=(brox.cnt.RCNT+broxsize)) {
bmy=-bmy ;ボールの縦移動の反転
bro_map.cnt.RCNT = 0 ;当たったブロックを消す
gosub *kasan ;得点の加算
brokazu-- ;ブロックの数を一つ減らす
xx=1 ;スキップする
}
}
if bro_map.cnt.RCNT = 0 : continue ;0ならブロックが存在しないのでスキップする
if((by+bsize)>=broy.cnt.RCNT) & (by<=(broy.cnt.RCNT+broysize)) & ((bx+bsize)>=brox.cnt.RCNT) & (bx<=(brox.cnt.RCNT+broxsize)) {
if((bby+bsize)>=broy.cnt.RCNT) & (bby<=(broy.cnt.RCNT+broysize)) {
bmx=-bmx ;ボールの横移動の反転
bro_map.cnt.RCNT = 0 ;当たったブロックを消す
gosub *kasan ;得点の加算
brokazu-- ;ブロックの数を1つ減らす
xx=1 ;スキップする
}
}
if xx=1 : break
loop
if xx=1 : break
loop
return
縦方向の判定と横方向の判定をして
どちらかがあたっていれば
ループを抜けるようにすればいいみたいですね
|
|
2008/12/15(Mon) 19:02:47|NO.21585
貫通はしませんが、ブロックの境界線付近で怪しげな反射をしてしまいますね…。
以下に違う方法のサンプルを載せます。
※preタグを使いましょう。。。
x=10.0:y=10.0
vx=0.01:vy=0.007
randomize
#module
#defcfunc checkhit double x, double y
ret=0
pget x,y
if (ginfo_r>0):ret=1
return ret
#global
screen 0,240,240,0:cls 4
color 192,255,255:boxf 0,0,239,239
color 0,0,0:boxf 4,4,235,235
color 255,255,255
repeat 65
font msgothic,rnd(16)+32,rnd(3)
pos rnd(211)+4,rnd(188)+4
mes strf("%c",rnd(26)+65)
loop
*MAIN_ROUTINE
redraw 0
if (checkhit(x,y)) {
r=ginfo_r
if (checkhit(x-vx,y+vy)) {
if (checkhit(x+vx,y-vy)){
vx = -vx : vy = -vy
} else {
vy = -vy
}
} else {
vx = -vx
}
if (r>250) {
color 0,0,0:pset x,y
}
} else {
color 0,0,0
pset x,y
}
x+=vx
y+=vy
if (checkhit(x,y)==0) : color 0,255,255 : pset x,y
redraw 1,x-2,y-2,4,4
await 0
goto *MAIN_ROUTINE
ボールが点なので見にくいでしょうが、一応白い所を壊しつつ反射を続けます。
キモである反射の部分の仕組みは、
今いる場所が壁なら、
仮にX方向に反転した先が壁なら
仮にY方向に反転した先が壁なら
・X,Y両方反転(ちょうど窪みの中心に突っ込んだ)
Y方向に反転した先が壁でないなら
・Y方向に反転
X方向に反転した先が壁でないなら
・Y方向に反転
壁でないなら
・そのまま直進
…のようになっています。
これだとブロックの境界線付近の反射でも余計な反転はしません。
|
|
2008/12/16(Tue) 09:53:07|NO.21622
皆さん教えていただきありがとうございました
ボールとブロックの当たり判定がうまく出来るようになりました
あと、もう一つ聞きたい事があります
ステージを複数組み合わせたいのですけれども
#defineが原因でうまくいかないんですけれども他にやり方があれば
教えていただけませんか?
|
|
2008/12/16(Tue) 12:09:26|NO.21624
「うまくいかない」で何が起きているか判るひとは多分いないので、もう少し詳しく…
とりあえず…、
define にしてることが原因だって判っているのなら、そもそもそこを define にしてることが妥当なのかどうかから、考え直してみてはどうでしょう?
|
|
2008/12/16(Tue) 14:33:08|NO.21627
ブロックの数を指定している
#define BROXKAZU 10 ;ブロックの横の数
#define BROYKAZU 8 ;ブロックの縦の数
の所なんですけどこれだと全て固定されてしまうのです
だから、ステージごとにブロックの指定をしたいのですが何か良い方法があれば
教えていただけませんか?
|
|
2008/12/16(Tue) 15:06:53|NO.21628
>良い方法
「なぜ define なのか考えてみる」
|
|
2008/12/16(Tue) 17:11:28|NO.21631
defineは命令自体よくしらないけど
BROXKAZU=10
とかにすればall okじゃね?って思う
ステージごとにBROXKAZU=12
とかかえていけば
|
|
2008/12/17(Wed) 09:28:51|NO.21652
BROXKAZU 10
BROXKAZU 8
て書いてしまうとエラーが起きてしまうんですよ
|
|
2008/12/17(Wed) 09:56:48|NO.21653
意図しない動作をする、のではなくて「エラーが起きる」というのは、HSPの書き方に従っていないからです。
何が問題なのか考えてください。
define は、定義した名前の代わりに数字を書くのと完全に同じです。
ですから、実行中にスクリプトに書かれた数字を書き換えることができないのと同じく、変更はききません。
ここまでは実際に defineを使っているのですからお分かりだと思います。お分かりですね?
そうなると、
defineで定義するのではなく、変数を使わないといけないことになります。
変数は実行中にいろんな数値を持つことができますからね。
で
変数を使うように書き換えるだけなら、エラーには絶対になりませんよね。
元々数字だったところを変数にしただけならエラーになるハズがないです。
defineの定義は数字を直接書くのと完全に等しいのですから、これを変数にするのも同じことです。エラーになるはずがありません。
なったとしたら、書き換えた結果がHSPの文法に従っていないだけです。
というか。
エラーになる
…としか書かないのは情報不足の典型です。解決を望むなら、情報は具体的に出してください。めんどくさがっても解決が遠のくだけです。最初の方からして、情報不足が原因で余計な手間と時間がかかっているでしょう?
“#define”をただ消しただけなのではありませんか?
それだと変数への代入の書き方とは違ってますから当然、エラー2(文法まちがい)になります。
|
|
2008/12/17(Wed) 13:28:17|NO.21655
a,b,cに表示させるのを設定して
a="0,0,0,0,0,0,0,0,0,0"
b="0,1,2,1,2,1,2,1,2,0"
c="0,2,1,2,1,2,1,2,1,0"
printで設定した変数を表示させる
print a
print b
print c
:
:
この方法はどうでしょうか?
|
|
2008/12/17(Wed) 13:42:33|NO.21656
修正案の是非は 質問者が決めることではありませんか…(汗)なぜ他人に聞くのです。
とりあえず思うさまスクリプトに書けばいいでしょう。
修正案が正しければ、思うように動いてくれます。
|
|
2008/12/17(Wed) 15:06:08|NO.21659
BROXKAZU = 10
BROXKAZU = 8
ではだめなのでしょうか?
|
|
2008/12/17(Wed) 15:33:55|NO.21660
kさん
それだと複数のステージを組み合わせる事が出来なくなるんですよ
|
|
2008/12/17(Wed) 15:41:52|NO.21662
話が変わりますけど
この中で「スカイプ」または「MSNメッセンジャー」を使っている方はいますか?
|
|
2008/12/17(Wed) 16:19:58|NO.21663
何がしたいのですか?
複数のステージを組み合わせる…の意味がわからないのですが…(汗)
|
|
2008/12/17(Wed) 16:27:00|NO.21664
「スカイプ」または「MSNメッセンジャー」のチャットを使うと会話がやりやすいし
データ交換も出来るので非常に便利かと・・・
現在作っている「ブロック崩し」は30ステージを作ろうと思っているんです
つまり、一つ一つ違ったステージを30種類作りたいのです
|
|
2008/12/17(Wed) 19:09:05|NO.21669
複数ステージをもつゲームのサンプルを貼ります。
#define の使いどころの例もついでに示してあります。こうしておくと、ステージの追加がラクですよね。
変数phase は、現在のステージ数です。0からなので表示のときだけ+1してます。
配列 map には、各ステージのデータを格納しています。
ステージ作成時に、そのデータから “*”の並び方を表す二次元配列 m を作っています。
ステージクリアしたあと、phaseに+1して
phase を使ってステージ数に応じた map の中身をよびだしているところが、今回参考にすべきところとなるでしょう。
※mapからmを作っている処理の部分は、ちょっと難しいかもしれませんし、ブロックを色分けしたいならこのままでは使えません。自分のスクリプトに合うように作り直してください。
#define STAGES 3
dim map,10,STAGES
map(0,0)=129,0,0,128,0,0,0,129, 4,3
map(0,1)=126,129,2,4,8,16,32,127, 0,7
map(0,2)=42,213,170,85,170,85,170,84, 0,0
screen 0,128,128,0
font msgothic,16
*MAKE_MAP
title "PHASE "+(phase+1)+"/"+STAGES
cls 4:s=0
color 255,255,255
dim m,8,8
repeat 8 : cnty=cnt : repeat 8
m(cnt,cnty)=(map(cnty,phase)<<cnt)&0x80
if m(cnt,cnty):pos cnt*16,cnty*16:mes "*":s++
loop:loop
x=map(8,phase)
y=map(9,phase)
pos x*16,y*16:mes "■"
*WAITING_INPUT
stick k
if(k=1||k=2||k=4||k=8){
xv=(k=4)-(k=1)
yv=(k=8)-(k=2)
} else { wait 1:goto *WAITING_INPUT }
*MOVING
color 0,0,0
boxf x*16,y*16,x*16+16,y*16+16
x+=xv : y+=yv
if (x<0||x>7||y<0||y>7) {
dialog "OUT":goto *MAKE_MAP
}
color 255,255,255
pos x*16,y*16:mes "■"
if (m(x,y)) {
m(x,y)=0 : s--
if(s=0) {
phase++
if phase=STAGES:dialog "ALL CLEAR.":end
goto *MAKE_MAP
}
goto *WAITING_INPUT
}
wait 1:goto *MOVING
※ゲームについて
カーソルキーで■を動かし、すべての*を拾い集めてください。
■は*を拾うまで直進しかできず、止まることもできません。
■が画面外に飛んでっちゃったら、やりなおし。
| |
|
2008/12/18(Thu) 11:06:07|NO.21682
ブロック崩しで2000ステップいきますか?
|
|
2008/12/18(Thu) 11:21:49|NO.21683
問題はどうなったのですか?
回答を無視して話を二転三転させるのであれば、今後回答はしません。
|
|
2008/12/18(Thu) 12:51:05|NO.21684
サンプルの方を見させて頂いたのですけれども
ブロックを消えないようにするのですけれども対応できるのですか?
|
|
2008/12/18(Thu) 13:11:07|NO.21685
とりあえず「当たり判定について」は
解決したと思いますので
ブロックさんに 解決にチェックをいれていただいても
いいのではないかと思います
|
|
2008/12/18(Thu) 13:20:04|NO.21692
スクリプトは穴埋め問題じゃなく、作文です。
できるのですかもなにも
「好きなようにしてください。」
>kさん
そうですね。
話が変わりすぎてますし最初の問題は解決したはずですから もし続けるとしても一度仕切り直すとよいでしょう…
|
|
2008/12/18(Thu) 13:21:53|NO.21693
当たり判定については解決しましたのでチェックの方をつけます
ありがとうございました
複数のステージの組み合わせについては、また新規で作らさせていただきます
|
|