2019年02月12日

ActiveBasicとDXライブラリでゲームプログラミング!~第4回・分岐する骨組みを作ろう!

n88_reon.gif
玲音:どうもこんにちは! 玲音です。先に言っておくと、楓ちゃんを引きずり込んだ、なんてことはありませんので!

n88_kaede.gif
楓:あ、先手打たれちゃった。玲音先輩の後輩の楓です! 先輩、今日は何をするんですか?

n88_reon.gif
うん。今日は、前回話した通り、ゲームプログラムの骨格の部分を作っちゃおうと思います! それじゃさっそく、始めていきましょう!

n88_kaede.gif
はーい!

~一つの流れで、複数のシーンに飛ばすには?~

n88_reon.gif
さてさて。まずは、これが今までの講座で使っていた、プログラムの基本骨格だったね。

=-=-=-=-=-=-=-=-=-=-
#include "Dxlib.sbp"

''初期処理
dxChangeWindowMode(1)
dxDxLib_Init()
dxSetDrawScreen(DX_SCREEN_BACK)

Do
''画面をクリア
dxClearDrawScreen()

''何等かの処理

''画面に反映
dxScreenFlip()
''メッセージ処理
If dxProcessMessage() = -1 Then
Exit Do
End If
Loop

''後処理
dxDxLib_End()
End
=-=-=-=-=-=-=-=-=-=-

n88_kaede.gif
はいっ。このDoとLoopの間、''何等かの処理、ってコメントの下に処理を書くんでしたよね。

n88_reon.gif
うん。でも、このまま使うとちょっと問題があるの。わかる?

n88_kaede.gif
問題、ですか? うーん……。

n88_reon.gif
今までは、キャラを動かしたり、文字を表示したりと、いわばゲームのプレイ中の部分だけを作っていたけど、実際のゲームには他にも色々なシーンがあるよね? タイトル画面とかクリア時のシーンとか、ゲームオーバーとか。

n88_kaede.gif
あっ、それはそうですね! それをどうするか、ですか。うーん……。

n88_reon.gif
ヒント。どのシーンでも、画面を描いて、それを反映させる、って処理は共通だよね? 違うのは描くのがタイトル画面か、それともゲームの背景やキャラか、ってだけで。

abdx1902-01.jpg

n88_kaede.gif
なるほど! ということは、何らかの方法で、タイトル画面を描く処理や、ゲーム中の画面を描く処理とかに分岐させればいいわけですねっ。こんな風に。

abdx1902-02.jpg

n88_reon.gif
うん、その通り! 具体的にどうするかは、これから解説するよ。

~Select Caseを使おう!~
n88_reon.gif
さてさて。その分岐させるために、変数とSelect Case文と、そしてサブプロシージャを使います。

n88_kaede.gif
変数はいわば、数や文字列をいれておく箱のようなものでしたよね。確か、使う前に、Dim命令であらかじめ宣言する必要があるんでしたっけ。こんな風に。

=-=-=-=-=-=-=-=-=-=-
Dim 変数の名前 As 変数の型

(例)
Dim hensu As Integer
=-=-=-=-=-=-=-=-=-=-

n88_kaede.gif
それで、Select Caseはどんな文なんでしたっけ?

n88_reon.gif
うん。それは、指定した変数や式の内容によって、処理を分岐させる文だよ。このように使うの。

=-=-=-=-=-=-=-=-=-=-
Select Case 変数or式
Case 値1
 処理1
Case 値2
 処理2
……
End Select

(例)
Select Case hensu
Case 0
 dxDrawString(50, 40, "hensu=0", white)
Case 1
 dxDrawString(50, 40, "hensu=1", white)
Case 2
 dxDrawString(50, 40, "hensu=2", white)
End Select
=-=-=-=-=-=-=-=-=-=-

n88_reon.gif
この例だと、変数hensuが0のときは、Case 0の下の、dxDrawString(50, 40, "hensu=0", white)が実行されて、1のときは、Case 1の下の、dxDrawString(50, 40, "hensu=1", white)が実行されるんだよ。

n88_kaede.gif
なるほどっ。例えば、上の例で、0、1、2以外の値のときに分岐させる処理を作りたいときはどうするんですか?

n88_reon.gif
そのときは、Case Elseを使うんだよ。これを入れると、Case 〇で指定した数以外の場合は、このCase Elseの下の処理を実行するようになるの。

=-=-=-=-=-=-=-=-=-=-
Select Case hensu
Case 0
 dxDrawString(50, 40, "hensu=0", white)
Case 1
 dxDrawString(50, 40, "hensu=1", white)
Case 2
 dxDrawString(50, 40, "hensu=2", white)
Case Else
 dxDrawString(50, 40, "hensu=X", white)
End Select
=-=-=-=-=-=-=-=-=-=-

n88_reon.gif
上の例の場合なら、hensuが0、1、2以外の場合は、Case Elseの下のdxDrawString(50, 40, "hensu=X", white)が実行されるんだよ。

n88_kaede.gif
なるほどっ!

~サブプロシージャって何?~
n88_reon.gif
さてさて。次に行くね。サブプロシージャというのは、昔のBASICにあった、サブルーチンを発展したようなものだよ。
サブプロシージャは次のように書きます。

=-=-=-=-=-=-=-=-=-=-
Sub サブプロシージャ名(引数1 As 引数1の型, 引数2 As 引数2の型, ……)
実際の処理
End Sub
=-=-=-=-=-=-=-=-=-=-

n88_reon.gif
そして、呼び出すときはこのように書きます。
=-=-=-=-=-=-=-=-=-=-
サブプロシージャ名(引数1, 引数2……)
=-=-=-=-=-=-=-=-=-=-

