godot

L010 ゲーム構成


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

チュートリアルにあるサンプルは速度変更して動作します。
正規化することで斜めの移動速度も上下左右と同じにしています。
これを追加して同時に動かしています。

最初の2Dゲーム
このステップバイステップチュートリアルシリーズの中では、初めての2Dゲームを作成します。このシリーズの最後には、以下のようなシンプルですが完成されたあなた自身によるゲームが完成します。 image0 このチュートリアルではエディタの使い方、...
四方向と斜め移動で差があります。
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にする必要があります。
メニュー>デバッグ>コリジョン形状を表示 にしてください。

GitHub - WOCae/L010
Contribute to WOCae/L010 development by creating an account on GitHub.

L010-main.zip

コメント