Part 1 の今回は、ゲームのプレイ画面にパドルを配置して動かすところまでやっていく。

ところで、ゲーム開発初心者が初めて挑戦するゲームにうってつけなのがブロック崩しだ。ブロック崩しはシンプルながらその開発を通して、ゲーム作りの基本をたくさん学習することができるので Godot 初心者やゲーム開発初学者にとてもおすすめだ。習得したゲーム開発の基本スキルは他のジャンルのゲームでもできることばかりだ。

これから数回に分けて、上の GIF ムービーのようなブロック崩しの作り方について解説していく。

Memo:
プロジェクトの新規作成の手順についてはこちらの記事をご参照ください。
Godot のプロジェクトマネージャの操作


画面サイズを設定する

まずはプロジェクトを新規作成しよう。
Right side bar on Project Manager window

下準備として、ゲーム画面のサイズを指定していく。今回、スプライト用の画像のサイズが小さいため、それに合わせて少し小さめで指定する。

「プロジェクト」メニュー >「プロジェクト設定」を選択する。
Right side bar on Project Manager window

「一般」タブ > サイドバー「Display」カテゴリ内の「Window」を選択する。
Right side bar on Project Manager window

「Size」セクションの「Width」、「Height」がそれぞれ画面の幅と高さだ。やや小さめにしたいので、デフォルトサイズの半分として、Width: 512、Height: 300 に設定する。また、テストプレイしてデバッグする時のディスプレイサイズは2倍の大きさにしたいので、Test Width: 1024、Test Height: 600に設定する。
Edit Size

続けて、さらに下の方にスクロールすると「Strech」セクションが表示される。ここでは「Mode」を「2d」に「Aspect」を「keep」に変更する。
Edit aspect ratio

最後に一番下の「閉じる」をクリックしたら画面サイズの編集完了だ。
Click Close Button



アセットを用意する

ブロック崩しで必要になるメインのオブジェクトは以下の3つになる。

  • パドル(プレイヤー)
  • ボール
  • ブロック

これらに使用する画像を用意した。こちらの Dropbox の共有フォルダ から「sprites」フォルダを丸ごとダウンロードしてほしい。


画像ファイルをファイルシステムへインポートする

ダウンロードしたら、それを Godot の「ファイルシステム」へドラッグ&ドロップしよう。
Drag and drop into file system

するとファイルシステム内に「Sprites」フォルダにまとめられた状態のままで画像ファイルが表示される。
Sprites images in file system


ドット絵をシャープに表示する

今回インポートした画像のようにサイズの小さなドット絵の場合は、デフォルトの設定により、ぼやけた感じで画面上に表示されてしまうため、これをドット絵特有のシャープな表示に変更しよう。

まずファイルシステム上で先ほどインポートした画像ファイルを全て選択する。
select all imported images

次に「インポート」タブを選択し、「プリセット」をクリックする。
click preset

そこで「2D Pixel」を選択する。
select 2D pixel

最後に「再インポート」をクリックすればキレイなドット絵表示に切り替わる。
click re-import


プロジェクトのアイコンを変更する

