はじめてのGodot 第3回: 画面の外に出ないようにしよう — 関数とclamp
前回で宇宙船が動くようになりましたが、画面の外まで飛んで行けてしまいます。今回はこれを直しながら、自分で関数を作ることを学びます。
今回のゴール

- 宇宙船が画面の端で止まる
- おまけ: 移動方向に機体が傾く
その前に: Godotの座標系
ここで一度、座標の話をします。この連載で一番大事なコラムです。
数学のグラフではyは上に行くほど増えますが、Godot(およびほとんどの2Dゲームエンジン)では逆です。
- 画面の左上が原点
(0, 0) - xは右に行くほど増える(これは直感どおり)
- yは下に行くほど増える
前回、上キーで (0, -1) になると書いたのはこのためです。「上=マイナス、下=プラス」。今後何度も出てくるので、ここで体に入れておいてください。
画面内に閉じ込める
player.gd をこう書き換えます。
extends Sprite2D
var speed = 400
func _process(delta):
var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
position += direction * speed * delta
keep_inside_screen()
func keep_inside_screen():
var screen_size = get_viewport_rect().size
position.x = clamp(position.x, 0, screen_size.x)
position.y = clamp(position.y, 0, screen_size.y)
実行すると、宇宙船が画面の端で止まるようになります。
何をしたのか
自分の関数を定義する
func keep_inside_screen(): — _process と同じ func で、自分の関数を作りました。_process はGodotが呼んでくれる特別な関数でしたが、自分で作った関数は自分で呼びます。それが _process の中の keep_inside_screen() という行です。
なぜ関数に分けるのか? _process の中に全部書いても動きますが、コードが伸びると読めなくなります。「画面内に収める」というひとまとまりの仕事に名前を付けて取り出すと、_process を読むだけで「移動して、画面内に収めている」と日本語のように読めるようになります。コードが伸びてきたら関数に分ける — この習慣を今日から始めましょう。
clamp() — 値を範囲内に収める
clamp(値, 最小, 最大) は「値が範囲からはみ出していたら、端に押し戻す」関数です。
clamp(500, 0, 480)→480(はみ出したので最大値に)clamp(240, 0, 480)→240(範囲内なのでそのまま)
これをx座標とy座標それぞれにかけることで、画面の外に出られなくしています。get_viewport_rect().size は画面のサイズ(このゲームでは 480 × 720)を返します。
おまけ: 移動方向に傾ける
見た目が一気にゲームらしくなる小技です。_process の最後に1行足してください。
rotation = direction.x * 0.3
右に動くと右に、左に動くと左に機体が傾きます。rotation はノードの回転角で、単位はラジアンです(0.3ラジアン ≒ 17度)。度で書きたい場合は rotation_degrees = direction.x * 17 でも同じことができます。
つまずきポイント
Function "keep_inside_screen()" not found: 関数の定義(func keep_inside_screen():)が_processの中に入ってしまっていませんか?func同士は同じ字下げレベル(行頭)に並べます- 機体の半分が画面外にはみ出る:
positionは画像の中心なので、端では半分はみ出します。気になる人はclamp(position.x, 30, screen_size.x - 30)のように余白を付けてみてください(30は画像の半分の幅)。こういう微調整も立派なゲーム開発です
今回学んだこと
- Godotの座標は左上が原点で、yは下向きに増える
func 名前():で自分の関数を定義し、名前()で呼び出す- ひとまとまりの仕事は関数に分けると読みやすくなる
clamp(値, 最小, 最大)で値を範囲内に収めるrotationの単位はラジアン
次回予告
操作まわりはこれで完成です。第4回ではいよいよ敵 — 降ってくる隕石を作ります。「シーンを部品として作る」という、Godotの設計思想の核心に触れる回です。