俺に解るように説明する "Godot Engine 3.x" 入門+

ゲームエンジン Godot Engine に関すること。入門とか使い方とかチュートリアルとか、あれとかこれとか。日本語解説。

Godot 音シュー04「カウントダウンして曲再生」

準備は整った。スクリプトする。ルートの「Node」ノードに貼る。(前回のスクショにもう貼ってあるのが見えてるけどな。)

f:id:ore2wakaru:20180525215310p:plain

なかなかキューブを飛ばすまで進まないなー。


貼るスクリプト
extends Node

var nASP_kyoku          #曲AudioStreamPlayer操作用
var nASP_kouka          #効果音AudioStreamPlayer操作用
var nLabel              #カウントダウン数字を表示するラベル操作用
 
var BPM = 113.0         #BPM 
var SPB = 60.0 / BPM    #1ビートが何秒か(ビートの間隔) second(s) per beat

var beatTimer = 9       #何ビート後に曲をかけるか
var myTime = 0.0        #シーン始まってからの経過時間(SPB越えたら引くけど)

func _ready():
    nASP_kyoku = get_node("AudioStreamPlayer_kyoku")
    nASP_kouka = get_node("AudioStreamPlayer_kouka")
    nLabel = get_node("Label")

func _process(delta):
    #カウントダウン > 曲play
    if beatTimer > 0:
        countDownPlay(delta)

func countDownPlay(dt):
    myTime = myTime + dt
    if myTime - SPB > 0:
        myTime = myTime - SPB
        beatTimer = beatTimer - 1
        match beatTimer:
            8:
                nASP_kouka.play()
            6:
                nASP_kouka.play()
            4:
                nLabel.text = "3"
                nASP_kouka.play()
            3:
                nLabel.text = "2"
                nASP_kouka.play()
            2:
                nLabel.text = "1"
                nASP_kouka.play()
            1:
                nLabel.hide()
            0:
                nASP_kyoku.play()


すばらしい解説

変数部分

f:id:ore2wakaru:20180525195001p:plain

L3 ~ 5

  • いつものようにノードを操作できるように変数を用意。

L7 ~ 8

  • BPM は前回調べたやつを書き込む。"113"
  • SPB には 1 ビートが何秒かを入れておく。BPM は 60 秒で何ビートかなんだから、"60 / BPM" で 1 ビートが何秒かが出る。シーンの開始時間から引いたとき答えがプラスになったら 1 ビート過ぎたという合図になる。

L9 ~ 10

  • コメントに書いた通り。
  • だけど、myTime に初期値 "0.0" と入れておかないとエラーになるから注意。


_ready()関数部分

f:id:ore2wakaru:20180525200309p:plain

L14 ~ 16

  • いままでとおんなじ風に、普通にセットしてるダケ。


_process(delta)関数部分

f:id:ore2wakaru:20180525200702p:plain

L20 ~ 21

  • beatTimer が "0" より大きければ、自作関数countDownPlay()を呼ぶ。
  • beatTimer countDownPlay() の方で、1 ビート過ぎた毎に "-1" してあるから、数値が "0" になった時点で呼ばなくなる。
  • 大事なのは、countDownPlay()カッコ内で "delta" を渡している事。ただ自作関数を呼んでるだけじゃない。
  • "delta" には前回 _process()関数が呼ばれた時から何秒経ったかの情報が入っている。つまり "delta" を加算していけば、開始からの時間経過が分かるって事だ。
  • だか "delta" には制限があって、この _process(delta) 内でしか使えない。使用範囲、スコープってのがある。
  • そこで、こんな風にカッコ内に変数を書いてやると、コッチで持ってる情報向こうの関数で使う事が出来るようになる。便利。
  • カッコ内の変数を parameter(パラメータ)という。なんか本当は「パマター」って聞こえるけどな。(日本語では引数『ヒキスウ』というらしい。かっこわる)


自作関数countDownPlay(dt)関数部分

f:id:ore2wakaru:20180525202607p:plain

L23

  • さっきはカッコの中が "delta" なのに、コッチでは "dt" になっている。これは、コッチの関数内では、"dt" っていう変数名で使うよって事を表している。向こうの関数内での "delta" の値をコッチの関数内で使う変数 "dt" に受け渡して、データを使えるようにした感じだ。

L24 ~ 27

  • 経過時間を加算して(L24)、もし 1 ビート分過ぎてたら(L25)、時間から 1 ビード分の時間を引いて(L26)、beatTimer からも "1" 引く(L27)。
  • 結局、時間経過で 1 ビート分過ぎたら beatTimer から "1" 引くにはどうすればいいかを考えてこうした。もっといい方法があったら知りたい感じ。

L28 ~ 45

  • ここまでで、beatTimer は "8 ~ 0" で変化する。
  • その変化をとらえて何かする方法として、今回、match ステートメントを使ってみた。黄色いから iffor と同じキーワード。

よく分からないけど、どうやら

match 変数:
    条件a:
        変数が条件aの時、実行されることを書く
    条件b:
        変数が条件bの時、実行されることを書く
    条件c:
        変数が条件cの時、実行されることを書く

こんな感じで使うっポイ。(見て分かる人はココ参照:GDScript — Godot Engine latest documentation

  • というわけで、開始から 1 ビート時間過ぎたら、つまり、betaTimer が "8" の時「カン♪」とならす。(L29 ~ 30
  • スクリプトで音を出すには、play() 関数。効果音が入った方の「AudioStreamPlayer」が指定されている事な。
  • さらに 2 ビート時間たったら、「カン♪」。
  • で、「カン♪」「カン♪」「カン♪」の時には音だけじゃなくて、「Label」ノードが持ってる text 変数をいじって、カウントダウンの画面表示もしてる。
  • 曲がかかる 1 ビート前にラベルを非表示(hide() 関数)にして、
  • 最後に beatTimer が "0" になったら、やっとこが入ってる「AudioStreamPlayer」をプレイする。

これで、

「カン♪、カン♪、『3』カン♪『2』カン♪『1』カン♪」 > 曲

が実現できた。よかったよかった。


次回は、キューブを飛ばしてタイミングよくキーを押したら、「good」となるような仕組みを考えていこうと思う。

考えるだけな。