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

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

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



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


スポンサーサイト

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






Chapter.110 [ ブロック崩しゲーム5:初期化処理の実装 ]

■初期化処理を実装する

前回の講座では、Windows API の宣言や変数・定数の宣言などを解説しました。
特別、難しいことをしているわけではありませんでしたが、コードの行数が結構あったのでちょっと面倒でしたね。ただし、ここは全ての根本になる大切な部分ですので、しっかりとやっておきましょう。

さて、今回はゲームの初期化処理について解説します。
ブロック崩しゲームの初期化処理では、ボールやバーの初期配置、各種変数の初期化などを行います。今回の初期化処理でポイントとなるのは、初期化処理自体を完全に単体のプロシージャで行うのではなく、用途に合わせて細分化する、というところになります。

初期化処理を細分化?
さて、実際に中身を見ながら、考えていくことにしましょう。


■初期化のタイミングと役割

ブロック崩しゲームの初期化には、いくつかの種類があると考えることができます。
ここでいう種類というのは、初期化処理が呼び出されるタイミングの違いによる種類です。

例えば、ボールやバーを画面中央において、これからゲームがスタートできるようにする初期化処理を作ったとします。この初期化処理は、ゲームがスタートする前はもちろん、ボールを落としてしまったあとにも呼び出す必要がありますよね。ミスしたあとの再スタート時にも、ボールやバーの初期化は必要となるわけです。

しかし、ブロックの初期配置は、最初の最初、本当のゲームのスタート時にしか呼び出しません。そうしておかないとミスをするたびに、毎回ブロックが復活してしまうことになります。これではゲームをクリアするのが大変ですし、なによりゲームとして変ですよね。

このように、ゲームの種類にもよりますが、初期化処理には呼び出されるべきタイミングの違いがあります。このことを踏まえると、全ての初期化処理をひとつのプロシージャだけで処理するのは間違いだということがわかりますね。複数の初期化処理を用途に合わせて準備しておくことで、ゲーム全体の流れをうまくコントロールすることができるのですね。

今回のブロック崩しでは、ボールやバーなどの初期化を行うプロシージャと、ブロックの配置を行うプロシージャの、ふたつのプロシージャを用意していきます。


■ボールの初期化から

さて、早速ですが初期化処理を実際に記述していきます。

まずは、ボールやバーを初期化するほうのプロシージャから作成しましょう。先にコードを掲載しますので、ちょっと見てください。

Sub Init()

    Dim L As Long
    Dim S As Single
    
    Randomize
    
    With Ball
        L = Int(Rnd * 30) + 30
        S = L * PI / 180
        .aX = 0
        .aY = 0
        .bX = W_Field / 2
        .bY = T_Bar - W_Ball / 2
        .vX = Cos(S)
        .vY = Sin(S)
        .Sp = 3
        .Vis = True
        If Int(Rnd * 2) = 0 Then .vX = -.vX
    End With
    
    With Bar
        .X = W_Field / 2
        .Y = T_Bar + H_Bar / 2
    End With
    
    With UserForm1
        .Ima_bar.Left = (W_Field - W_Bar) / 2
        .Ima_bar.Top = T_Bar
        .Ima_ball.Left = (W_Field - W_Ball) / 2
        .Ima_ball.Top = T_Bar - W_Ball
    End With
        
End Sub

結構な行数がありますね。With ステートメントを活用しながら設定を行っているのがわかると思います。具体的には『ボール構造体への初期値のセット』、『バー構造体への初期値のセット』、『ユーザーフォーム上のコントロールの初期配置』というみっつのおおまかなくくりで処理しています。


最初に登場するのが、ボール管理構造体へのデータのセットです。

ここで、ボール管理構造体の各要素の役割を確認しておきましょう。

(aX, aY) …… ボールの移動後の座標
(bX, bY) …… ボールの移動前の座標
(vX, vY) …… ボールのベクトル
Sp …… ボールの移動スピード
Vis …… ボールが見えているかどうか

たくさんの要素があって紛らわしいですが、よく役割を考えながら、落ち着いて見ていきましょう。

小文字の a から始まっている X と Y は、ボールの移動処理を行う際に使います。ボールが移動したあとの座標をこの変数で管理します。同様に、小文字の b から始まっている X と Y もボールの移動に関連した処理で使いますが、こちらはボールが移動する前の座標を管理します。

小文字の v から始まっている X と Y がありますね。
これはベクトルです。ボールの移動ベクトルを管理するのが vX と vY です。そしてボールの移動スピードを管理する Sp 、ボールの今現在の可視状態を管理する Vis 、これらがボール管理構造体の全容です。

上記の役割を踏まえたうえで、初期化処理を見てください。

    With Ball
        L = Int(Rnd * 30) + 30 '①
        S = L * PI / 180 '②
        .aX = 0
        .aY = 0
        .bX = W_Field / 2
        .bY = T_Bar - W_Ball / 2
        .vX = Cos(S)
        .vY = Sin(S)
        .Sp = 3
        .Vis = True
        If Int(Rnd * 2) = 0 Then .vX = -.vX '③
    End With

①の部分では、乱数を用いて何らかの処理を行っていますね。ここでは、30~59 の間の乱数を取得しています。仕組みはよく見るとわかると思います。『 Int(Rnd * 30) 』の部分で 0~29 までの乱数が生成され、そこに30を加算しているので、結果的に 30~59 の間の乱数が取得されるようになっています。

ここで得られた数値は、ボールの最初の発射角度になります。毎回同じ方向に向かってボールを打ち出すのではなく、ランダムに角度が変更されるようになっているわけですね。ただ、ボールが打ち出される角度はある程度限定しておかないと、真横にすっとんでいったりしてしまう可能性があります。ですから、乱数を使って 30~59 の範囲に限定して処理しているのです。

