投稿
第二回、解説つきサンプル講座(?) 今回は、みんなが結構やりたがるサイドビューのジャンプとBGとの判定です! まあ第三回があるかは分かりませんけどね~。
40そうだね
プレイ済み
返信[1]
親投稿
とりあえずソースです。
0そうだね
プレイ済み
返信[2]
親投稿
結構処理が似てるんで、とりあえず第1回とかぶるような内容の説明はサラッと流しますんで、わからない人は前回のやつをみると良いと思います。 一部はやり方をあえて変えてみたので、もちろんその部分はちゃんと説明します。サンプルに関する質問があったら、このコメントで答えるので聞いてください。ではスタート。 1:定番の画面クリアのおまじない 2〜4:BGに書き込む命令で背景となる地面ブロックを3つ描画しています。 6:使用する変数を初期化しています。てかDの初期化は不要ですね…。間違えて残ってました…。最後のコロンも消し忘れてるし…。 ということで、 X: キャラクタのX座標 Y: キャラクタのY座標 AY: Y座標への加速度(ジャンプや落下用) を設定しています。
0そうだね
プレイ済み
返信[3]
親投稿
7:管理番号1にキャラクタを割り当てて登場させています。実際の位置は26行目で設定するので、ここでは画面に出しているだけです。 9:メインループのための定番のラベルです。 10:ボタンの入力を変数Bに入れています。また定義番号用の変数Dを初期化しています。 12〜13:左右ボタンでキャラクターを左右に動かすためのコードです。この時に、定義番号の為の値をDに設定しておきます。 15:Y座標に加速度AYを加えます。そして加速度AYには重力(1)を加えています。 ここでちょっと特殊なことをしていて、前回はやらなかったのですが、MIN関数を使い、AYが16より大きくならないようにしています。これはAYが16より大きくなると落下している時に判定がブロックをすり抜けてしまう可能性があるため、ブロックの最大の高さである16より大きくならないようにして飛び越えないようにしてます。
0そうだね
プレイ済み
返信[4]
親投稿
17:ここが肝心要のBGとの当たり判定です。BGGET命令でレイヤー0に対してX+8,Y+16の位置にあるBG番号を取得しています。最後の引数1はこれをつけるとスプライトの座標の位置からBG番号を求められるようになります。これがないとスプライトの座標をBG座標に変換する必要が出てくるので、1にしておくとちょっと便利です。 X座標とY座標に数値を足しているのはキャラクタの中央足元の位置の座標を調べるためです。こうしないとデフォルトのキャラクタの原点は左上に設定されているので左上の位置のBGで判定されてしまいます。どの位置を調べるかというのは重要なので気をつけましょう。 また&&で同時にAYが0より大きいかどうかも条件に加えています。これがないと上昇中も当たり判定をしてしまい、キャラクタが突然ブロックに乗るワープのような状態が発生してしまうからです。
0そうだね
プレイ済み
返信[5]
親投稿
この条件で判定している事からわかるようにブロックに対して頭はぶつかりません。単純にすり抜ける感じです。頭がぶつかるようにしたかったら、それは別途判定を加えて処理する必要があります。 18〜21:判定したBGが0以外、つまりなにかあった時に実行される部分です。 18:Y座標の位置がブロックの上になるように補正しています。BGは16×16のサイズなので、Yを16で割って(余りのでないDIVを使用してます)、再度16をかけることでちょうどキリの良い値にしてブロックの上に乗っかるようにしています。 19:ブロックに乗ったので加速度であるAYは0にしています。 20:ここはA(ジャンプ)ボタンの処理です。ボタンが押された時に上方向へ-12の加速度を入れているだけです。
0そうだね
プレイ済み
返信[6]
親投稿
ただAボタンの処理をこの位置にもってきたのにはちゃんとした理由があります。この位置にすることで、ブロックの上に乗っているときにしか判定されないので、空中でジャンプボタンを押してジャンプしてしまうなどが起こらないようになります。 ただ本当にこの位置でこのやり方で判断するのがベストかどうかはケースバイケースです。一つの例ぐらいに思っていてください。 22:BG接触判定時のIFの終わりですね。 24:ここはキャラクタをアニメーションさせている処理です。この部分が前回とやり方を変えてみたところです。 前回はSPANIM命令を使ってアニメーションさせたのですが、このようなやり方で自分でアニメを切り替えてアニメーションさせることも出来ます。というか普通はSPANIMのような便利な命令がない場合も多く、その場合はこういうやり方がスタンダードです。
0そうだね
プレイ済み
返信[7]
親投稿
D(定義番号)が0(停止)の時はアニメーションをさせる必要がないのでIFで判断し、アニメーションの必要があるときにSPCHR命令で管理番号1のスプライトの定義番号を直接変えています。 この時に、MAINCNTというシステム変数を使っていますが、これはプチコンに始めから用意されている変数で毎フレーム勝手に数値が増えていくというカウンタ代わりに便利な変数です。 この変数をつかい4フレーム毎(なので4で割って使っている)に余りを求める命令であるMODを使い、さらに4で割った余りを求め、これをD(定義番号)に足しています。余りなので必ず0〜3の値になるのでそれによって一定パターンの繰り返しのアニメーションを行うことが出来ます。 今回SPANIMを使わなかったのは、こういうやり方もあるよ、という例と今回は直接変える事でコードが短くなるケースだったので1画面にも収まるのでこうしてみました。
2そうだね
プレイ済み
返信[8]
親投稿
さて、ここまで来ればあとは簡単(?)ですね。 26:キャラクタの位置を変更。 27:定番の同期おまじない、VSYNC(1/60フレーム)。 28:メインループのラベルに戻る(飛ぶ) って感じでフィニッシュです! 長々と書いてしまいましたが、これが少しでも役に立てば嬉しいです。ご静聴ありがとうございました!
0そうだね
プレイ済み
返信[9]
親投稿
追記:BGGET命令で返される16ビット数値を取り出すプログラムをUPしています。詳しくは、僕の顔をクリック! (宣伝SORRY)
0そうだね
プレイ済み
返信[10]
親投稿
おかっぺ Japanese_WASABI
BGはまだ全くさわったことがなかったので参考にさせて頂きます。第三回にも期待♪
0そうだね
プレイ済み
返信[11]
親投稿
宣伝問題ないです(^ ^) 第三回はネタ的にどうしようかというのもあったり…。とくにサンプルは1画面に収まるコード量と決めてるので、出来ることも限られるしなー。 でも、お役に立てたなら嬉しいです。 今は二進数の詳しい説明とかしたら需要はあるのかなぁ、とも迷い中です(^ ^)
0そうだね
プレイ済み
返信[12]
親投稿
ほんたくっ ruuzibatakuma
結構間が空いた質問なのですが… よろしければ、ブロックの左、右の当たり判定と、天井の当たり判定教えてください… 本当にすいません!
0そうだね
プレイ済み
返信[13]
親投稿
久々に書き込みが…。てか返事が遅くなってすいません。最近はどうもなかなか…。 結局は当たり判定は移動後(や移動前)に座標をチェックするしかないんですよね。 例えば天井との当たりであれば、上昇中(AYがマイナス)の時に、自分の頭の位置の作業を調べて壁だったらAYを0にするとかすれば壁にぶつかったら落ちてきます。その際に、着地の時のように座標補正をするとベストです。 左右も移動方向をみて、その移動先の座標を調べる…という感じなので、この辺は地味にチェックするしかないと思います。 とりあえず今回のサンプルをちゃんと理解出来れば(精度はともかく)ある程度は実装出来るようになると思いますし頑張ってみてください!
1そうだね
プレイ済み
返信[14]
親投稿
ほんたくっ ruuzibatakuma
ありがとうございますっ!
0そうだね
プレイ済み
返信[15]
親投稿
ほんたくっ ruuzibatakuma
Xの移動速度にVXという変数をつけて、 壁にぶつかったらVXを0にするという方法を思いつきました。
0そうだね
プレイ済み
返信[16]
親投稿
そういう思いつきが自分の力になっていくと思うので良いことだと思いますよ! ちなみに移動先が壁の時にVXを0にする場合、例えば移動量が10ドットだとして5ドット先から壁の場合、単純に0にすると壁に隣接出来ない事になるので、その場合はVXを5にする(壁に隣接するギリギリ)みたいな補正が出来るようになると、さらに良くなると思いますので、実力がついてきたら色々と試してみるのもいいと思います。 そういう風に考えていくと移動一つとっても色んなやり方やノウハウが詰まっているのに気づけると思いますよ。
0そうだね
プレイ済み
返信[17]
親投稿
ほんたくっ ruuzibatakuma
詳しい説明、そしてアドバイスありがとうございます! 感謝しています!
0そうだね
プレイ済み