ExcelVBAゲームプログラミング?

初心者でもきっとできる!
Excelさえ持っていれば特別なソフトは不要!
すぐにでも始められる簡単ゲームプログラミング!
今すぐ始めよう!

サンプルやゲームのダウンロードができる別館も好評運営中です。
ご意見やご質問、ゲームの感想等は掲示板までお気軽に。是非、皆さんの声を聞かせてください。運営、開発の励みになります。



各種ダウンロードはコチラ ↓ 意見・感想・質問はコチラ ↓
影倉庫 Shadow warehouse サポート掲示板
ブログの全体像はコチラ ↓ リンクのページはコチラ ↓
サイトマップ 自分本位なリンク


スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。






Chapter.48 [ シューティングゲーム8:Mod演算子の活用 ]

■敵キャラクター下準備

前回までの講座内容で、プレイヤーキャラクターがショットを撃つところまでは作成できました。随分ゲームらしくなってきましたね。

今回からは敵キャラクターについて考えていきたいと思います。
とは言っても、敵キャラクターは、基本的にキー入力などの受け付けをする必要がありません。出現するべきポイントを決めてあげさえすれば、あとは勝手に移動や攻撃をするようにしておくだけです。やり方としてはショットのときの考え方に近いかもしれません。

プレイヤーキャラクターの処理を行う際に、キャラクター用の構造体をすでに宣言しています。敵キャラクターもこれを流用して作成することが可能です。
今回は、画面上に最大で10体まで表示できるようにしてみましょう。

それでは、まず敵キャラクターを管理する配列変数の宣言です。先ほども書いたように、これにはプレイヤーキャラクターに使用した構造体を流用します。

Public Enemy_Data(9) As Chara

この1文で、敵キャラクター10体分の配列変数を宣言できました。データ型を間違えないように注意してくださいね。

次に、ユーザーフォームの準備です。
こちらは、専用の画像を用意しました。

     敵その1          敵その2     
Blue.gif
Yellow.gif


今回は2種類の敵キャラクターが表示されるようにしてみたいと思います。

先ほども書いたように、今回は敵キャラクターを10体まで表示できるようにします。そこで、ユーザーフォーム上に、10個の新しいイメージコントロールを配置しましょう。
今回は、敵用のイメージコントロールに『Enemy1Enemy10』までの連番で名前をつけておきます。ここで名前を連番にしておくことで、ショットの処理のときと同様、繰り返し処理との相性が非常によくなります。

260.gif

ただし、今回はこれで準備完了とはいきません。なぜなら、敵キャラクターを2種類用意するからです。
そのためには、アニメーションのときに解説したテクニックを併用します。具体的に言うと『原画を準備しておく』ということです。

もちろん、敵キャラクターの1番から5番までを敵その1、6番から10番までを敵その2、という具合に切り分けて処理することもできなくはありません。ですが、敵キャラクターの出現と同時に好きなように切り替えられる、というようにしたほうが、あとあと何かと便利ですし、コードもスマートに仕上がります。

以前、アニメーション処理を行った際には、あらかじめユーザーフォーム上に原画となるイメージコントロールを3つ配置していました(あの丸いキャラクターのときです)。そして、イメージコントロールから別のイメージコントロールへ、画像データの転送を行っていましたね。
あれと同じ要領で、今回は敵キャラクターの種類に応じて、表示される画像が変化するようにするわけです。

そこで、原画用のイメージコントロールを、ユーザーフォームの大きさを変更して配置します。デザインしている段階では、ユーザーフォームが大きくなっていても問題ありません。ユーザーフォームが表示される直前、つまり『Initializeイベント』で適切な大きさに調節すればいいからです。これについては以前にも詳しく解説しましたね。よくわからないという人はそちらをご覧ください(Chapter40を参照)。

261.gif

このように、デザイン中はユーザーフォームの大きさを、余裕のある大きさにしておきます。そして、最終的には隠してしまう部分に、原画となるイメージコントロールを配置しておきます。
この2つのイメージコントロールの名前は『Enemy_s1 ・ Enemy_s2』としておきます。
敵キャラクターを実際に表示する段階になったら、その種類に応じて、適切な敵キャラクターの画像をここから転送してあげます。このようにしておくことで、何番目のイメージコントロールを使うときでも、画像は自由に切り替えて処理することができるのです。


