2
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

【Godot Engine】2Dゲームチュートリアル(Part.3)

概要

Godot Engine での2Dゲーム作成チュートリアルの Part.3 (最終回)です。

前回はこちら

↓↓↓

クリックして破壊できるようにする

クリックしてGodotくんを破壊できるようにします。

シグナルの追加

"Enemy"タブをクリックする、またはファイルシステムから「Enemy.tscn」をダブルクリックして、"Enemy"シーンを開きます。
Godot_Engine_-_MyFirstGame_-_Enemy_tscn_と_Steam.png

開いたら、インスペクタのとなりにある「ノード」をクリックします。
Godot_Engine_-_MyFirstGame_-_Enemy_tscn.png

するとシグナルの一覧が表示されます。
シグナルとは、「別のオブジェクトと衝突した」「マウスでクリックされた」など、オブジェクトに対する影響を判定できる信号のことです。
色々とシグナルは用意されていますが、ここでは CollisionObject2D > input_event() を選んで、ダブルクリックします。
Godot_Engine_-_MyFirstGame_-_Enemy_tscn____.png

そのまま「接続」をクリック。
Godot_Engine_-_MyFirstGame_-_Enemy_tscn____.png

するとシグナルを受け取る関数が追加されます。
Godot_Engine_-_MyFirstGame_-_Enemy_tscn____.png
ちなみに関数の左側に表示されている緑色のアイコンは「シグナルで接続されている」ことを示すものとなります。

この関数を以下のように修正します。

Enemy.gd
func _on_Enemy_input_event(viewport, event, shape_idx):
    # 何らかの入力イベントが発生
    if event is InputEventMouseButton:
        # マウスボタンの入力イベント
        if event.is_pressed():
            # クリックしたので、インスタンスを破棄
            queue_free()

input_event() は様々なイベントを受け取るので、まずはイベントがマウスボタンのイベントであるかどうかを判定します。
そしてそれがマウスクリックであれば queue_free() でインスタンスを破棄します。

実行して、マウスクリックでGodotくんが消えることを確認します。
shot.gif

クリア判定

ゲームクリア判定を作ります。

"Main"タブを選ぶ、または ファイルシステムから "Main.tscn" をダブルクリックして、Mainシーンを開きます。
Godot_Engine_-_MyFirstGame_-_Enemy_tscn.png

次にMainノードを選択して右クリックし、「スクリプトをアタッチ」を選択します。
Godot_Engine_-_MyFirstGame_-_Main_tscn.png

そのまま「作成」をクリックします。
Godot_Engine_-_MyFirstGame_-_Main_tscn.png

"Main.gd" スクリプトを以下のように修正します。

Main.gd
extends Node2D

func _process(delta):

    var all_destroyed = true
    # 子ノードをすべて調べる
    for node in get_children():
        if "Enemy" in node.name:
            # 敵が生存している
            all_destroyed = false

    if all_destroyed:
        # ゲームクリア
        OS.alert("ゲームクリア")

        # アプリケーションを終了する
        get_tree().quit()

子ノードをすべて調べて、ノード名に "Enemy" が含まれるオブジェクトが存在しなければゲームクリア、としています。

実行して、すべてクリックするとゲームクリアとなることを確認します。
shot.gif

パーティクルを実装する

最後にGodotくんが消滅するときのパーティクルを実装します。
タブの右隣にある「+」をクリックして、シーンを追加します。
Godot_Engine_-_MyFirstGame_-_Main_tscn.png

「+ その他のノード」をクリックします。
Godot_Engine_-_MyFirstGame.png

検索欄に「Particle」と入力して CPUParticles2D を選んで、作成ボタンをクリックします。
Godot_Engine_-_MyFirstGame.png

作成された CPUParticles2D のノード名を 「Particle」に変更します。
Godot_Engine_-_MyFirstGame____.png

いったん、Ctrl+S (Cmd+S) でシーンを「Particle.tscn」として保存します。
Godot_Engine_-_MyFirstGame____.png

パーティクルの設定

テクスチャの設定

Particleノードを選択して、ノードタブから「インスペクタ」に戻します。
Godot_Engine_-_MyFirstGame_-_Particle_tscn.png

インスペクタから、Drawing > Texture > [空] をクリックして、「読み込み」を選択します。
Godot_Engine_-_MyFirstGame_-_Particle_tscn____.png

パーティクルに使用する画像選択画面が表示されるので、"icon.png" を選びます。
Godot_Engine_-_MyFirstGame_-_Particle_tscn____.png

すると、Godotくんが生成され続けるパーティクルとなります。
shot.gif

