Godot4の覚書です。
簡単な構成で、一通り確認することを目的としています。
構成
だいたいのゲームは以下のような構成になっていると思います。
スタート画面 | ゲーム画面 | ゲームオーバー画面 | 設定画面(ない場合も) |
。。。途中 |
設定
画面サイズ
ゲーム画面のサイズを設定しておきます。
幅:800、 高さ:1380、 モード:viewport
スタート画面
スタート画面を作ります。
startが明滅するようにしています。
extends Control
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
var counti:int
func _process(delta):
counti +=1
$start.show()
if counti > 50:
$start.hide()
if counti > 100:
counti = 0
#print("ループ"+str(counti))
シーンの切り替え
シーン遷移
スタート画面からゲーム本編へ移動します。または設定画面へ移動する場合もあります。
本編や設定画面を作成したら、シーンを呼び出して移動します。
ほとんどの場合において、なんらかのキーを押すことで移動しますので、キー設定も行う必要があります。startするためのボタンは、キーボードなら何でもよいようにします。
以下のコードを追加します。キーボードのキーが押された場合、mianシーンに変えます。
#シーンの切り替え
func _input(event: InputEvent) -> void:
# キーボードのキーが押された場合の処理
if event is InputEventKey:
get_tree().change_scene_to_file("res://Scene/main.tscn")
終了画面
作りはスタート画面とほぼ同じです。
ゲームオーバーの条件を満たした場合に遷移する設定を、ゲームmainに設定します。
画面の作成と、キーによる操作の設定をします。
インプットマップでキーボードのqキーにQuitを設定します。
func _input(event):
if event.is_action_released("Quit"):
get_tree().quit() #ゲーム終了
elif event.is_action_released("ui_accept"):
get_tree().change_scene_to_file("res://Scene/start_game.tscn")
"ui_accept"は組み込みアクションになります。スペースキーやエンターキーが該当します。
ゲーム本編
ひとまず、簡単な条件を設定します。
・プレイヤーだけが登場
・5秒停止しているとゲームオーバー
画面
mainのシーンを作成してゲーム画面とします。
プレイヤー
プレイヤーのシーンを作成してmainシーンに配置します。
プロジェクト設定のインプットマップにキー操作を設定します。(動画だとすでにゲームパッドの設定が入っています)
このスクリプトは位置を指定して動作します。(下記に速度でのコードがあります)
func _process(delta):
if Input.is_action_pressed(&"move_right"):
position.x += 1
if Input.is_action_pressed(&"move_left"):
position.x -= 1
if Input.is_action_pressed(&"move_down"):
position.y += 1
if Input.is_action_pressed(&"move_up"):
position.y -= 1
velocity
チュートリアルにあるサンプルは速度変更して動作します。
正規化することで斜めの移動速度も上下左右と同じにしています。
これを追加して同時に動かしています。
var screen_size # Size of the game window.
@export var speed = 80
func _ready():
screen_size = get_viewport_rect().size
func _process(delta):
var velocity = Vector2.ZERO # The player's movement vector.
if Input.is_action_pressed(&"move_right"):
velocity.x += 1
if Input.is_action_pressed(&"move_left"):
velocity.x -= 1
if Input.is_action_pressed(&"move_down"):
velocity.y += 1
if Input.is_action_pressed(&"move_up"):
velocity.y -= 1
if velocity.length() > 0:
velocity = velocity.normalized() * speed
position += velocity * delta
position = position.clamp(Vector2.ZERO, screen_size)
ルール
ここで、mainシーンにゲームルールのスクリプトを記述しておきます。
var lastPosi_X:float
var lastPosi_Y:float
var timeCount:float
func _process(delta):
#print(delta)
#位置を調べる
if $Player.position.x== lastPosi_X && $Player.position.y== lastPosi_Y:
timeCount += delta
else:
timeCount = 0
lastPosi_X = $Player.position.x
lastPosi_Y = $Player.position.y
#カウント5以上で画面遷移
if timeCount >= 5:
get_tree().change_scene_to_file("res://Scene/end_game.tscn")
プレイヤーの位置が変化ない場合、deltaをカウントして5以上になると、ゲームオーバー画面に変わります。
HUD
経過時間を表示するHead-Up Display(HUD)を設定します。
$HUD/time.text = str(ceil(timeCount * 10) / 10) #ceil関数:切り捨て整数表示
フォーマットで指定する場合
$HUD/time.text = "%7.1f" % timeCount #7は全文字数(.を含む)1は小数点以下数
Pause画面
ゲーム中に一旦停止する画面です。
ここでは別のシーンを呼び出さず、ノードを表示する方法で行います。
Pause画面で大事なこととして、Pauseした場合に再度操作するにあたって、
Process設定をAlwaysにしておくことです。設定しておかないと、操作を受け付けてくれません。
マップ
マップではなく障害物のような扱いですが、地形を描いてみます。
プレイヤーが接触するとゲームオーバーになります。
マップのシーンを作成して、mainシーンに配置します。
mainのスクリプトで、mapからのシグナルを受信して処理を行います。
if area.name == "Player":
# ゲームオーバーになる
get_tree().change_scene_to_file("res://Scene/end_game.tscn")
接触する場合
接触物として当たる場合には、CharacterBody2Dノードでプレイヤーを作成して、マップをStaticBody2Dノードで作成します。
var screen_size # Size of the game window.
@export var speed = 80
func _ready():
screen_size = get_viewport_rect().size
func _physics_process(delta):
var velocity = Vector2.ZERO # The player's movement vector.
if Input.is_action_pressed(&"move_right"):
velocity.x += 1
if Input.is_action_pressed(&"move_left"):
velocity.x -= 1
if Input.is_action_pressed(&"move_down"):
velocity.y += 1
if Input.is_action_pressed(&"move_up"):
velocity.y -= 1
if velocity.length() > 0:
velocity = velocity.normalized() * speed
position += velocity * delta
position = position.clamp(Vector2.ZERO, screen_size)
move_and_slide()
エネミー
エネミー(敵)というよりは、シーンの組付けに関することです。
構成
ゲームではそれぞれの構成が関係しあいます。また、デザインであったり個々でも深く作り込まれます。
いくつかのケースを確認します。
マップ追加
。。。途中
サンプルモデル
githubに置いています。
コリジョンの形状表示をonにする必要があります。
メニュー>デバッグ>コリジョン形状を表示 にしてください。
コメント