Initializeイベントを修正

さて、先ほどの敵キャラクター表示切り替えのために、ユーザーフォームを大きくしてしまいました。これはゲームの開始と同時に調節して、原画用のイメージコントロールが見えなくなるようにしなくてはいけません。

Private Sub UserForm_Initialize()
    UserForm1.Width = 220
End Sub

フォームモジュールに、このようなInitializeイベントを追加しておきます。これで、ユーザーフォームが表示される直前に、ユーザーフォームの横幅が適切な状態に調節されます。原画用のイメージコントロールがうまい具合に隠れるはずです。


それからもうひとつ、あらかじめ設定しておくべきことがあります。
ショットの処理を行ったときもそうでしたが、敵キャラクターは、ゲームが始まった瞬間から画面上に表示されていてはおかしいですね。先ほどの画像みたいに、画面上にズラリとならんでいるのは変です。
そこで、敵キャラクター用のイメージコントロールは、あらかじめVisibleプロパティを『False』に設定しておきます。こうしておけば、ゲームのスタート時には、敵キャラクターが視覚的には見えなくなります。

敵キャラクターが出現する段階になったら、『種類に応じて画像を設定』→『出現させたい座標にセット』→『VisibleプロパティをTrueに設定』→『その後の移動などの処理へ』と順番に処理していくわけです。

ここまでが実装できれば、ユーザーフォームの準備はOKです。
あとは、敵キャラクターの出現するタイミングをいかに管理するかですね。


■敵キャラクター出現のタイミング

さて、それでは実際に敵キャラクターを出現させるために、必要となる概念について考えて見ましょう。

世の中には、様々なゲームがあり、その種類に応じて、様々な敵キャラクターが存在します。
例えばスーパーマリオブラザーズに登場する『クリボー』や『ノコノコ』。ドラゴンクエストに登場する『スライム』や『キメラ』。その他にも、ギャラクシアンに登場する様々な虫型の敵達や、ツインビーに登場する『ポコポコ大魔王』などなど、ゲームによって千差万別です。

そして、その出現方法もまた、千差万別ですね。
マリオのような横スクロール系のアクションゲームでは、キャラクターを移動して画面がスクロールすると、向こうのほうから敵が出現します。ドラゴンクエストはランダムにエンカウントして敵が出てきますね。

今回作成するのは『縦スクロールのシューティングゲーム』でしたよね。ということはツインビーのような感じで敵が出現するようにするわけですね。具体的には、自動的に画面がスクロールしていき、決まった場所に到達すると敵キャラクターが出現するという感じです。
このような敵キャラクターの出現をプログラミングするには、一体どうしたらいいのでしょうか。

これを実現するための方法として、私の感覚で一番簡単だと思うのは、『内部カウンター方式』です。
この『内部カウンター方式』というのは一般的な手法ではなくて、あくまで私が名づけた手法のひとつです。そこらへんは誤解しないでくださいね。多分検索とかしても何も出ません……きっと。

さて、では内部カウンター方式とは具体的にはどのような方法なのか、それを解説しましょう。

まず、この手法を実現するために、Publicでひとつ変数を宣言します。

Public Total_Count As Long

この変数、カタカナ読みすると『トータルカウント』と読めますね。この変数をうまく使うことで内部カウンター方式が実現できます。

ゲームが始まったら、最初にこの変数Total_Countを0にしておきます。これは初期化処理のところで、他の変数同様に初期化しておけばいいですね。
そして、ゲームの実行中、ループごとに毎回プラス1ずつ増やしていきます。すると、ゲームが進めば進むほど、この変数Total_Countの値が増加していくことになりますね。ここまでくればなんとなく想像がつきませんか?

この変数Total_Countの値が小さいうちは、ゲームが開始されてからまだそれほど時間が経っていないことになります。逆に、大きな値が入っているとしたら、長い時間経っていることになりますね。

ゲームの開始と同時にカウントを始め、一定の数値に来たときにだけ、敵キャラクターが出現するようにすれば、任意のタイミングで敵キャラクターを出現させることができるわけです。
間隔を空けずに、短いカウントの中で連続して出現させることもできますし、逆に少し間を空けることも簡単です。

