※本記事にはアフィリエイト広告(Udemy)を含みます。
前回のおさらい
前回③では、Signalを使って「発電する」ボタンとGameManagerをつなぎ、クリックするたびに電力が増える仕組みを作りました。ただ、これだけだと放置ゲームとしては物足りません。今回は、クリックしなくても電力が自動で増えていく仕組みを追加します。
今回のゴール
今回作るのは「発電パネル」という設備です。電力を使って発電パネルを購入すると、以後は何もしなくても毎秒電力が増えていきます。
STATION OPSでは今回はじめて「購入」という概念が登場します。何かを購入すると、その分だけ次回の購入コストが上がっていく、という放置ゲームによくある仕組みも、あわせて実装します。
GameManagerに発電パネルの状態を追加する
GameManager.gdに、以下の変数を追加します。
var power_panel_count: int = 0
var power_panel_cost: float = 10.0
const POWER_PANEL_COST_RATE: float = 1.15
const POWER_PANEL_PRODUCTION: float = 1.0
power_panel_count:現在所持している発電パネルの数power_panel_cost:次に1基購入するときのコストPOWER_PANEL_COST_RATE:購入するたびにコストが何倍になるかPOWER_PANEL_PRODUCTION:発電パネル1基あたりの毎秒の生産量
なぜコストが購入するたびに上がっていくのか
もしコストが常に一定なら、電力さえ貯めれば発電パネルを無限に増やせてしまい、ゲームとしての駆け引きがなくなってしまいます。購入するたびにコストを1.15倍にすることで、「次の1基を買うために、また電力を貯める」という遊びのリズムが生まれます。この数値は今回10→11.5→13.2…のように上昇していきますが、ちょうどよい上昇率は実際に遊びながら調整していく部分です。
発電パネルを購入する処理を書く
func buy_power_panel() -> bool:
if power < power_panel_cost:
return false
power -= power_panel_cost
power_panel_count += 1
power_panel_cost *= POWER_PANEL_COST_RATE
resources_changed.emit()
return true
if power < power_panel_cost: return falseの行で、電力が足りない場合は何もせずに処理を終えるようにしています。こうすることで、電力がマイナスになってしまう不具合を防いでいます。
Timerで自動生産を実装する
Timerノードとは
Timerとは、指定した時間が経過するたびにtimeoutというSignalを発信してくれるノードです。「1秒ごとに何かをする」といった、時間を基準にした繰り返し処理を作りたいときに使います。
シーンに置かず、コードからTimerを生成する
今回のTimerは、シーンエディタ上でドラッグ&ドロップするのではなく、GameManager.gdの中でコードから生成します。
var _production_timer: Timer
func _ready() -> void:
_production_timer = Timer.new()
_production_timer.wait_time = 1.0
_production_timer.autostart = true
_production_timer.timeout.connect(_on_production_tick)
add_child(_production_timer)
GameManagerはシーンファイルを持たないオートロードなので、シーンエディタで直接ノードを配置できません。そのため、_ready()の中でTimer.new()を呼び出してノードを作り、add_child()で自分の子として追加しています。wait_time = 1.0が「1秒ごと」、autostart = trueが「起動と同時に自動でカウントを始める」設定です。
毎秒、発電パネルの数だけ電力を増やす
func _on_production_tick() -> void:
if power_panel_count > 0:
power += power_panel_count * POWER_PANEL_PRODUCTION
resources_changed.emit()
TimerのtimeoutSignalが発信されるたびにこの関数が呼ばれ、所持している発電パネルの数だけ電力を加算します。
購入ボタンをUIに追加する
①②で用意した「UpgradeList」の中に、発電パネルの購入行を追加します。
- UpgradeListの子として「HBoxContainer」を追加する
- その子として「Label」を追加し、所持数とコストを表示する
- 同じく子として「Button」を追加し、テキストを「購入」にする
Main.gd側では、次のように接続します。
@onready var power_panel_info: Label = $Margin/VBoxContainer/UpgradeList/PowerPanelRow/PowerPanelInfo
@onready var power_panel_buy_button: Button = $Margin/VBoxContainer/UpgradeList/PowerPanelRow/PowerPanelBuyButton
func _ready() -> void:
# (③で書いた接続に加えて)
power_panel_buy_button.pressed.connect(_on_power_panel_buy_pressed)
func _on_power_panel_buy_pressed() -> void:
GameManager.buy_power_panel()
func _update_display() -> void:
power_label.text = "電力: %d" % int(GameManager.power)
power_panel_info.text = "発電パネル (%d基) - 次: %d" % [
GameManager.power_panel_count,
int(GameManager.power_panel_cost)
]
power_panel_buy_button.disabled = GameManager.power < GameManager.power_panel_cost
最後の行のdisabled = GameManager.power < GameManager.power_panel_costが、電力が足りないときにボタンを押せなくする処理です。ボタンが押せない状態になっていれば、プレイヤーは一目で「まだ買えない」と分かります。
動作確認
「発電する」ボタンでコスト分の電力を貯め、発電パネルを1基購入してみてください。購入後は、ボタンを押さなくても1秒ごとに電力が増えていけば成功です。
次回予告
次回⑤では、酸素・部品という新しい資源を追加し、電力→酸素→部品という連鎖構造を作ります。
Godot学習におすすめのオンライン講座
Timerとオートロードを組み合わせた設計は、放置ゲームに限らずいろいろな場面で応用できます。基礎から体系的に学びたい方はこちらもどうぞ。


コメント