n88_kaede.gif
先輩っ。この引数ってなんですか?

n88_reon.gif
うん。それは、呼び出し元からサブプロシージャに渡す値のことだよ。例えば。

=-=-=-=-=-=-=-=-=-=-
Sub SubProc1(hiki1 As Integer, hiki2 As Integer)

End Sub

SubProc1(3, 5)
=-=-=-=-=-=-=-=-=-=-

n88_reon.gif
とすると、変数hiki1に3が、hiki2に5が入るの。そうそう。Subのところで指定した引数を入れる変数(例の場合だと、hiki1とhiki2)は、このサブプロシージャの中。具体的には、SubとEnd Subの間でしか使えないから気を付けてね。

abdx1902-03.jpg

n88_kaede.gif
はーいっ。

n88_reon.gif
さてさて。例にある通り、サブプロシージャを呼び出すと、該当するSubからEnd Subの間の処理が実行されます。そして、End Subまで実行したところで、元の処理に戻るよ。

abdx1902-04.jpg

n88_kaede.gif
なるほどっ。

n88_reon.gif
最後にもう一つ。今扱ったようなSubを使ったサブプロシージャでは、呼び出し元に処理結果を返すことはできないの。返したいときは、Subではなく、Functionを使うよ。Functionを使う場合は、このように書きます。

=-=-=-=-=-=-=-=-=-=-
Function サブプロシージャ名(引数1 As 引数1の型, 引数2 As 引数2の型, ……) As 戻り値の型

End Function
=-=-=-=-=-=-=-=-=-=-

n88_reon.gif
値を返すときは、サブプロシージャ名と同じ名前の変数に結果を入れてあげればOKだよ。こんな風にね。あ、この変数については、Dim命令で宣言する必要はないからね。それは、SubやFunctionのところで宣言する、引数を入れる変数についても同じ。

n88_kaede.gif
ふむふむ。

n88_reon.gif
そして、Functionのサブプロシージャは、それ自体を変数や関数のように使うことができるよ。だから、変数に代入したり、式に使ったりすることができるの。

=-=-=-=-=-=-=-=-=-=-
hensu1 = SubProc1(3, 5)
※hensu1に、SubProc1から返ってきた値を入れる

hensu2 = SubProc2(4) + 5
※hensu2に、SubProc2から返ってきた値に5を足したものを入れる
=-=-=-=-=-=-=-=-=-=-

n88_kaede.gif
なるほど、わかりましたっ。

~骨格を作ろう!~
n88_reon.gif
さて、それではここまで説明してきた、変数とSelect Case、そしてサブプロシージャを使って、骨組みを作ってみましょう! どうすればいいかな?

n88_kaede.gif
はーい! シーンが切り替わるときに、変数にそのシーンを表す数を入れて、そしてSelect Caseで、その変数で分岐させて、それぞれの画面を描くサブプロシージャを呼び出せばいいんじゃないですか?

n88_reon.gif
はい、正解! それではやっていきましょう。最初に紹介した基本の骨組みに追加する形でやっていくからね。
さてさて。まずは、そのシーンを表す変数が必要だよね。#include "Dxlib.sbp"の下あたりに、次の文を入れてね。

=-=-=-=-=-=-=-=-=-
Dim scene As Integer
=-=-=-=-=-=-=-=-=-

n88_kaede.gif
このsceneという変数に、シーンを表す数を入れるんですねっ。

n88_reon.gif
そうだよ。さらにその下に次の文も入れましょう。

=-=-=-=-=-=-=-=-=-=-
Const TITLE = 0
Const GAME = 1
Const GAMEOVER = 2
=-=-=-=-=-=-=-=-=-=-

n88_kaede.gif
先輩。このConstって文はなんですか?

n88_reon.gif
これは定数といって、簡単にいえば、単語と値を結びつけるものだよ。これをやっておくと、例えば、式でGAMEという単語を使うと、このGAMEという単語が1と同じ意味になるの。

abdx1902-05.jpg

n88_kaede.gif
なるほど。確かに、GAMEとかいう単語のほうがわかりやすいですよねっ。

n88_reon.gif
うん。さて、まずはゲーム開始時はタイトルだよね。なので、Doの直前に、次の一文をいれよう。

=-=-=-=-=-=-=-=-=-=-
scene = TITLE
=-=-=-=-=-=-=-=-=-=-

n88_reon.gif
さて、ここからいよいよ本番。''何らかの処理、ってコメントの下に、次のSelect Case文をいれましょう!

=-=-=-=-=-=-=-=-=-=-
Select Case scene
Case TITLE
  TitleProc()
Case GAME
GameProc()
Case GAMEOVER
  OverProc()
End Select
=-=-=-=-=-=-=-=-=-=-

n88_kaede.gif
変数sceneの値がTITLE(0)のときはTitleProc、GAME(1)のときはGameProc、そしてGAMEOVER(2)のときはOverProcのサブプロシージャを実行するわけですね。

n88_reon.gif
そうだよ。さて、そしたら、そのサブプロシージャも作っておかなきゃいけないよね。プログラムの一番最後に作っていきましょう。

=-=-=-=-=-=-=-=-=-=-
Sub TitleProc()

End Sub

Sub GameProc()

End Sub

Sub OverProc()

End Sub
=-=-=-=-=-=-=-=-=-=-

n88_reon.gif
これで完成だよ!

n88_kaede.gif
わーい!

n88_reon.gif
次回は、これにさらに追加して、タイトル画面やゲーム画面などを実際に表示させようと思います。お楽しみに!

n88_kaede.gif
次回も楽しみですっ! また次回~!



※次の更新は、2月15日、『師匠TのチャレンジARSゲーム!』の予定です。お楽しみに!