②の部分では、先に得られたボールの発射角度を、ラジアンに変換しています。

そこから先は、順次必要な値をセットしているだけです。
ボールの移動後の座標を表す aX と aY は、初期値は 0 です。まだ一切移動を行っていないので、ここは深く考えずに 0 を入れておいて問題ありません。
ボールの移動前の座標は、bX と bY でしたね。bX には、ボールの横位置が入ります。ボールは初期状態では画面の中央(ちょうどバーの上に乗っているような感じ)に置かれるようにしますので、フィールドの幅を半分にした数値を設定します。W_Field は、フィールドの横幅を表す定数でしたね。これを 2 で割った数を bX には指定します。
bY の場合はちょっとわかりにくいかもしれません。T_Bar は、バーの高さを表す定数です。そしてそこからボールの大きさを表す定数W_Ball の半分を引いています。こうすることで、ちょうどバーの上にボールが乗っかっているような感じになります。

620.gif

さて、続いては vX と vY 、つまりベクトルです。
ベクトルは最初に乱数を使って算出していたラジアンを使って求めます。横向きのベクトルを表す vX には、コサインを使って求めた数値を入れます。同様に vY にはサインを使って求めた数値を入れます。これは簡単ですね。

そして、ボールの移動スピードの初期値を Sp に入れます。さらに、ボールは初期状態では見えていないとおかしいですから Vis にも True が入りますね。

最後に③の部分。ここでは、再度乱数を用いた処理を行っていますね。
ボールのベクトルの向きを、50%の確立で反転させています。最初に vX に入る値は必ずプラスの数値になります。しかしこのままでは、毎回必ず右方向に向かってボールが移動することになってしまいますので、半分の確立で符号を反転させることによって、ランダムに左方向へも移動するようにしているのですね。

ボールの初期化処理だけでも、これだけ濃い内容になってしまいました。
焦らず、ひとつひとつ意味を考えながら理解していってくださいね。


■続いてバーの初期化

さて、続いてはバーの初期化です。こちらはボールに比べるとかなり簡易です。

    With Bar
        .X = W_Field / 2
        .Y = T_Bar + H_Bar / 2
    End With

バーのほうは、必要な情報がその位置だけなので、ここではそれを設定しています。ボールのときと同じように、ここでも定数をうまく活用して値を設定しています。
横位置を表す X の要素には、フィールドの幅の半分の数値を設定します。これはボールのときと全く同じですね。画面の中央に横位置を合わせているわけです。縦位置は、バーの高さを表す定数 T_Bar に、バーの縦幅の半分をプラスして設定しています。


■最後にユーザーフォーム上の設定を行う

さて、ボールとバーの管理構造体にデータをセットすることができました。あとは、ユーザーフォーム上にあるコントロールの初期配置を行えば初期化は完了です。

    With UserForm1
        .Ima_bar.Left = (W_Field - W_Bar) / 2 'バーの横位置(Left)
        .Ima_bar.Top = T_Bar 'バーの縦位置(Top)
        .Ima_ball.Left = (W_Field - W_Ball) / 2 'ボールの横位置(Left)
        .Ima_ball.Top = T_Bar - W_Ball 'ボールの縦位置(Top)
    End With

ここでも、イヤと言うほど定数がたくさん登場しています。

アルファベットの W から始まる定数は、全て横幅を表す定数であり、アルファベットの H から始まる定数は、縦の幅を表す定数です。このことを踏まえて落ち着いてみていけば、おおよそ何をやっているのかはわかると思います。

定数の宣言を行った前回の講座でも書きましたが、定数を用いることの利点が今回解説したプロシージャを見るとよくわかります。一見すると、定数を利用したことによって文字数が増えますから、わかりにくく感じるかもしれません。しかし、今後、バーの大きさやボールの大きさを変更したいと思ったとき、今回解説したプロシージャには一切手を加える必要はありません。定数の宣言部分で、設定している値を変更すればいいだけなのです。

定数を用いた処理を記述することに対して、最初はどうしても戸惑いを感じるかもしれません。しかし、これには是非、慣れておいてほしいと思います。あとあとのメンテナンス性を考える場合、定数を利用したコードの記述は大きな武器になります。
今回の初期化プロシージャは、たとえフィールドの大きさが変更されようが、ボールの大きさが変更されようが、はたまたバーの大きさが変更されようが、一切修正することなく対応できる完璧な初期化プロシージャになっています。これは、定数を用いてあらゆる処理を行っていることによって、初めて可能になることなのです。


■まとめ

さて、今回は初期化処理ひとつを取り上げて、じっくりと解説してきましたがどうでしたでしょうか。ボールの初期化の部分は、かなりわかりにくく感じると思いますが、落ち着いて考えてみてくださいね。構造体の各要素の役割をきちんと理解し、定数を使って値を設定していけばおのずとうまくいくはずです。実際にゲームが動くようになってくると、もっとイメージが湧きやすいと思うので、あとからじっくり見直してみるというのもありだと思います。

最初に書いたとおり、今回のブロック崩しでは、初期化ルーチンをブロックの初期化と、それ以外の初期化に細分化して作ります。今回作成した初期化処理はブロック以外のボールとバーの初期化を行いましたね。次回は、ブロックの初期化処理に取り組んでいく予定です。


■格言

初期化処理を目的別に作成する
構造体の要素の意味を踏まえて考える
定数を用いて処理する


次回のブロックの初期化は、ワークシートにあるデータを拾ってきて処理する、というのをやってみたいと思いますので、お楽しみに。


関連記事






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ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。