アクションゲーム製作 1-3

アクションゲーム製作 1-3 〜 ジャンプ 〜


ジャンプの動作は落下する処理が再現できれば簡単です。
ただし、ゲーム画面で見えている以外の部分に必要な処理がいくつかあります。

横スクロールでジャンプをするゲームを作る場合には必須の作業になりますが、
スクリプトで最も多用する変数の分岐を使った要素が出てくるので、
ここでだいたいの流れを覚えてしまいましょう。

今回は少し長いですが、
この部分が理解できればスクリプト入力の基礎をマスターしたのも同然です。
情報量が多いので最初から全部を理解しようとせず、
少しずつ自分で入力しながら覚えていきましょう。


ボタン入力

ジャンプをするにはどうしたら良いでしょうか。

ジャンプをする為にボタンの判定、
そして飛び上がる動作が必要になってきます。

まずはボタンの判定から作っていきましょう。
今回も関数入力支援ウィンドウから探してみる事にします。

なんとなく近い感じのものはありますが、
具体的にボタンを押したかどうかの判断ができる関数は見つからないのではないでしょうか。

実はボタン入力に関しては“変数”を使う事になります。
変数は関数のように入力支援が無いので、
どういったものがあるかを知るにはマニュアルのリファレンスにある変数一覧を見るか、
スクリプト入力画面で変数を選択した時に右下に表示される説明を見るしかありません。

時間がある時にでもマニュアルを眺めて、
だいたいどういった内容のものがあるか知っておくと、
必要な変数を探しやすいと思います。
(マニュアルの関数一覧と変数一覧は印刷しておくのがお勧めです)

それでは、ボタン入力の判定方法を作成します。
関数が無いので難しいのでは? と思う人もいるかもしれませんが簡単です。

ボタン入力の判断に使える変数には大まかに以下の3種類があります。
ボタンを押しているかどうかを判断する『sK**』
ボタンを押した瞬間を判断する『sTr**』
ボタンを押している時だけカウントをする『sCt**』

押した瞬間だけ判断する方が処理的に向いているので、
今回は『sTr**』変数の中でキーボード Z キー、ジョイスティック1番のボタン2の判定をする『sTrB2Z』を使いたいと思います。

入力方法に関しては直接入力するか選択する2つの方法がありますが、
詳しくは『スクリプトの基本』にある『変数の入力方法』を参考にしてください。

話を戻して、変数の説明を見てみましょう。


※スクリプト編集画面右下の説明欄

つまりこの変数には、
キーボード Z キー、ジョイスティック1番のボタン2が押された瞬間だけ1が代入されると言う訳です。

この格納された値から判断し、
ボタンが押された時にだけジャンプの処理を実行させれば良いと言う事になります。
ここで『スクリプトの基本』で説明していた条件分岐の出番です。

then 関数を使い sTrB2Z の格納された値から分岐させれば、
ボタンを押した時とそうでない時の分岐が簡単に作れます。

肝心のジャンプそのものの動作ですが、
これは Y 座標移動量の cYadd にマイナスの値を代入すれば、
押した瞬間だけ Y 座標がマイナス方向に移動し、
後は重力要素である cYadd の加算が自動で下に引っ張ってくれると言う寸法です。

さっそくスクリプトを入力してみましょう。

0 yoko_move 3  3 
1 add_lim cYadd  1 8
2 char_move        
3 map_hit_act 8 b0 1 1

4 then sTrB2_Z 5 6  
5 let cYadd  -12 0


今までの説明からすると char_move の後に来るのはおかしいのでは無いかと思われるかもしれませんが、
これは後ほど説明します。
とりあえず map_hit_act の後に実行するようにしてください。

それではスクリプトを実行してみましょう。



キーボード Z キーもしくはジョイスティック1番のボタン2を押したらキャラクターがジャンプするようになったでしょうか。

ですがこれでジャンプの動作が完成した訳ではありません。
このままではジャンプボタンを連打するとどこまでもジャンプしてしまいます。
これを防止する方法は次のステップで説明します。


連続ジャンプ防止

ジャンプするようになりましたが、
このままではいつでもジャンプが連続して出せるので、
ゲームとしては問題があります。

これを防止するにはどうしたら良いでしょうか?

とりあえず思いつくのが、
『ジャンプしたら着地するまでジャンプできないようにする』
と言う感じでしょうか。
着地=マップチップに乗っていると考えると再現できそうな気がしてきます。

とは言え、マップチップとの衝突判定である map_hit_act は、
衝突したかどうかの判断しかできないので、
下や横から衝突した場合も判定されてしまいます。

そこで先ほどの map_hit_act 関数で引数2で入力した変数です。
map_hit_act 関数の引数2の説明を見てみましょう。




『2衝突向き(1=上,2=右,4=下,8=左→ビットフラグ)を代入する変数』と書いてあります。
“ビットフラグ”とは簡単に言ってしまうと ZGE では衝突方向のようなものです。
詳しくはマニュアルに記載されていますので省略しますが、
これを利用すれば衝突した方向が判断できると言うわけです。

