“RUN” それは魔法の言葉

私とコンピュータの思い出を、だらだらと綴ります。

52.キューブ避けゲームを作ろう その3

星のスクロールができたので、いよいよキューブの部分を作る。

グラフィックのパターンは、面倒なのでネットで拾えた画像から3パターンを抜粋。それを切り替えながら繰り返し表示すると、キューブが回転しているように見えるw

キューブはランダムなY座標に登場するようにした。
そして、自機に向かって来るタイミングもランダムにした。
それっぽければいいのだw
※本家はY軸のラインが複数あって、そのライン上に沿って出現する。気になる人は解説動画へどぞー。

出現したときは、水平、X方向に動くだけ(Y方向は移動量0にする)にして、乱数を発生して向きを変える条件になったら、自機に向かって飛ぶように移動量を決める。

キューブが自機に向かって飛んで来る動きは、三角関数を使って作る。
自機の座標値と、キューブの座標値を元にして、ATAN(アークタンジェント)で角度を求める。
その角度で、X成分とY成分の移動量をsinとcosを使って求める。
それに加速する分の係数を掛けてやれば、次にキューブをXY方向それぞれ、どれだけ動かせばよいかを決められる。
詳しくは、”自機に向かってくる弾 アルゴリズム”とかで、Google先生に聞けば、解説してくれているサイトがあるのでそちらを参考にしてねwww

これをキューブ1個ずつに対して、繰り返し行うと、動きは完成。

キューブの現在の座標、移動量、移動方向、画像などは、配列変数に持たせた。
ループする処理でカウンタをカウントアップして、そのカウンターの値に応じて配列を指定して順次処理するオーソドックスなやり方で作った。

ソースから一部抜粋。

!キューブのビットマップ・初期座標・移動量をセット
FOR i=1 TO 10 %キューブは最大10個まで
 cx[i]=900+(i-1)*400
 cy[i]=50*INT(RND()*9)
 cix[i]=-clength_n % キューブの通常の移動量増分
 ciy[i]=0 % 最初はY方向には動かないので0
 GR.BITMAP.DRAW c_bitmap[i,1],c_obj,cx[i],cy[i]
 GR.BITMAP.DRAW c_bitmap[i,2],c_obj2,cx[i],cy[i]
 GR.BITMAP.DRAW c_bitmap[i,3],c_obj3,cx[i],cy[i]

 !画像を一旦隠す
 GR.HIDE c_bitmap[i,1]
 GR.HIDE c_bitmap[i,2]
 GR.HIDE c_bitmap[i,3]

NEXT

 !キューブを移動
 c_num=MOD(c_count,10)+1

 GR.HIDE c_bitmap[c_num,1]
 GR.HIDE c_bitmap[c_num,2]
 GR.HIDE c_bitmap[c_num,3]

 GR.SHOW c_bitmap[c_num,MOD(c_timing,3)+1] %カウンタを3で割った余りの数で表示するキューブのグラフィックを変更

 !キューブが自機に向かうようにする(100までの乱数を適当に発生させて、15で割り切れるときに向かう)
 IF (MOD(INT(RND()*100),15)=0) & cx[c_num] < 900 & ciy[c_num] = 0 THEN
  angle=ATAN2(jx-cx[c_num],jy-cy[c_num]) %自機とキューブの角度を求める
  cix[c_num] = INT(clength_q*SIN(angle)) %X方向の成分をSINで
  ciy[c_num] = INT(clength_q*COS(angle))   %Y方向の成分をCOSで
 ENDIF

 !キューブを移動
 !キューブの移動量をX、Y方向にプラス(マイナス)して、グラフィックを移動
 cx[c_num]+=cix[c_num]
 cy[c_num]+=ciy[c_num]
 GR.MODIFY c_bitmap[c_num,MOD(c_timing,3)+1],"x",cx[c_num],"y",cy[c_num]

 !キューブが画面外にでた?
 IF (cx[c_num] < 0 | cy[c_num] <0 | cy[c_num] > 500) & c_count > 10 THEN 
  cx[c_num]=1000+INT(RND()*9)*100
  cy[c_num]=50*INT(RND()*9)
  cix[c_num] = -clength_n 
  ciy[c_num] = 0   
 ENDIF
 c_count+=1

<余談>
画像を切り替えたりするのに、昔よくやってた方法。
カウンタの変数を作って0を代入。
ループするたびに、カウンタに1を足す。
そのカウンタを10で割って、余りの数字に1を足すと、1から10までの値が、順番に繰り返される。

0 → 余り0なので → 1
1 → 余り1なので → 2

8→ 余り8なので → 9
9→余り9なので → 10
10→余り0なので → 1
11→余り1なので → 2

割り算の余りを求めるには、MOD関数を使う。たぶんどの言語にも似た命令もしくは演算記号があると思う。
単純にカウンタが10になったら1に戻せばいいのだけど、ゲーム開始から通しで、カウンタ値を使いたいときには、無駄にカウンタを2つ作らなくていい。