背景スクロール実装
とりあえず仮で背景を描いてスクロールさせてみました。
最初の方で自機を操作できるようにしたとき、自機が画面外に出てもエラーにならないことを知りました。
つまり表示されている画面の外にも描画できるって事ですよね。
ってことは画面サイズより大きな絵を描いて、あとはそれを表示する座標を動かしてやればスクロールは実装できるはずです。
で、想定通りできました。
もっと躓くかと思っていたんだけども、あっさり成功。
ササッと描いたので、絵の出来には突っ込み無しで(笑)
まあ、本腰入れてもたいして変らないと思いますが・・・。
なんかスクリーンショットはだいぶR-TYPEっぽくなってきました。
いや、親の贔屓目全開ですが・・・w
上下の壁などと同じ絵の中に描いた星空と別に、画面サイズと同じ大きさで真っ黒な画像に星を描いて、背景の1枚奥に表示しています。
手前の背景は1フレーム毎に1ドットスクロールし、奥の星空は手前の背景のX座標を2で割った余りが0の時だけ1ドットスクロールします。
つまり、奥の星空は2フレームに1ドットスクロールする事になります。
この背景2枚をスクロールさせるのは試しておきたかったことの1つで、これが出来れば今回やるかどうかは別として、背景の多重スクロールが簡単に実装できるか実験できると思いまして。
あとは絵の端が切れるタイミングでループするように表示するだけなんで、プログラム的には簡単でした。
ちなみに当たり判定はまだ無いので、自機も敵機も波動砲も、壁を突き抜けます。
では実行ファイルを。
操作、ダウンロードについては#8の記事を参照してください。
http://multip.net/view/4maUo603x2
画面だけはいっちょ前になってきました。
動いてないとわかりずらいんですが、波動砲が敵機に当たって爆発した瞬間のスクリーンショットです。
もちろん自機と敵機にも当たり判定をつけました。
もっとも一般的な円と円の当たり判定です。
自機、敵機、波動砲にそれぞれ絵の中心から当たり判定の範囲にしたい円の半径を設定します。
あとは中心点の座標同士の距離を調べて、互いの半径を足した値より小さければ当たったとみなします。
三平方の定理を使って点と点の距離を算出する方法です。
平方根の処理は重いようなので、両辺を2乗した形で大きさを比較します。
例えば、自機の中心座標と半径を(X0,Y0,r0)、同じく敵機を(X1,Y1,r1)とすると、
(X0-X1)^2 + (Y0-Y1)^2 <= ( r0+r1 )^2
この条件を満たせば両者は接触しているとみなせます。
せっかく当たり判定をつけたんで、敵機が爆発するアニメーションも頑張って実装しました。
では実行ファイルを。
ソーステキストも同梱です。
操作やダウンロードについては前回の記事を参照してください。
自機と敵機が接触した場合も終了です。
終了後はキー入力待ちになるので、何かキーを押して完全に終了させてください。
http://multip.net/view/oRzzwkfefZ
かなりシューティングゲームになってきましたね。
理論は理解していても、当たり判定がちゃんと想定通りに働くと嬉しいもんです。
思わず、ニヤけちゃいました(笑)
ボタンを押すと単発で弾を発射するところから、連射、溜め打ちと順に実装してゆきました。
波動砲のパワーは5段階で、1.5秒で最大まで溜まります。
波動砲のデータを構造体にして、その構造体を配列にする事で連射できるようになっていて、今のところ1画面に10発まで対応するようになってます。
配列の要素ごとに使用中かどうかのフラグを持っていて、発射の際は使用されていない一番若い配列番号を使用します。
画面外に消えたらこのフラグを降ろして次の発射に備えます。
実行ファイルを。
ソース同梱です。
リンク先、四角い枠内下のほうにある『ダウンロード』をクリックでダウンできます。
zipファイルなので解凍してから、フォルダ内のexeファイルをダブルクリックで実行されます。
操作
矢印キー & パッド方向キー ・・・ 自機の操作
Zキー & パッドAボタン押す ・・・ 波動砲溜める
Zキー & パッドAボタン離す ・・・ 波動砲発射
ESCキー ・・・ プログラム終了
http://multip.net/view/2ot267Uczo
次はそろそろ当たり判定かな。
ジグザグ運動実装
実現するための考え方は固まってたんだけど、Cでの三角関数の扱い方がわからなかったのと、小数点以下を含む型を使い慣れてなかったので思わぬ苦戦を強いられました。
では、方法を説明します。
数学を教えるブログじゃないんで、ざっくりとした説明で。
座標の原点 ( 0 , 0 ) を中心とする半径 r の円を考える。
円周上の点 ( x , y ) の y は、その点と原点を結ぶ線とX軸の作る角度を θ とすると、
r × sinθ
と表すことができ、この値は0度から180度までは正の値を、180度から360度までは負の値をとる。
数値の流れを追ってゆくと、0度から少しずつ大きくなり、90度で最高点に達し、そこから小さくなり180度を境に負の領域に入る。
270度で最小値となり、そこから大きくなって行って360度で0になる。
一定の角速度で動いた場合、頂点となる90度と270度付近ほど数値の変化が小さくなるので、Y座標は加速、減速、反転、加速、減速、反転と滑らかな上下運動となる。
角度を1フレームごとに一定の量ずつ増やし、この y の値を敵機のY座標に足してやればOK。
敵のデータをまとめた構造体に、現在の角度、振幅(円の半径r)、円運動の角速度を追加しました。
この三つの値を変化させて、位相、振幅、波長をコントロールする感じ。
これに、最初の直線運動の関数も通して、X座標を変化させれば、きちんと波のようなジグザグに動きます。
ソース部分も軽く説明を。
まず、三角関数を使うためにmath.hをインクルード。
あと、C言語では角度を『度』ではなくラジアン(360度を”2×パイ”とする表現)で表すみたいなので、パイ(円周率)の値と、度をラジアンに変換する式の定数宣言を追加しました。
数値を入力する時は『度』で入力できた方が個人的にはイメージしやすいからです。
あとは、必要なデータを敵機の構造体に追加し、上記の考え方をコード化した関数を追加しました。
実行ファイルをどうぞ。
ソーステキストも同梱です。
ダウンロードの方法や操作については#2の記事を参照してください。
http://multip.net/view/0lTRTZOC1F
いつもの事ですが、プログラミングと格闘の末、最後の力を絞ってブログを更新してるので、脳が上手く働いてません。
文体が統一されてなかったり、説明が不足してるのは勘弁してください(笑)
あ、誤字もね。
敵機をクルクルアニメーションさせてみた。
DrawAnimationと言う関数を新たに追加。
アニメを簡単に表示する方法を考えたんだけど思いつかなくて、最初の方の記事で使っていたテキスト『14歳からはじめるC言語ゲームプログラミング』を調べた。
なるほどね!
よく思いつくなあと、しばし関心。
まず、1秒間に何コマアニメーションさせるかを fps とする。
1000/fps で1コマの時間が計算できる。
例えば1秒で8コマ動かすなら、1000/8で1コマの時間は125ミリ秒となる。
次にGetNowCount関数で現在の時間をミリ秒で得る。
それをさっき求めた1コマの時間で割る。
t = GetNowCount( )
とすると
t / ( 1000/fps )
って感じで。
そうすると、1コマ分の時間が経過するごとに1増える値が得られる。
これをアニメが一回りする総コマ数で割ってやる。
その余りをアニメパターンのコマ番号に使うのだ。
表示するコマ番号 = ( int )( t / (1000/fps) ) % 総コマ数
計算は割り算で小数になることもあるので、変数は float型で宣言し、割り算計算する部分の頭に ( int )を付けて整数に変換する。
ちょっとややこしいけど、落ち着いて一つ一つの処理を追えば難しくは無い。
例えば1秒間に10コマ進むアニメパターンのfpsは10だ。
1000/10は100。
現在時刻が15545だったとしよう。
15545/100は155.45となる。
整数にするために小数点以下を切り捨てると、155になる。
このアニメパターンの総コマ数が4だったとすると、
155/4で、応えは38と余りが3となる。
この余り3がコマ番号だ。
4で割っているので、この余りは割られる数が1増えるごとに0から3の範囲でループする。
で、割られる数は何だったかと振り返ると、1コマ分の時間ごとに1増える数なのだ。
つまり、1コマ分の時間経過にあわせて余りは1ずつ増え、総コマ数に達すると0に戻る。
わかりやすく説明できたかなあ・・・。
この計算を関数内でおこなう。
渡す引数は(座標x、y、アニメパターの入ったグラフィックハンドル配列の最初のコマのアドレス、fps、総コマ数)って感じだ。
これで、座標、キャラクターの種類、1コマの時間、総コマ数を問わずに、この関数を通せばアニメーションさせることが出来る。
ルールはひとつ。
アニメーションパターンは順番どおりにグラフィックハンドルの配列変数に入れておくこと。
では実行ファイルを。
ソースも入ってます。
http://multip.net/view/bEcjpJQM0k
そういや、返り値の必要ない関数はvoid型でよかったんだね。
だいぶ前にやったから忘れてて、関数全部int型で宣言してた・・・(汗)
いちいち return 0; って書くのなんか違和感あったんだよなあ(笑)
というわけで、ちゃんとvoid型になってます。
たまに復習もしないとだめだね。
- ABOUT
- カレンダー
06 | 2025/07 | 08 |
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 最新コメント
- プロフィール
はい。
- ブログ内検索
- カウンター
- アクセス解析