スクロール方向が変わりまくる

傾いた地形

 「配列変数を使った地形との当たり判定」で説明した地形の描画を、任意の角度に回転させて 描きます。
 scroll_cntがいくつの時に何度にする、という指定を何個か書いて、スクロール方向が変わりまくる演出をします。

 1.回転させた座標を求める関数

 回転させるのですから、壁、背景のマップチップ、自機の座標はすべて中心の座標で表します。角度は「度」とし、必要な時に ラジアンに直します。

 各マップチップの位置をまず水平の状態で計算して、ゲーム画面の中心に対して(ゲーム画面の中心を中心として)指定した角度 回転させた位置を求め、指定角度分傾けて描画すればよいということになります。

 任意の座標をゲーム画面の中心に対して、指定した角度回転させた座標を求める関数があれば便利です。そこで、この関数 (ユーザー定義命令)を作ります。

  関数名 Rotate_Point
  引数 new_x、new_y(回転後の座標、参照渡し)、x、y(回転前の座標)、angle(角度)

 2.地形の描画

(1)静止している地形の描画

 地形を傾けるのですから、その分描画範囲が広くなります。どれくらい広くすればいいかというと、描画範囲がもっとも大きく なるのは、45度傾けた時です。

最大の高さ

 三平方の定理より図の赤い点線の長さは480*√2=678.82……となります。つまり赤い四角の幅、高さは678.82……です。
この幅(高さ)に32×32ドットのマップチップが何個入るかというと、480*√2/32=21.21……個です。
つまり22行22列描けば、角度が何度であろうと絶対に、画面内に描画されない部分はできません。

 適当な地形を任意の角度に回転させて描画するプログラムを作ってみました。

[テストプログラムをダウンロード]
※カーソルキーの左右で角度を変えられます。

 ここで「画像ファイルを使ったline文」の時と同じ問題が起こります。小数点以下を切り捨てる ことによるわずかな誤差により、マップチップ同士の間に隙間ができてしまうのです。壁の方は、まあ仕方ないかといった程度なのです が、背景の方は、角度によっては黒い筋が入ってしまい、見苦しいです。
 そこで、同講座の時と同じ対処をします。背景のマップチップを少し(ここでは8ドットとします)広めにし、マップチップ同士が一部 重なるようにします。

マップチップの拡張

 これに伴って、以下のように変えます。

(2)スクロールする地形の描画

 次に、この画像をスクロールすることを考えます。これまでと同様、水平の時点でscroll_cnt\32左にずらして計算します。
 描画範囲がゲーム画面に比べて十分に大きいので、1列多く描くという手順は省いてもよさそうに見えます。しかし、45度傾けた時に やはり1列足りなくなるので、1列多く描きます。
 すると以下のように変更になります。

[テストプログラムをダウンロード]
※カーソルキーの左右で角度を変えられます。

 やはり小数点以下を切り捨てることによる誤差が影響します。マップチップがグラグラと揺れてしまうのです。地形が傾いている時 には、まあ仕方ないかという感じなのですが、0度や90度の時にはまるで陽炎(かげろう)のように揺らめいていて、非常に見苦しいです。 そこで誤差を少なくするために、小数点以下を切り捨てから、四捨五入に変更します(Rotate_Point関数)。

 これで0度や90度の時にきれいになります。

(3)画面外

 画面外にあるマップチップについては描く必要がありません。例えば壁のマップチップが、画面上端より上にある場合を考えます。

中心から下端までの高さ

 中心から下端までの高さは、45度傾いた時に最も大きくなり、16*√2=22.62……となります。ということは中心のy座標が-23以下 の時、どんな角度であろうと絶対に画面外にあります。
 背景のマップチップについても同様で、20*√2=28.28……ですから、中心のy座標が-29以下の時絶対に画面外にあります。

(4)配列変数のデータを読んで描画

 配列変数mapの各要素は22行分にもなり、地形の配置データを書くのも一苦労です。しかし、上3行、下3行は、どんな角度に傾けよう とごく一部しか見えないので、書いてもあまり意味がありません。この部分は壁であることにし、残りの16行分について配置データを 書きます。

map(159)="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
	・
	・
	・
map(  7)="1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1"
map(  6)="1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1"
map(  5)="1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1"
map(  4)="1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1"
map(  3)="1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1"
map(  2)="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
map(  1)="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
map(  0)="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"

 水平の時の座標計算は、「配列変数を使った地形との当たり判定」の地形描画のアルゴリズムと同様 です。すると結局、地形描画の手順は以下のようになります。

 背景の描画

 壁の描画

 3.角度の変更

 何度に変更するのかを変数set_angleに入れます。
  もしscroll_cntが16*32ならset_angle=30
  もしscroll_cntが32*32ならset_angle=60
    ・
    ・
    ・
 のように、変えたい場所と角度を列挙します。
 map_angleを少しずつ増やして(あるいは減らして)set_angleと一致するようにします。1フレームあたり1度くらい増減してもいい ように思えますが、それだと急激に角度が変わるので、ここでは1フレームあたり0.2度ずつ増減します。

 4.地形との当たり判定

 一見、「傾いた矩形の当たり判定」のアルゴリズムを使って、一つ一つの壁と当たり判定を行わな ければならないように見えます。しかし、同講座と同じ考え方で、自機の中心座標をゲーム画面の中心に対して-map_angle度回転させた 架空の点を考えれば、水平の状態の地形との当たり判定を行うのと同じことです。つまり、画面全体を-map_angle度回転させて考える わけです。


[サンプルプログラムをダウンロード]

[目次へ][前へ] inserted by FC2 system