初期速度の設定 Initial Velocity > Velocity

発生時の初期速度を設定します。
Initial Velocity > Velocityの値を「150」に変更します。
shot.gif
すると右方向に向けて放出されるようになります。

発生方向の変更 Direction > Spread

発生方向を全方向に変更します。
Direction > Spread の値を「180」にすると±180度となるので、全方向に放出されるようになります。
shot.gif

サイズの変更 Scale > Scale Amount

サイズが大きすぎるので、Scale > Scale Amount を 0.5 にして小さくします。
Godot_Engine_-_MyFirstGame_-_Particle_tscn____.png

また時間経過に合わせてサイズを小さくしたいので、Scale Amount Curve > [空] をクリックして、「新規カーブ」を選びます。
Godot_Engine_-_MyFirstGame_-_Particle_tscn____.png
作成されたCurveをクリックして、カーブグラフを表示し、右クリックしてポイントを追加し、右下がりのカーブを作成します。
shot.gif

すると時間経過で小さくなるパーティクルとなります。
shot.gif

放出タイミングの調整 Time > Explosiveness

クリックでの破壊時にまとめて放出したいので、Time > Explosiveness を「1」にします。
Godot_Engine_-_MyFirstGame_-_Particle_tscn____.png

この指定をすると、まとめて放出されます。
shot.gif

One Shot再生にする Time > One Shot

このパーティクルは一度再生したら終了するタイプなので「One Shot」に変更します。
Time > One Shotにチェックを入れると一度きりの再生となります。
Godot_Engine_-_MyFirstGame_-_Particle_tscn____.png

再び動作を確認したい場合は、One Shotの指定は外して、Emitting にチェックを入れます。
One Shotにチェックを入れたままにすると、Emittingをクリックするたびに再生されます。
shot.gif

もしOne Shotのチェックを外した場合は、チェックを入れるようにしておいてください。

スクリプトのアタッチ

Particleノードを右クリックして、スクリプトのアタッチを選びます。
Godot_Engine_-_MyFirstGame_-_Particle_tscn____.png
「作成」を選択します。
Godot_Engine_-_MyFirstGame_-_Particle_tscn____.png

スクリプトには以下のように記述します。

Particle.gd
extends CPUParticles2D

func start(pos):
    # 放出開始
    emitting = true
    # 位置を設定
    position = pos

func _process(delta):
    if emitting == false:
        # 再生終了
        queue_free()

start() で座標を指定して放出を開始します。
また emitting で終了判定をします。

Enemyからパーティクルを呼び出す

Enemyシーンを選択して、Enemy.gd スクリプトを以下のように修正します。

Enemy.gd
extends Area2D

# パーティクルオブジェクト
var Particle = preload("res://Particle.tscn")

# 画面サイズ
var screen:Rect2

# 移動速度
var velocity:Vector2

……

var Particle = preload("res://Particle.tscn") という記述が追加されています。これは Particleシーンを Enemy.gd で使用するための記述となります。

そして後半の _on_Enemy_input_event()を修正します。

Enemy.gd
func _on_Enemy_input_event(viewport, event, shape_idx):
    if event is InputEventMouseButton:
        # マウスボタンの入力イベント
        if event.is_pressed():
            # クリックしたので、インスタンスを破棄
            queue_free()

            # パーティクルを生成
            var p = Particle.instance()
            # パーティクル再生開始
            p.start(position)
            # ルートノードに設定する
            var root_node = get_parent()
            root_node.add_child(p)

Godotくん破壊時にパーティクルを生成する記述となります。
現在のノード構成では "Enemy" の上に Mainノードがあることが決まっているので、get_parent() で親ノードを取得して、add_child() でぶら下げています。

では、実行してGodotくんの破壊パーティクルが再生されることを確認します。
shot.gif

パーティクルの挙動が今ひとつな感じなので、気になる方はより詳しい使い方を以下のページにまとめていますので参考になるかもしれません。

最後に

ここまでできたら、あとは色々なチュートリアルを試してみるのが良いと思います。
公式のチュートリアルでは、スプライトアニメーションやボタンの作成方法など、色々な機能が使われているので勉強になると思います。

あと、個人的にシューティングを作るときに悩んだことは以下のページにまとめましたので、ひょっとしたら参考になるかも……。



※2021.3.25 追記
フラッピーバードを作るチュートリアル記事を作成しました

ebp6q79hc7t6geipzxcwt702fxho.gif
このようなゲームを作る手順を紹介しています。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
2
Help us understand the problem. What are the problem?