mieki256's diary



2020/10/27(火) [n年前の日記]

#1 [godot] Godot Engineで林檎と爆弾をたくさん生成

Godot Enigne 3.2.3 x64 の勉強を兼ねて、Apple Catcher っぽいゲームを作成中。

今回は、 _前回作成した林檎と爆弾 をゲームウインドウ上に大量発生させるシーンを作ってみる。

シーンとノード構成を作成。 :

以下のようなノード構成でシーンを作成。
Node2D
  │
  ├─ Node2D
  │
  ├─ Timer
  │
  └─ Timer

godot_tuto10_generate_items_ss01.png


各ノードの名前を分かりやすく変更しておく。
ItemGenerator (Node2D)
  │
  ├─ Items (Node2D)
  │
  ├─ ItemTimer (Timer)
  │
  └─ RateTimer (Timer)

godot_tuto10_generate_items_ss02.png

  • Items : 発生させた林檎や爆弾を追加していくノード。
  • ItemTimer : 林檎や爆弾の発生間隔を担当するノード。
  • RateTimer : 爆弾が混じる確率を変化させるノード。

Timer は、指定時間毎に「時間だよ」とシグナル(Signal、信号)を出してくれるノード。Signal と何かのメソッドを接続しておくことで、指定時間毎に何かの処理をする、ということができるようになる。

Timerのプロパティを変更。 :

ItemTimer の時間設定を変更。Wait Time を 0.2秒に。Autostart も有効に。

godot_tuto10_generate_items_ss03.png


RateTimer の時間設定を変更。Wait Time を 1秒に。Autostart も有効に。

godot_tuto10_generate_items_ss04.png

スクリプトをアタッチ。 :

ItemGenerator にスクリプトをアタッチする。

godot_tuto10_generate_items_ss05.png


スクリプト、ItemGenerator.gd を記述。

godot_tuto10_generate_items_ss06.png

内容は以下。

_ItemGenerator.gd
extends Node2D

export (PackedScene) var Apple
export (PackedScene) var Bomb
export var w = 96
var rnd = RandomNumberGenerator.new()
var screen_size
var born_rate = 100
var born_enable = false

func _ready():
    rnd.randomize()
    screen_size = get_viewport_rect().size
    born_rate = 100
    born_enable = false
    
    start()  # Delete in production environment

func start():
    born_enable = true
    born_rate = 100

func stop():
    born_enable = false

func generate_item():
    if born_enable:
        var x0 = w / 2
        var x1 = screen_size.x - (w / 2)
        var x = rnd.randi_range(x0, x1)
        var item
        if rnd.randi_range(0, 100) > max(20, born_rate):
            item = Bomb.instance()
        else:
            item = Apple.instance()
        item.position.x = x
        item.position.y = -w
        $Items.add_child(item)
    
func update_rate():
    if born_enable:
        born_rate -= 3
        if born_rate <= 1:
            born_rate = 100

  • export (PackedScene) var Apple : 林檎キャラのシーンを記憶する変数。
  • export (PackedScene) var Bomb : 爆弾キャラのシーンを記憶する変数。

  • _ready(): 初期化処理。
  • start() : 発生処理開始。実行フラグを立てる。
  • stop() : 発生処理停止。実行フラグを下す。
  • generate_item() : 林檎か爆弾を発生させる処理。ランダムなx座標位置で、Items に登録していく。
  • update_rate(): 爆弾が混ざってくる確率を変化させる。

  • vat item = Apple.instance() で、Apple のインスタンスが得られる。
  • add_child(item) で、item を自分の子ノードとして追加できる。
  • $Items.add_child(item) なら、自分の子ノードの Items に、item を子ノードとして追加する。

  • export var xxxx と書いておけば、GUIで変数の値を設定できるようになる。
  • export (PackedScene) var xxxx なら、シーンを記憶できる変数になる。

今回は、林檎のシーン Apple.tscn と 爆弾のシーン Bomb.tscn をドラッグアンドドロップで設定しておく。

godot_tuto10_generate_items_ss07.png


変数 Apple と、変数 Bomb に、Apple.tscn、Bomb.tscn が登録(?)された。これでスクリプト内から Apple と Bomb を使える状態になった。

godot_tuto10_generate_items_ss08.png

シグナルとメソッドを接続。 :

Godot Engine の各ノードは、何かの条件を満たした時に「xxxになったよ」的お知らせとして「シグナル(Signal、信号)」を発行する。例えば、Timerノードは設定された時間が経過すると timeout() シグナルを発行する。timeout() シグナルと何かのメソッドを接続しておけば、設定時間毎に何かの処理が実行される状態を作れる。

今回は、以下のシグナルとメソッドを接続する。
  • ItemTimer の timeout() → ItemGenerator.gd 内の generate_item()。林檎か爆弾の発生処理メソッド。
  • RateTimer の timeout() → ItemGenerator.gd 内の update_rate()。爆弾が発生する確率を変化させるメソッド。

ItemTimer を設定。ItemTimer を選んでから、ノードタブに切り替えて、timeout() を選んで「接続」。

godot_tuto10_generate_items_ss09.png


「メソッドにシグナルを接続」ウインドウが表示される。

godot_tuto10_generate_items_ss10.png


ItemGenerator を選んで、受信側メソッドに「generate_item」を入力して「接続」。「()」は打ち込まなくていい。

godot_tuto10_generate_items_ss11.png


メソッドとシグナルが接続されると、スクリプトのエディタ画面で、メソッド名の左側に「シグナルが接続されてるよ」と示す緑のアイコンが表示される。

godot_tuto10_generate_items_ss12.png


RateTimer を設定。RateTimer を選んでから、ノードタブに切り替えて、timeout() を選んで「接続」。

godot_tuto10_generate_items_ss13.png


ItemGenerator を選んで、受信側メソッドに「update_rate」を入力して「接続」。

godot_tuto10_generate_items_ss14.png


スクリプトのエディタ画面で、update_rate() の左側にも「シグナルが接続されてるよ」アイコンが表示された。

godot_tuto10_generate_items_ss15.png


ItemGeneratorノードを選択してからF6キーを押して実行してみる。次々に林檎や爆弾が発生してくれた。

godot_tuto10_generate_items_ss16.gif

しばらく動かし続けると爆弾の出現頻度が高くなって、ある時間を超えるとまた林檎だけ出てくる状態になる。それらしく動いてくれた。

アタリ判定のMask設定を変更。 :

今の状態では林檎と爆弾の発生間隔が長いので見た感じそれほどおかしくはないけれど…。例えば、ItemTimer の Wait Time を小さくすると林檎と爆弾の発生数が増えて、ところどころの林檎や爆弾が回転してる感じになる。これは林檎や爆弾同士がぶつかり合ってその際に回転してしまうから。

林檎や爆弾はプレイヤーキャラとぶつかればいいのであって、林檎や爆弾同士でぶつかる必要は無い。そこで、林檎キャラや爆弾キャラの Collision 設定を変更して、林檎や爆弾同士では衝突判定をしない・アタリを取らないようにする。

Apple.tscn を開いて、Collision → Mask を全てオフにする。デフォルトでは一番左だけチェックが入っているはず。

godot_tuto10_generate_items_ss17.png


Bomb.tscn も開いて、Collision → Mask を全てオフにする。

godot_tuto10_generate_items_ss18.png


これで、林檎や爆弾同士では衝突判定をしない状態になった。

プレイヤーキャラと林檎・爆弾の大量発生まで作れたので、次回はゲームのメインシーンを作ってそれぞれ合体させてみたい。

以上です。

過去ログ表示

Prev - 2020/10 - Next
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project