今回は、この敵キャラクター出現を管理するプロシージャを、がんばって作成してみることにしましょう。


■敵キャラクター出現管理

今回作成するのは、あくまでもテスト段階用のプロシージャです。

普通、シューティングゲームは敵の出現するパターンが決まっています。今作成しているシューティングゲームも、最終的には一定のパターンで敵が出現するようにします。
ただ、テストの段階では、同じパターンで敵が何度も出現してくれたほうが、動作を確認しやすいです。そんな理由から、今回の講座で解説するコードは、あくまでもテスト用とします。

それではコードを見ながら考えてみましょう。

Sub Stage_Count()
    Select Case Total_Count Mod 200 '①
        Case 0
            敵キャラクター出現処理A
        Case 50
            敵キャラクター出現処理B
        Case 100
            敵キャラクター出現処理C
    End Select
End Sub

これが、敵キャラクターの出現を管理するプロシージャです。
このプロシージャの名前は『Stage_Count』としました。厳密には複数のステージがあるわけではないのですが、便宜上、このような名前にさせていただきます。

さて、このプロシージャで肝となるのは、ズバリ①の部分です。というか、ここがほとんど全てです。

まず、Select Case文を使っているのは見てわかりますね。そして、条件分岐の判断材料となる部分に『Total_Count Mod 200』と書いてあります。
この式を見て、皆さんは意味がわかるでしょうか。

Mod』というところで、多分クエスチョンマークが浮かぶと思います。ですのでまずはこれについて解説しますね。

Mod』は、演算子と呼ばれているもののひとつです。
演算子は『+-÷×』などの、計算に使う記号と思ってもらえればわかりやすいと思います。数字と数字を、何かしらの法則によって計算するための記号ですね。

Mod演算子は、考え方としては『÷』に近いです。皆さん小学生の頃に『余りのある割り算』を勉強したと思いますが、要するにあれです。
いくつか例を挙げてみましょう。

10 Mod 10 …… 10 ÷ 10 = 1......余り0
10 Mod 5 …… 10 ÷ 5 = 2......余り0
10 Mod 4 …… 10 ÷ 4 = 2......余り2
10 Mod 3 …… 10 ÷ 3 = 3......余り1

この計算は大丈夫ですね? 割り切れない数で除算した場合には、小数点以下まで計算しなければ必ず余りが出ます。Mod演算子はこれを一発で計算してくれるという便利な演算子なのです。

これが理解できたところで、もういちど先ほどのコードを見てみます。

Select Case Total_Count Mod 200

変数Total_Countは、ゲームの開始と同時に常にカウントされ続けます。1から始まり、2、3、4……11、12、13……101、102、103……と永遠に増え続けます。この数字を200で割り算してみると余りはどのようになるでしょうか。

Total_Countの値Mod 200 を計算した結果
10
10
50
50
100
100
200
0
250
50
350
150
500
100

このように、Mod演算子を使うと、『ある特定の範囲に限定した数値』を取得することができます。
例えばTotal_Countが199の時には、『 199 ÷ 200 』を計算すればいいので、答えは『 199 ÷ 200 = 0......余り199 』になりますね。次のループではTotal_Countの値が200になるはずですから『 200 ÷ 200 = 1......余り0 』という計算が成り立ち、Mod演算子の計算結果は0に戻ります。

つまり、ゲームが進行している最中、『Total_Count Mod 200』の計算結果は、常に0~199の範囲をぐるぐる回り続けるのです。
この値をSelect Case文の条件分岐にかけることによって、任意のタイミングで処理を行うことが可能になります。Mod演算子の計算結果が0のときは……50のときは……100のときは……という具合ですね。

変数Total_Countの値がどれほど大きくなっても、常にMod演算子による計算結果は一定の範囲に限定されます。これがポイントです。
Mod演算子をうまく活用することによって、繰り返し同じ範囲の数値を取得することができるのですね。

これは、テスト用の敵出現管理として理想的な処理と言えるでしょう。何度も同じ敵が繰り返し出現するので、動作がおかしくないかチェックしやすいです。


