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

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

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



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


スポンサーサイト

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






Chapter.46 [ シューティングゲーム6:ショットを撃つ① ]

■前回の謎

さて、前回はかなり長い講座になってしまって、皆さん結構大変だったと思います。
ですが、前回の内容でも言いましたが、ほとんど全ての根本処理を実装させましたので、あとは継ぎ足し継ぎ足しで、どんどんゲームが完成に近づいていきます。ここからは少しペースアップできるはずですから、がんばって進めていきましょう。

まずは、前回の最後に書いた『勘のいい人なら気がつく、おかしなところ』というなぞなぞの答えから考えます。

前回の処理を実装させてコードを実行すると、プレイヤーキャラクターが自由に画面上を動き回ります。このとき目いっぱい右下にキャラクターを寄せてみると、何がおかしいのかきっとわかります。

250.gif

何がおかしいのかわかりましたか?
では、左上に目いっぱい寄せた場合と比較してみましょう。

251.gif

右下に寄せた場合だけ、キャラクターが画面の外側にめり込んでしまっていますね。座標計算は間違っていないのに、どうしてこのような現象が起こるのでしょうか。実はこれ、フレームのせいなんです。

フレームコントロールはその名の通り、ユーザーフォーム上の空間を切り取るフレームの役目を果たします。枠線が表示されて、そこだけが独立した空間になるのですね。
しかしこの枠線、思いっきり拡大してみると、こんな感じになってます。

252.gif

ご覧の通り、この枠線は2ピクセル分の幅があります。つまり、両端それぞれ2ピクセルの合計4ピクセルが、枠線として使われているのです。
これをポイント単位に変換すると、『 4 × 0.75 = 3 』という式が成り立ちますね。ですからフレームコントロールのWidthプロパティが『200ポイント』だとすると、そのうち3ポイントは枠線なので、黒くなっている中身の空間は『197ポイント』しかないということになるわけです。

253.gif

これでは左右対称な処理ができなくなってしまいますので、ちょっと困ります。座標計算は画面の大きさを200として計算しています。この仕組みがキチンと動作するために、フレームコントロールの大きさを、適切なかたちに修正しておきましょう。

具体的には、現状200ポイントに設定されているWidthプロパティを、枠線の分だけ広くすればいいのです。ですからフレームコントロールのWidthHeightを『203ポイント』に修正しておきましょう。
こうしておけばプロシージャ内のコードを修正しなくとも、キチンと端の部分でキャラクターが止まるようになります。はみだし防止処理が完全になりました。謎が解けてすっきりです。


■ショットを撃てるようにするためには

今回の主題『ショットを撃つ』について考えてみましょう。
プレイヤーキャラクターがショットを撃つということは、移動処理と同様、プレイヤーのキー入力をチェックして処理しなくてはいけません。ここまではなんとなく想像がつきますね。

ですので、まずはモジュールの宣言部分、『定数宣言』に次のコードを追加します。

Public Const Shot_Key As Long = 90 'Zキー

これはキーボードのZキーを表すキーコードを、定数として宣言している部分です。ここで定数としてキーコードを宣言しておけば、あとで処理がしやすいですね。
そしてもうひとつ、ショットの大きさを定義する定数です。

Public Const Shot_Size As Single = 3

プレイヤーキャラクターのときにも、その実際の大きさを定数化しましたね。あれと同じ意味のものです。

次に、Publicを使ってひとつ変数を宣言します。

Public Shot_Interval As Long 'ショットの間隔

この『変数Shot_Interval』は、プレイヤーの放つショットの間隔を調節するのに使います。どういうことか、具体的に説明しましょう。


ここまで進めてきた皆さんは、既にメインループについて十分な知識を身につけていると仮定して、これから先の内容を説明していきます。よくわからない人は以前のChapterをよく読んで、理解してから挑戦してみてください。

メインループでは、同期処理を行って、1秒間に何回ループするか定義していましたね。
前回載せたメインループのコードをよく見ていただければわかりますが、今回のシューティングゲームは1秒間に30回強、ループするようになっています。
でもこれ実はものすごい速さです。1回あたり約0.03秒ですからね。
まぁこれも、人間からみるとものすごい速さですが、昨今のパソコンにとっては大したスピードでもないのだからすごいですよね。

とにかく、普通は、人間がキーを入力するとき、0.03秒でキーを押して離してが出来るとは思えません。タイピングのプロじゃあるまいし、そんなにものすごく速いスピードでシューティングゲームを遊ぶのは無理です。
しかしループ中は、毎回キーの入力をチェックしていますよね。
もし、キーが押されていることを判断材料としてショットを発射してしまうと、1秒間に30回以上ショットが発射されてしまいます。これはちょっと多すぎです。処理能力的にも見ても、これは少し無理があります。

そこで、先ほど宣言した変数Shot_Intervalを有効に使って、この問題を解決します。