試しに引数2で指定した b0 の内容を画面左上に表示してみましょう。









それぞれキャラクターから見た向きが代入されているのが分かるかと思います。

つまり b0 が4なら、
マップチップはキャラクターの下に衝突していると判断できます。

ここで思いつくのが下のようなスクリプトではないでしょうか。

0 yoko_move 3  3 
1 add_lim cYadd  1 8
2 char_move        
3 map_hit_act 8 b0 1 1
4 if(!=)not_eq b0  4 7 
5 then sTrB2_Z 6 7  
6 let cYadd  -12 0



実際に実行してみると問題なく動作しているようにも思えます。

ですがマップチップを下記のように配置してみたらどうでしょうか。



恐らく壁に衝突している間ジャンプができなくなっていると思います。

マニュアルのビットフラグに関する説明を読むと分かりますが、
ビットフラグには衝突している方向の合計が格納されます。

つまりブロックの上に乗った状態(下から衝突)で、
尚且つブロックが右から衝突している場合、
右2+下4=6と言う結果が b0 に格納される為に、
4行目の if(!=)not_eq で5行目以降のジャンプの処理が飛ばされてしまうのです。

これを解消するには、
if を衝突方向だけ記述するのも良いですが、
ここでは get_and と言うとても便利な関数を使う方法を紹介します。

map_hit_act 関数のようなビットフラグを格納する関数を実行した後に、
get_and と言う関数を記述し、
引数1と2にはビットフラグを格納している変数、
そして引数3には衝突したかどうかの判断をしたい方向の値を入力するだけです。

そうすると、下方向の衝突をした場合、
右2、右2+下4、下4+左8の上方向だった場合はビットフラグの上である4、
そうでない場合は0が b0 に格納されるようになります。

また、上方向をまとめて判断したいなら、
map_hit_act の後の get_and にある引数3に1を指定すれば同様の形で処理できます。
理由は説明しても伝わりにくいので省略しますが、
ビットフラグを使って同一方向での衝突には get_and を使うと、
頭の片隅にでも入れておいてください。

本題に戻りますが、スクリプトは以下のようになります。

0 yoko_move 3  3 
1 add_lim cYadd  1 8
2 char_move        
3 map_hit_act 8 b0 1 1

4 get_and b0 b0 4 
5 then b0 6 8  

6 then sTrB2_Z 7 8  
7 let cYadd  -12 0



5行目は if(!=)not_eq でも良いですが、
対象の変数が0かそれ以外かで分岐する then 関数にしてみました、

これで床に乗りつつ壁に衝突していてもジャンプができるようになったと思います。

ですが、実は未だジャンプに関しては問題が残っています。
その話は次のステップで紹介します。


さらに一手間

現状で十分に思えるジャンプですが、
今の状態では床に着地していないとジャンプのスクリプトは実行されなくなってしまいます。

これでは空中ジャンプしたい時に問題が出てきてしまいますし、
後々になって何かしら追加したい時も汎用性に欠く事になるので、
早いうちに修正しておきたい部分です。

そこで、通常変数を使って分岐をさせる事にしてみます。
スクリプトは以下の通りです。

0 yoko_move 3  3 
1 add_lim cYadd  1 8
2 char_move        
3 map_hit_act 8 b0 1 1
4 get_and b0 b0 4 

5 then b0 6 8  
6 let i0  0 0
7 goto 9     
8 let i0  1 0

10 then sTrB2_Z 11 14  
11 if(>)more i0  0.0 14
12 let i0  1 0

13 let cYadd  -12 0


通常変数 i0 をジャンプ判断用の変数として使いました。

簡単に説明してしまうと、
ジャンプをしたら i0 に1を代入、
着地をしたら i0 に0が代入されるようと言う感じです。

これで i0 の値からジャンプをしたかどうかが判断できるようになるので、
ジャンプを実行する前の行に i0 の値から、
ジャンプしているならジャンプ動作である cYadd に代入しないようにすれば、
着地している時にだけジャンプをさせる事が可能になります。

8行目で i0 に1を代入しているのは、
床からジャンプをせずに降りた時、
空中でジャンプができてしまうのを防止する為の措置です。

床の上に乗っていないならジャンプをしたと言う事にし、
床から降りても空中ジャンプをできないようにします。

ここでさらにもう1つ変数を使う事で、
すでにジャンプをしたと判断された場合に分岐を作り、
空中ジャンプを実装する事も可能となるなど、
応用の利くスクリプトになりました。

これでジャンプの動作はようやく完成です。

次は横スクロールアクションの王道でもある、
敵を上から踏みつける動作を作っていこうと思います。

次の『アクションゲーム製作 2-1』は製作中です。
しばらくお待ちください。



▲フレームが表示されない人はクリック