最終的にゲームが完成に向かう段階に入ったら、Select Case文で直接カウント数を参照して、敵の出現を管理してしまうのもありです。それが例えば次のコードです。

Sub Stage_Count()
    Select Case Total_Count '①
        Case 0, 200, 400, 800
            敵キャラクター出現処理A
        Case 50, 500, 1000
            敵キャラクター出現処理B
        Case 100, 600, 650, 700, 900
            敵キャラクター出現処理C
    End Select
End Sub

今度は①の部分でMod演算子を使っていませんね。変数Total_Countの値を直接使ってSelect Case文で分岐しています。

この方法では、先ほどとは違って同じパターンで敵が何度も出現することはありません。なぜなら、ループごとにカウントされる変数Total_Countは、いずれ1000を超えていってしまうからですね。

カウント数が1000以下の場合には、指定のカウント数で敵が出現しますが、そのあとは一切何も出現しません。Select Case文で指定されている最大数が1000なので、それ以上の数値になってしまったら、絶対に敵の出現処理に移る事はないわけです。

どのようなタイミングで敵が出現するようにするのかは、ゲームの大筋が完成してから考えればいいでしょう。ですから、今の段階では、動作のチェックがしやすいテスト仕様のコードを使っていきましょう。


■まとめ

さて、少し長くなりました。
途中、Mod演算子に関することなど、少し横道にそれたので、わかりにくくなってしまったかもしれませんね。
ただ、Mod演算子は使い方さえ理解できていれば、ゲームの開発にはとても役立ちます。今回の講座で覚えてしまえばきっと損はしません。

とりあえず今回は、ユーザーフォーム上の準備をしっかりやっておきましょう。さらに、敵の出現するタイミングをどのように管理したらいいのか、それがわかっていれば充分です。

実際の敵出現処理は次回解説です。次回の内容を実装させたら、敵キャラクターが出現するようになりますので、より一層ゲームらしくなるはずです。がんばりましょう。


■格言

敵キャラクターをしっかり準備する
カウント数を参照して敵の出現を管理する
Mod演算子をうまく活用


Modは超使えます。是非習得してほしいですね。
関連記事






Comment

Name
E-mail
URL
Comment
Pass  *
Secret? (管理者にだけ表示)

メールフォーム

影斬に物申すという方はこちら

名前 :
メール:
件名 :
本文 :

可能な限り要望には応えますが、必ず返信や回答ができることを、保障するものではありません。
ご了承ください。

Chapters

コンテンツ一覧