ショットが発射された瞬間から、それ以降のループの中で、この変数を毎回プラス1ずつカウントするようにします。そして、一定の数までカウントされるまでは、ショットを再び発射することができないようにしてしまいます。
例えば、変数Shot_Intervalが10になるまでカウントするとすれば、1秒間に約3発のショットが発射できることになります。1秒間に約30回ループするからですね。
カウント待ちする回数を増やせば間隔が長くなり、少なくすれば、間隔が短くなります。今回はカウント待ち回数を『 7 』に設定してやってみます。これなら、1秒間に約4~5発程度のショットが発射されるようになります。

If Shot_Interval = 0 Then
    If GetAsyncKeyState(Shot_Key) < 0 Then
        ショットを発射する
        Shot_Interval = 1
    End If
Else
    Shot_Interval = Shot_Interval + 1
    If Shot_Interval > 7 Then Shot_Interval = 0
End If

さて、上のコードを見てください。
これは、前回記述したプロシージャ『Player_Action』に追加する、ショットを管理するためのコードです。
先ほどPublicで宣言した変数Shot_Intervalをどのように使っているかがポイントとなります。まず、始めから条件分岐による判断を行っていますね。変数Shot_Intervalの値が0かどうかを判断しています。

変数Shot_Intervalの値がもし0だった場合には、これはショットを撃てる状態であると判断します。ですのでキーが押されているかどうかその次のIf文でGetAsyncKeyStateを使って判断しています。もしキーが押されていた場合は、その後のショットを発射する部分に処理が移ります。

ひとたびショットを発射したら、変数Shot_Intervalの値を1にします。ショットが発射されると同時に、この変数Shot_Intervalの値が1になることで、この次のループが回ってきたときには一番最初のIf文を通ることが出来なくなります。よって、キーが押しっぱなしになっていてもショットは絶対に発射されません。
変数Shot_Intervalが0じゃないとき、この場合はショットが発射できないと判断するわけです。
しかしこのままでは二度とショットが撃てなくなります。ですから、変数Shot_Intervalが0ではなくなった場合の処理が必要ですね。それが『Else』以降の部分ですね。

ここでは変数Shot_Intervalを毎回プラス1ずつ増やしていきます。そして、その値が7より大きい、つまり8になった瞬間に、再び変数Shot_Intervalを0に戻します。

こうすることで、次のループでは、もしキーが押されていればショットが発射できるようになります。

このように、変数Shot_Intervalを有効に利用して、理論上は8ループに1回しかショットが発射されないようにするわけですね。

今回載せたコードは『ショットを発射する』の部分がまだ未完成です。これは次回作成するとして、その時に完成版コードを載せるようにするつもりです。とりあえず今回はその考え方や仕組みを理解できていればいいでしょう。


■ショットの扱い

さて、これでショットを発射するための『プレイヤーキャラクター側の準備』はできました。あとやらなくてはならないのは、『ショットそのものを準備する』ということです。

具体的には、次のようなことをやらなくてはいけません。

ショットの画像を準備する
ショットが生成されるプロシージャを作成する
ショットの移動を管理するプロシージャを作成する

今回は、画像をイメージコントロールにロードするところまでやってしまいましょう。

ショットの画像は非常に小さいです。ちょっとわかりづらいかな?

Shot01.gif

この画像を使って、ショットに見立てたイメージコントロールを用意します。
ショット用の画像は大きさが8×8ピクセルです。ということは……もうわかりますね。ショット用のイメージコントロールのWidthプロパティとHeightプロパティは6ポイントに設定すればいいわけです。

今回はプレイヤーキャラクターが放つショットとして、最大で画面上に5発まで発射できるようにしたいと思います。そこで、ユーザーフォーム上に、5つのイメージコントロールを追加します。

254.gif

言うに及ばず、これらの追加したイメージコントロールも、枠線の消去や、透過処理設定をしておきます。これは以前の講座で詳しく解説しましたね(Chapter24Chapter25を参照)。

イメージコントロールの名前の変更はキチンとやっておきましょう。次回以降のコードでは、この名前でイメージコントロールを指定します。特別な理由がない限りはこの名前をしっかり設定しておいてくださいね。

そして、忘れてはならないのが、このショット用イメージコントロールのVisibleプロパティの設定です。
Visibleプロパティは、そのコントロールが見えているかいないかを定義するプロパティです。もし、このまま画面上に見えてしまっていたら、撃たれていないショットが画面上に置いてあるみたいで、なんだか変ですよね。

そこで、これらの5つのイメージコントロールは、全てVisibleプロパティをFalseに設定しておきます。こうしておけば、ユーザーフォームが実際に表示されるときには、画面上から見えなくなります。画面上からなくなってしまうわけではありません。あくまでも、見えないだけです。
なくなってしまったわけではないので、あとでコードの中でVisibleプロパティにTrueを設定すれば、キチンと画面上に現れます。それはショットを発射するときに行いますので、現段階ではVisibleプロパティにFalseが設定されていれば大丈夫です。

これで、ユーザーフォーム上のコントロールは準備できました。

次回は、ショットを撃つためのコードを記述します。今回の講座内容をキチンと理解しておいてください。


■格言

フレームは枠線を考慮した大きさに設定
ループ内でカウントして適切なショット間隔に


プレイヤーキャラクターの弾数はとりあえず5発でやります。
関連記事






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