godot

L011 ゲーム構成 プレイヤー


godot4.xの覚書です。
基本的な構造を確認しています。

プレイヤーは以下の要素で構成されます。
・キャラクター 
・判定(別記)
・操作

ベース

作業

extends Area2D

@export var speed = 5

func _process(delta):

	var velocity = Vector2.ZERO
	
	if Input.is_action_pressed("ui_up"):
		velocity.y -= 1 # moveup
	if Input.is_action_pressed("ui_down"):
		velocity.y += 1 # movedown
	if Input.is_action_pressed("ui_left"):
		velocity.x -= 1 # moveleft
	if Input.is_action_pressed("ui_right"):
		velocity.x += 1 # moveright

	position += velocity.normalized() * speed

キー入力

キー入力は既定の設定でされているものを使用します。(名称をコード内に記入します)
キーボードの↑→↓←キーで移動します。

インプットマップの組み込みアクションを表示で確認できます。

github

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

状態遷移

ゲームにおける状態遷移について

ゲームにおける状態遷移とは、ゲーム内のオブジェクトやシステムが、ある状態から別の状態へと変化することです。例えば、RPGのキャラクターが「通常状態」から「戦闘状態」に変わる、パズルゲームのブロックが「静止状態」から「落下状態」に変わるなどが、状態遷移の例として挙げられます。

なぜ状態遷移が重要なのか?

  • ゲームのロジックを明確にする: ゲームの動作を状態という概念で分割することで、複雑な処理をより分かりやすく管理できます。
  • 柔軟なゲームデザイン: 状態遷移を設計することで、ゲームの動作を様々な条件やイベントに応じて変化させることができます。
  • 再利用性の向上: 状態という単位でコードをモジュール化することで、他のゲームへの応用や、コードの再利用が容易になります。

状態遷移の表現方法

状態遷移は、主に以下の2つの方法で表現されます。

  • 状態遷移図: 状態をノード、状態間の遷移をエッジで表した図です。視覚的に状態の流れを把握しやすく、ゲームの設計段階でよく利用されます。
  • 状態遷移表: 状態とイベント、次の状態を一覧にした表です。状態遷移図をより詳細に記述する場合や、プログラムに直接変換する場合に利用されます。

格闘ゲームの行動例

var PState:PlayerState = PlayerState.std 
enum PlayerState {
Idle, #0
Walk, #1
Jump,
Attack,
Block,
Special,
Stun,
Down,
}
Idle: 何も行動していない状態
Walk: 移動している状態
Jump: ジャンプしている状態
Attack: 攻撃している状態
Block: ガードしている状態
Special: 特殊技を出している状態
Stun: 攻撃を受けて硬直している状態
Down: ダウン状態

弾を追加(r1)

よくある構成として、弾を射出する部分を追加してみます。

以下を作成します。
・弾(Ball)となるシーン
・プレイヤーを含む上位のシーン(main)
・プレイヤーに弾を生成する部分を追加

弾(Ball)となるシーン

extends Area2D

var velocity = Vector2()

const Window_X = 32  
const Window_Y = 32  
const Window_W = 360 -32
const Window_H = 720 -32 


func _physics_process(delta):
	if isInScreen(self) == false:

		queue_free() #out
	
	position += velocity * delta

func isInScreen(ball):
	# out
	if ball.position.x < Window_X:
		return false
	if ball.position.y < Window_Y:
		return false
	if ball.position.x > Window_W:
		return false
	if ball.position.y > Window_H:
		return false
	
	return true #in
	

func start(x, y, speed):
	position = Vector2(x, y)
	velocity.x = 0
	velocity.y = -speed

プレイヤーを含む上位のシーン(main)

mainシーンを追加してplayerを含めます。

プレイヤーに弾を生成する部分を追加

playerのコードを以下のように追加修正しています。

extends Area2D

@export var speed = 5

const Ball = preload("res://ball.tscn") #ballシーンのプリロード

#ウィンドウ範囲の指定
const Window_X = 32  
const Window_Y = 32  
const Window_W = 360 -32
const Window_H = 720 -32 

func _process(delta):

	var velocity = Vector2.ZERO
	
	if Input.is_action_pressed("ui_up"):
		velocity.y -= 1 # moveup
	if Input.is_action_pressed("ui_down"):
		velocity.y += 1 # movedown
	if Input.is_action_pressed("ui_left"):
		velocity.x -= 1 # moveleft
	if Input.is_action_pressed("ui_right"):
		velocity.x += 1 # moveright

	position += velocity.normalized() * speed
	
	#画面内にとどめる
	if position.x < Window_X:
		position.x = Window_X
	if position.x > Window_W:
		position.x = Window_W
	if position.y < Window_Y:
		position.y = Window_Y
	if position.y > Window_H:
		position.y = Window_H
	
	#ballを作成する スペースを押すとボールが作成されます。
	if Input.is_action_pressed(("ui_select")):
		# ball 
		var Ball = Ball.instantiate()
		Ball.position = position
		
		# ballの位置と速度
		Ball.start(position.x, position.y, 100)
		
		#ルートにインスタンスを追加
		var mainNode = get_owner()
		mainNode.add_child(Ball)

画面サイズ

画面のサイズを以下にしておきます。幅:360 高さ:720

メニューのプロジェクト>プロジェクト設定

弾の設定追加(r2)

射出間隔と弾速を設定します。

player.gdを以下に追加変更します。

extends Area2D

@export var speed = 5
@export var Shotcnt = 0.5 #射出間隔
@export var ShotSpeed = 1000 #速度
var cnt = 0
const Ball = preload("res://ball.tscn") #ballシーンのプリロード

#ウィンドウ範囲の指定
const Window_X = 32  
const Window_Y = 32  
const Window_W = 360 -32
const Window_H = 720 -32 

func _process(delta):

	var velocity = Vector2.ZERO
	
	if Input.is_action_pressed("ui_up"):
		velocity.y -= 1 # moveup
	if Input.is_action_pressed("ui_down"):
		velocity.y += 1 # movedown
	if Input.is_action_pressed("ui_left"):
		velocity.x -= 1 # moveleft
	if Input.is_action_pressed("ui_right"):
		velocity.x += 1 # moveright

	position += velocity.normalized() * speed
	
	#画面内にとどめる
	if position.x < Window_X:
		position.x = Window_X
	if position.x > Window_W:
		position.x = Window_W
	if position.y < Window_Y:
		position.y = Window_Y
	if position.y > Window_H:
		position.y = Window_H
	
	#ballを作成する スペースを押すとボールが作成されます。
	if Input.is_action_pressed(("ui_select")):
		cnt += delta
		if cnt > Shotcnt:
			cnt -= Shotcnt
		
			# ball 
			var Ball = Ball.instantiate()
			Ball.position = position
			
			# ballの位置と速度
			Ball.start(position.x, position.y, ShotSpeed)
			
			#ルートにインスタンスを追加
			var mainNode = get_owner()
			mainNode.add_child(Ball)

コメント