ついでに、プロジェクトのアイコン画像も用意しておいたので、デフォルトの Godot ロゴの画像を上書きしよう。ファイルシステムにコピーした「Sprites」フォルダ内の「Icon.png」を「Sprites」フォルダの外(つまりルートフォルダ「res://」直下)に移動する。
Move Icon.png to root folder

同じ名前のファイルを上書きして良いか確認するダイアログが表示されるので「上書き」を選択する。
Confirmation of overwritten Icon.png

本当にプロジェクトのアイコンが変更されたか、念のため確認しておこう。
「プロジェクト」メニュー>「終了してプロジェクト一覧を開く」を選択する。
Select menu of quit project and open project list

確認のダイアログが表示されたら「はい」を選択する。
Confirmation of quit project

プロジェクトのアイコン画像がきちんと変更されているのが確認できた。

そのままプロジェクトマネージャー上で「Breakout」プロジェクトをダブルクリックし、ブロック崩しのプロジェクトに戻ろう。
Check the project icon image



シーンを作る

いよいよシーンを作成していく。シーンというのは、1つ以上のノードで構成されたゲームの構成要素の単位だ。例えば、オーソドックスなRPGだったら、キャラクターのシーン、モンスターのシーン、バトルのシーン、ワールドマップのシーン、町のシーン、コンフィグ画面のシーン、などのシーンを別々用意しておき、それらを必要に応じて画面に表示させたり引っ込めたりするわけだ。

シーンには一つ以上のノードが必要で、シーン内に最初に追加するノードが自動的にルートノードになる(あとで変更もできる)。ノードというのは、その一つ一つがシーンの構成要素であり、基本的にそれぞれが特有の機能を持っている。例えば、2D の「Sprite」ノードなら、テクスチャ画像を設定して画面上に表示されるキャラクターやアイテムを表現できるし、Label ノードなら テキストを設定してその文字列を画面に表示することができる。数種類ある Collision系のノードは、衝突判定を自動的に行ってくれる。

このように、特徴的な機能をもつノードをうまく組み合わせてシーンを作り、そのようなシーンをまた複数組み合わせることでゲーム全体を作っていく。ちょうど枝分かれしている木のような構成だ。実際に Godot でもゲームを構成するシーンをまとめてシーンツリーと呼ぶ。これが Godot でのゲーム作りの基本だ。

さて、ここでは 2D のブロック崩しを作るので、シーンドックの「ルートノードを生成」の選択肢から「2D シーン」を選択する。
select 2D scene

すると、自動的に「Node2D」という名前のノードが生成される。これがルートノードになる。右クリックして「名前の変更」をクリックして名前を変更しておこう(シーンドック上で「Node2D」ノードを選択してクリックまたはEnterキーでも構わない)。
change name of node

今回は「Game」という名前にした。
change the name of node to Game



プレイヤーのパドルを作る

「Game」ノードを選択した状態で「+」ボタンをクリックして、「Game」ノードに別のノード(子ノード)を追加する。ショートカットキー操作も便利だ(ノードを追加 Windows: ctrl + A / macOS: Cmd + A)。
click plus icon selecting Game node

「Node を新規作成」のパネルが開いたら「kinematic」と検索しよう。検索結果の中に「KinematicBody2D」が見つかったらそれを選択して「作成」をクリックする。
input kinematic in search bar

これで「Game」ノードの子ノードとして「KinematicBody2D」ノードが追加された。
![added KinematicBody2D(/images/tutorials/gd0004_breakout/breakout_1/img019.png)

「KinematicBody2D」ノードの名前も変更しておこう。名前は「Paddle」とする。このように、主要なノードをシーンツリーに追加したら、早めに名前を変更しておく癖をつけていこう。そうすればプロジェクトが大きくなっても同じ名前のノードがたくさんあって困るということがない。
Change the name of KinematicBody2D node

今度は「Paddle」ノードに子ノードを追加する。「Game」ノードから見たら孫ノードだ。「Paddle」を選択して「+」ボタンをクリックする。もちろんショートカットキー操作でも構わない。
add a child node to「Paddle」node

「sprite」と検索し、検索結果のうち「Sprite」を選択して「作成」をクリックする。
select「Sprite」searching sprite

「Paddle」ノードに「Sprite」ノードが追加された。「Sprite」はゲーム画面に画像を表示するノードだ。プレイヤーキャラクターや敵キャラクター、背景のオブジェクトやアイテムなどなど、様々な場面で使用される。
added「Sprite」node as a child of「Paddle」node

シーンドック上で「Sprite」ノードを選択した状態で、インスペクタドックを見てほしい。現在シーンドック上で選択されている「Sprite」ノードのプロパティが表示されている。今、一番上の「Texture」というプロパティは空になっている。このプロパティに画像ファイルを指定することでゲーム画面に画像が表示されるという仕組みだ。

では「Texture」プロパティめがけて「ファイルシステム」から先に用意しておいた「Sprites」フォルダ内の「Paddle1.png」という画像ファイルをドラッグ&ドロップしよう。
add texture to「Sprite」node

Textureに画像が反映した。
reflected the「Paddle」image as the texture

画面中央にある 2D ワークスペースのちょうど赤と緑の線が交わる箇所に表示されている(小さく表示されてわかりにくい場合は拡大しよう)。この位置が x, y 座標の (0, 0) に当たる。
check the「Paddle」in 2D workspace

同様に「Paddle」ノードにもう一つ別の子ノードを追加する。
add another node as a child of「Paddle」node

今度は「collisions」と検索し、「CollisionShape2D」を選択して「作成」をクリックしよう。似たような名前の「CollisionPolygon2D」の方ではないので要注意だ。
search collision and select CollisionShape2D

これで「Paddle」に2つ目の子ノード「CollisionShape2D」が追加された。「CollisionShape2D」は2Dノードのいわゆる当たり判定用のノードだ。例えば、一般的なプラットフォーマー(横スクロールアクション)ゲームで、プレイヤーキャラクターが敵キャラクターや地面、壁、アイテムなどにぶつかったかどうかを判定するために使う。
added CollisionShape2D node as a child of「Paddle」node

シーンドック上で「CollisionShape2D」を選択した状態で、インスペクタを見てほしい。一番上の「Shape」プロパティが [空] になっている。[空] と表示されている箇所をクリックして形を指定していく。
click empty of shape property of CollisionShape2D

形をSpriteの画像に合わせたいので、オプションの中から「新規RectangleShape2D」(Rectangle: 長方形)を選択する。
select New RectangleShape 2D

設定された。
set the collision shape

2D ワークスペースを見ると、そこに「Sprite」の画像に重なった 半透明の青緑色をした四角形がある。これが「CollisionShape2D」の形だ。今の時点ではまだ「Sprite」ノードの「Texture」プロパティの画像の形と「CollisionShape2D」ノードの「Shape」プロパティの形が一致していない。今からこれを一致させていく。
check the current collision shape in 2D workspace

形を調整する前に少し下準備をする。2D ワークスペース上部のツールバーを見てほしい。スナッピングオプション(3つの点が縦に並んだアイコン)を見つけたらそれをクリックする。
click snapping options on tool bar

表示されたオプションのうち「ピクセルスナップを使用」にチェックを入れて閉じる。
tick using pixel snap

赤丸で囲んだ丸い点をドラッグして、形を「Sprite」ノードの「Texture」に合わせよう。先の設定によって、1 ピクセルずつスナップされるので簡単に調整できるはずだ。
adjust collision shape to match the texture of the sprite

形が一致したら調整完了だ。
done adjusting the shape

それではここで一度ゲーム画面を表示してみましょう。エディタ右上のアイコンのうち、「シーンを実行」アイコンをクリックしよう。ショートカットキー操作でも構わない(シーンを実行 Windows: F6 / macOS: Cmd + R)。
execute scene

すると、今回のように初めてシーンを実行する時にまだシーンが保存されてなければ「実行前にシーンを保存」パネルが表示される。今回はファイルを整理するためにシーン用のフォルダを作成する。右上の「フォルダを作成」をクリックする。
create folder on the pannel of save the scene before execute

フォルダ名を入力する。今回は「scene」とする。
input the name of folder as scene

パネル上部の保存先のフォルダパスが間違いないことを確認する。
check the folder path to save

ファイル名を確認して(今回はそのまま Game.tscn )問題なければ「保存」をクリックする。
check the file name and save

デバッグパネルが開いた。よく見ると「Paddle」ノードが左上の角にあるのがわかる。これは「Paddle」ノードの位置が(0, 0) にあるためだ。ゲーム画面の x, y 座標は左上の角が (0, 0) で右に行くと x 座標が上がり、下に行くと y 座標が上がる。学校などで習う x, y 座標と違い、ゲーム画面では y 座標は下に行くほど大きな値になる。このことについて慣れるまで違和感があるかもしれませんが、大事なポイントなので覚えておこう。
saw the「Paddle」is on the left upper corner

では「Paddle」ノードの初期位置を変更していこう。まず、手動でドラッグする可能性を考慮して、「Paddle」ノードの子ノードを選択不可する。選択不可にするには、シーンドックで「Paddle」ノードを選択した状態で、2D ワークスペース上部のツールバーにある「オブジェクトの子を選択不可にする」アイコンをクリックする。

例えば「Paddle」ノードを移動させようと思った時に、過って子ノードの「Sprite」だけ移動させてしまいそうになっても、選択不可にしておけば、子ノードを動かしてしまう心配はなく、常に親ノードと子ノードの位置関係が変わらない状態をキープできる。
disable to select child nodes for「Paddle」node

ツールバーの「オブジェクトを選択不可にする」アイコンをクリックすると、シーンドックの「Paddle」ノードの右側に、ツールバーと同じアイコンが表示される。
saw the icon of disabling to select child nodes

手動で 2D ワークスペース内を移動させても良いのだが、今回はきっちり中央下よりに配置するため、インスペクタで位置を変更する。シーンドックで「Paddle」ノードを選択した状態で、インスペクタから「Transform」プロパティをクリックして開く。一番上の「Position」プロパティの (x, y) の値を (256, 256) とする。
set the position of Paddle

再度シーンを実行してみよう。
re-execute the scene

今度はデバッグパネルの画面中央下寄りの位置に「Paddle」が表示された。
Saw「Paddle」node on DEBUG pannel



パドルを動かす

ようやくゲーム画面に「Paddle」ノードが表示されたが、まだ動かせない。ここから少しばかりプログラミングをして「Paddle」ノードを動かせるようにしていく。


インプットマップにアクションを追加する

Paddle を操作するために必要なキー操作をあらかじめ用意しておく。
click project settings

「インプットマップ」タブを開こう。ここにはデフォルトで登録済みのインプット操作の項目がすでに表示されている。だが、今回は敢えて、カスタマイズした操作を登録することにする。
select input map tab

パネル上部の「アクション」に操作の名前を入力する。「move_right」と入力して「追加」をクリックする。
add move_right

すると、登録された「move_right」が一番下に表示される。その右側にある「+」ボタンをクリックして「キー」を選択する。
add key

パネル中央に、キー操作を受け付けてくれるウインドウが表示される。この状態で、キーボードのいずれかのキーを押下すると、そのキーの名前が表示される。ここではキーボードの右方向キーを押下する。そのまま「OK」をクリックする。間違って「Enter」キーを押さないようにしよう。押すと「Enter」キーが登録されてしまうからだ。
input key to select it

同様に「move_left」もキーボードの左方向キーを割り当てて登録ておこう。
do it again for move_left the same as right


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

プログラミングを始める前の下準備として、スクリプトを「Paddle」ノードにアタッチ(添付)する。

シーンドックで「Paddle」ノード選択してから、右上の「スクリプト」アイコンをクリックしよう。
click script attach icon

「ノードにスクリプトをアタッチする」パネルが表示されたら「パス」の項目右側のフォルダアイコンをクリックする。
click folder icon

「スクリプトを開く / 場所を選択する」パネルが出るので、上部「パス」がルート「res://」になっている状態で、右上の「フォルダを作成」をクリックする。もし「res://scene」になっていたら、パネル左上の「↑」アイコンをクリックして一階層上の「res://」に移動できる。
select folder to save a gdscript file

スクリプト用のフォルダを用意したいので、「scripts」と入力して「OK」をクリックする。
input scripts as the folder name

パネル上部で、パスが「scripts」フォルダのパスになっていることを確認する。
check the path if it is scripts folder’s

パネル下部で、ファイル名はそのまま「Paddle.gd」として「開く」をクリックする。
check file name and click open

「ノードにスクリプトをアタッチする」パネルに戻り、パスが更新されたことを確認できたら「作成」をクリックする。
Check folder path and click create


スクリプトをコーディングする

スクリプトをアタッチすると、Script ワークスペースに切り替わる。現在、デフォルトだでにコードが少し記述されている状態だが、このスクリプトでは一番上のextends KinematicBody2D以外は不要なので、全て選択して削除しよう。
default whole code of KinematicBody2D

シーンドックには「Paddle」ノードにスクリプトがアタッチされていることがスクリプトアイコンでわかるようになっている。
There is an icon in Scene dock

このスクリプトに記述する GDScript によるコードは以下になる。プログラミングがよくわからない人は、一旦丸ごとスクリプトワークスペースにコピー&ペーストしてほしい。

extends KinematicBody2D

# パドルの速さ:1秒あたりの移動距離(pixel)
export (int) var speed = 150

func _process(delta):
  # 毎フレーム、パドルの向きを(0, 0)にリセットする
	var direction = Vector2.ZERO

  # キーボードで右方向キーを押している場合は、パドルの向きを(1, 0)に更新する
	if Input.is_action_pressed("move_right"):
		direction.x = 1
  # キーボードで左方向キーを押している場合は、パドルの向きを(-1, 0)に更新する
	if Input.is_action_pressed("move_left"):
		direction.x = -1

  # position(パドルの位置)に移動距離(速さ:speed x 向き:direction x 時間:delta)を加算
	position += speed * direction * delta

ここからスクリプトの内容について少し説明していく。プログラミングが苦手な人は一旦スキップしてもらって構わない。



スクリプト解説

まずは最初の1行目から。

extends KinematicBody2D

これはスクリプトファイルがアタッチされている「Paddle」ノードのクラスである KinematicBody2D を拡張するために必要なコードになる。「KinematicBody2D」というクラスはもともと用意されているが、それをさらに拡張させることによって「Paddle」ノードを開発者が思った通りに動かせるようにしていくわけだ。

次にspeedというプロパティだ。

Memo:
プログラミングの世界ではクラスの中の変数をプロパティといいます。

# パドルの速さ:1秒あたりの移動距離(pixel)
export (int) var speed = 150

最初に#から始まる行はコメントだ。#で始まる行は、プログラム実行時には直接関係ないものとしてスキップされるため、これを利用してスクリプト上にメモを残すことができる。

次の行を見てみよう。最初に出てくるexport (int)という記述についてはあとで説明する。まずはvarというキーワードだが、これを頭につけるとプロパティを定義できる(クラス内の変数をプロパティと言いる)。varに続けて、自分でプロパティの名前を決めて記述する。ここではspeedという名前の変数にしている。そして=のあとにプロパティに代入したい値を記述する。ここでは150と記述している。このプロパティで、パドルの移動速度(秒速)を設定している。つまり、毎秒 150 ピクセルの速さで移動するという内容になる。

さて、冒頭のexportのキーワードだが、これをつけると、インスペクタドックでスクリプトがアタッチされたノード(ここでは「Paddle」ノード)のプロパティとして表示されるようになる。今は150と指定しているが、テストしてみたら150だと遅すぎる(または速すぎる)、となった場合にインスペクタの方で気軽にプロパティの値を修正できるのだ。
custom property in inspector dock

そのあと(int) と記述しているが、これはデータタイプを指定している。int は整数を表すデータタイプ(データ型)で、同じ数値でも float という浮動小数点(例えば、1.3141、256.159など)という別のデータタイプもあって、それを明確に区別するために記述している。ただし、GDScriptは動的なプログラミング言語なので、変数に代入された値によってデータタイプを自動判別してくれる。つまり、今回のコードの場合は記述する必要は特にない。

次は_process()という関数だ。

func _process(delta):

まず GDScript ではfuncというキーワードを頭につけることでメソッドを定義できる(クラス内の関数をメソッドと言う)。そのあと続けてメソッドの名前を記述する。ここでは_processだ。さらにそのあと()で囲った中に引数を入力する。引数というのは、メソッドを使うときに任意で指定できる値で、この引数の値の違いによって、毎回メソッドの実行結果が変わってきます。例えるなら、ジュースを作るミキサーという機械がメソッドで、そこに入れる食材が引数だ。フルーツや野菜など入れる食材によって、出来上がるジュースが変わるのと同じだ。

ただし、今回定義しているこの_processという関数は実はもともと KinematicBody2D クラスに用意されているメソッドなのだ。先にextendsキーワードでこのクラスを拡張することを宣言しているので、もともと用意されているメソッドに内容を追加したりして、再定義しているわけだ。

この_process関数は、毎フレーム(デフォルトでは1秒間に60フレーム)読み込まれて、その内容が実行される。引数のdeltaはもともと指定されている引数で、一つ前のフレームにかかった時間を保持している。ゲームというのはその時々の処理の重さなどによって、毎フレームきっちり1/60秒の長さにはならないようだ。そこで、先に定義したパドルの速さにこのdeltaを掛け合わせることで、一定の速度でパドルを動かすことが可能になる。

ではここから_process()関数の中をみていくが、GDScript ではメソッドブロック(メソッドの中身)を記述する際は、どこまでが中身なのかがわかるように、インデントして(ずらして)記述していく。このインデントがないとエラーになるので注意ほしい。

  # 毎フレーム、パドルの向きを(0, 0)にリセットする
	var direction = Vector2.ZERO

パドルの移動する方向を代入するdirectionという名前のプロパティにしている。ひとまず初期値としてVector2.ZEROを代入した。GDScriptには Vector2 というデータタイプ(データ型)が用意されていて、これがいわゆるベクトル座標(x, y)形式のデータになる。 Vector2(x, y) という形で記述する。今回記述しているVector2.ZEROは Vector2 というクラスの ZERO というプロパティを表している。ちょっと特別な書き方だが、Vector2(0, 0)と同じ意味になる。他にも以下のように「長さが 1」で、方向だけを表す際に使用しやすいプロパティが Vector2 クラスには用意されている。

  • Vector2.UP: Vector2(0, -1)と同じ *ゲーム画面では下にいくほど y 座標が上がる
  • Vector2.DOWN: Vector2(0, 1)と同じ *ゲーム画面では上にいくほど y 座標が下がる
  • Vector2.RIGHT: Vector2(1, 0)と同じ
  • Vector2.LEFT: Vector2(-1, 0)と同じ

話が少し逸れたが、毎フレームでプロパティdirectionをパドルの方向をどちらにも向いていない (0, 0) にリセットすることで、プレイヤーが操作をしていない時はきちんとパドルが止まるようするのが狙いだ。

  # キーボードで右方向キーを押している場合は、パドルの向きを(1, 0)に更新する
	if Input.is_action_pressed("move_right"):
		direction.x = 1
  # キーボードで左方向キーを押している場合は、パドルの向きを(-1, 0)に更新する
	if Input.is_action_pressed("move_left"):
		direction.x = -1

Inputというのはクラスの名前で、このクラスには様々な入力操作を扱うプロパティやメソッドが用意されている。is_action_pressed()というメソッドもその一つで、引数に先に登録しておいた(またはデフォルトで登録されている)インプットマップの名前を入力することで、そのキーを押しているかどうかの値を返してくれる。ちなみにこの真(当てはまる)か偽(当てはまらない)いずれかの値しか取らないデータタイプを bool という。bool は boolean の略だ。つまり、このメソッドは bool 型のデータを結果として返してくれるのだ。

この bool 型はよく if 構文で利用される。例に漏れず、このスクリプトでもそのような記述をしている。なお、GDScript では if 構文もメソッドと同様にその中身を記述するときはインデントが必要なので注意してほしい。

インプットマップ「move_right」が押されている場合、つまり、プレイヤーが右方向キーを押している時は、direction.x = 1が読み込まれる。directionは先に定義しておいた Vector2 型のプロパティだった。.xがついているので、これはdirectionプロパティの x 座標のことを指している。その x 座標に1を代入せよ、という意味になる。 direction = Vector2(1, 0)と記述するのと同じ意味になる。どちらでも構わない。インプットマップ「move_left」も同様だ。

  # position(パドルの位置)に移動距離(速さ:speed x 向き:direction x 時間:delta)を加算
  position += speed * direction * delta

positionというプロパティが急に出現している。変数(プロパティ)を定義するにはvarというキーワードが必要なのに、これはなぜだろうか。答えは、もともと KinematicBody2D クラスでこのpositionプロパティが定義済みだからだ。extendsで拡張しているので、もともと定義されているプロパティはそのまま使えます。そして、このpositionは Vector2 型のプロパティで、ゲーム画面上のそのノードの位置を表する。

+=という記述は、その変数に対して、今その変数に代入されている値に+より後の値を足す、という意味になる。これはposition = position + (speed * direction * delta)と記述するのと同じ意味になる。つまり、略記だ。そして移動距離を「速さ×方向×時間」で表すことができるので、speed * direction * deltaとなる。


パドルを動かす

それでは、最後にパドルが実際に動くか見ていく。さっきは「シーンを実行」でデバッグパネルを起動したが、今度は「実行」ボタンでプロジェクトを実行してみよう(とはいえ、今は一つのシーンしかないので出力される画面は同じだ)。ショートカットキー操作も便利だ(実行 Windows: F5 / macOS: Cmd + B)。
run project

すると、まだプロジェクトのメインシーンが設定されていないので、以下のダイアログが表示される。「選択」をクリックしよう。
click select

今のところ唯一作成済みのシーン「Game.tscn」ファイルを選択して「開く」をクリックする。
choose the scene and click open

デバッグパネルが開いたら、キーボードの左右の方向キーで動かしてみよう。思った通りに動いただろうか。もしパドルのスピードが気に入らない時は、シーンドックで「Paddle」ノードを選択してから、インスペクタで「speed」プロパティの値を変えて調整してみてほしい。
moving paddle



おわりに

以上で Part 1 は終了だ。次回 Part 2 は、ボールのオブジェクトを作ってそれをパドルから発射するところまでやっていく。