■Chapter 一覧■
    全てのChapterの一覧です。
    直接アクセスしたい方はこちらをご利用下さい。

    Chapter.1 [ 知っておくべき心得 ]
    Chapter.2 [ Excelってなんだろう ]
    Chapter.3 [ Excelの基本画面 ]
    Chapter.4 [ VBAとは? ]
    Chapter.5 [ モジュールについて ]
    Chapter.6 [ 変数 ]
    Chapter.7 [ 変数の型と宣言 ]
    Chapter.8 [ プロシージャとスコープ ]
    Chapter.9 [ ゲームつくる様々な手法 ]
    Chapter.10 [ ユーザーフォーム ]
    Chapter.11 [ プロパティウィンドウ ]
    Chapter.12 [ 乱数 ]
    Chapter.13 [ 条件分岐 ]
    Chapter.14 [ ゲーム画面のデザイン ]
    Chapter.15 [ コード記述の基本作法 ]
    Chapter.16 [ じゃんけんゲーム:1 名前をつける ]
    Chapter.17 [ じゃんけんゲーム:2 フォームの起動 ]
    Chapter.18 [ じゃんけんゲーム:3 乱数の種 ]
    Chapter.19 [ じゃんけんゲーム:4 イベント ]
    Chapter.20 [ じゃんけんゲーム:5 引数 ]
    Chapter.21 [ じゃんけんゲーム:6 役判定 ]
    Chapter.22 [ じゃんけんゲーム:7 予測と制限 ]
    Chapter.23 [ Withステートメント ]
    Chapter.24 [ 画像を表示させる ]
    Chapter.25 [ 画像表示の発展形 ]
    Chapter.26 [ 繰り返し処理 For文 ]
    Chapter.27 [ 繰り返し処理 Do~Loop文 ]
    Chapter.28 [ Exitステートメント ]
    Chapter.29 [ フォーム上の位置情報 ]
    Chapter.30 [ API基礎知識 ]
    Chapter.31 [ API補足知識 ]
    Chapter.32 [ メインループを考える ]
    Chapter.33 [ 同期処理の概念 ]
    Chapter.34 [ 移動処理その1:画面設定と考え方 ]
    Chapter.35 [ 移動処理その2:DoEvents ]
    Chapter.36 [ 移動処理その3:キー入力判定API ]
    Chapter.37 [ 条件分岐のさらなる探求 Select Case ]
    Chapter.38 [ アニメーション ]
    Chapter.39 [ 配列変数 ]
    Chapter.40 [ ゲームの初期化 ]
    Chapter.41 [ シューティングゲーム1:ゲーム設計 ]
    Chapter.42 [ シューティングゲーム2:メインプロセス ]
    Chapter.43 [ シューティングゲーム3:構造体 ]
    Chapter.44 [ シューティングゲーム4:定数 ]
    Chapter.45 [ シューティングゲーム5:プレイヤーキャラクター ]
    Chapter.46 [ シューティングゲーム6:ショットを撃つ① ]
    Chapter.47 [ シューティングゲーム7:ショットを撃つ② ]
    Chapter.48 [ シューティングゲーム8:Mod演算子の活用 ]
    Chapter.49 [ シューティングゲーム9:敵キャラクター登場 ]
    Chapter.50 [ シューティングゲーム10:衝突判定 ]
    Chapter.51 [ シューティングゲーム11:衝突の実体 ]
    Chapter.52 [ シューティングゲーム12:敵の攻撃 ]
    Chapter.53 [ シューティングゲーム13:爆発エフェクト ]
    Chapter.54 [ シューティングゲーム14:残機数表示① ]
    Chapter.55 [ シューティングゲーム15:残機数表示② ]
    Chapter.56 [ シューティングゲーム16:スコアの表示 ]
    Chapter.57 [ シューティングゲーム17:タイトル画面 ]
    Chapter.58 [ シューティングゲーム18:ボスキャラクター ]
    Chapter.59 [ シューティングゲーム19:最後の仕上げへ ]
    Chapter.60 [ シューティングゲーム20:いよいよ完成STG ]
    Chapter.61 [ カードゲームで使えるめくり効果 ]
    Chapter.62 [ ラジアンと角度 ]
    Chapter.63 [ ラジアンの活用:円運動 ]
    Chapter.64 [ ラジアンの活用:任意の角度へ移動する ]
    Chapter.65 [ APIによるサウンド再生:基礎 ]
    Chapter.66 [ APIによるサウンド再生:MIDIと多重再生 ]
    Chapter.67 [ APIによるサウンド再生:MCIコマンドとループ再生 ]
    Chapter.68 [ Function プロシージャ ]
    Chapter.69 [ 値渡しと参照渡し ]
    Chapter.70 [ デバッグ1:イミディエイトウィンドウ ]
    Chapter.71 [ デバッグ2:ローカルウィンドウ ]
    Chapter.72 [ デバッグ3:コード実行の中断 ]
    Chapter.73 [ オブジェクトってなんだ ]
    Chapter.74 [ プロパティ・メソッド・イベント ]
    Chapter.75 [ オブジェクト変数 ]
    Chapter.76 [ オブジェクトとコレクション ]
    Chapter.77 [ 特殊な繰り返し:For Each ]
    Chapter.78 [ エラー処理 ]
    Chapter.79 [ On Error と GoTo文 ]
    Chapter.80 [ Resumeステートメント ]
    Chapter.81 [ バイトとビット ]
    Chapter.82 [ ウィンドウメッセージとイベント ]
    Chapter.83 [ 文字列の基礎 ]
    Chapter.84 [ 文字列操作① ]
    Chapter.85 [ 文字列操作② ]
    Chapter.86 [ タイピングゲーム1:仕様を決める ]
    Chapter.87 [ タイピングゲーム2:キー入力検知 ]
    Chapter.88 [ タイピングゲーム3:文字列照合 ]
    Chapter.89 [ タイピングゲーム4:判定関数 ]
    Chapter.90 [ タイピングゲーム5:ゲーム画面設計 ]
    Chapter.91 [ タイピングゲーム6:問題文のソート ]
    Chapter.92 [ タイピングゲーム7:動的配列 ]
    Chapter.93 [ タイピングゲーム8:キーダウンイベント ]
    Chapter.94 [ タイピングゲーム9:正打数の表示 ]
    Chapter.95 [ タイピングゲーム10:タイムの表示 ]
    Chapter.96 [ クリックゲーム1:イベントの種類 ]
    Chapter.97 [ クリックゲーム2:画面設計 ]
    Chapter.98 [ クリックゲーム3:クリック座標検知 ]
    Chapter.99 [ クリックゲーム4:キャラクター準備 ]
    Chapter.100 [ クリックゲーム5:キャラクターの配置 ]
    Chapter.101 [ クリックゲーム6:キャラクター移動とNot演算子 ]
    Chapter.102 [ クリックゲーム7:クリックのヒット判定 ]
    Chapter.103 [ クリックゲーム8:ヒットマークエフェクト ]
    Chapter.104 [ クリックゲーム9:サウンド処理の実装 ]
    Chapter.105 [ クリックゲーム10:マウスカーソルの変更 ]
    Chapter.106 [ ブロック崩しゲーム1:仕様と概要を決める ]
    Chapter.107 [ ブロック崩しゲーム2:基本概念の確認 ]
    Chapter.108 [ ブロック崩しゲーム3:ベクトルとは ]
    Chapter.109 [ ブロック崩しゲーム4:変数や定数の宣言 ]
    Chapter.110 [ ブロック崩しゲーム5:初期化処理の実装 ]
    Chapter.111 [ ブロック崩しゲーム6:ブロックの配置 ]
    Chapter.112 [ ブロック崩しゲーム7:根幹処理とバーの処理 ]
    Chapter.113 [ ブロック崩しゲーム8:線分と線分の交差を判定 ]
    Chapter.114 [ ブロック崩しゲーム9:線分同士の交点 ]
    Chapter.115 [ ブロック崩しゲーム10:ボールの処理 ]
    Chapter.116 [ ブロック崩しゲーム11:最終調整して完成へ ]
    Chapter.117 [ テキストファイル操作基礎 ]
    Chapter.118 [ テキストファイル操作:読み込み編 ]
    Chapter.119 [ テキストファイル操作:CSV読み込み編 ]
    Chapter.120 [ テキストファイル操作:様々な読込編 ]
    Chapter.121 [ テキストファイル操作:バイナリ編 ]
    Chapter.122 [ テキストファイル操作:暗号化編 ]
    Chapter.123 [ テキストファイル操作:復号化編 ]
    Chapter.124 [ クラスモジュールとは ]
    Chapter.125 [ クラスモジュール:メソッド編 ]
    Chapter.126 [ クラスモジュール:プロパティ編 ]
    Chapter.127 [ クラスモジュール:イベント拡張編 ]
    Chapter.128 [ クラスモジュール:イベント自作編 ]
    Chapter.129 [ APIによる描画処理1:ハンドル ]
    Chapter.130 [ APIによる描画処理2:デバイスコンテキスト ]
    Chapter.131 [ APIによる描画処理3:ペン オブジェクト ]
    Chapter.132 [ APIによる描画処理4:ブラシ オブジェクト ]
    Chapter.133 [ APIによる描画処理5:図形描画準備編 ]
    Chapter.134 [ APIによる描画処理6:図形描画実践編 ]
    Chapter.135 [ APIによる描画処理7:画像描画の仕組み編 ]
    Chapter.136 [ APIによる描画処理8:ビットブロック転送編 ]
    Chapter.137 [ APIによる描画処理9:ラスタオペレーション ]
    Chapter.138 [ APIによる描画処理10:マスク描画 概念編 ]
    Chapter.139 [ APIによる描画処理11:マスク描画 実践編 ]


    コードやVBAに関する質問などはサポート掲示板(別館)までお気軽にどうぞ。




fc2 seotool Excel VBA ゲーム プログラミング 講座

Counter

twitter


Shadow BBS - 影掲示板

VBA 関連書籍



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。