Godot 4.4で作る溜めと硬直システム - 格闘ゲーム風の操作感を実現

Godot 4.4で作る溜めと硬直システム

格闘ゲームやアクションゲームでよく見られる「溜め」と「硬直」のシステム。これらの要素を追加することで、単純な移動から戦略性のある操作感に変化させることができます。

溜めと硬直システムとは

溜め(チャージ)システム

  • ジャンプ前の準備時間: 0.3秒の溜め時間
  • 戦略的な操作: タイミングを計って行動
  • 専用アニメーション: 溜め中の視覚的フィードバック

硬直(ラグ)システム

  • 着地後の硬直: 0.2秒の行動不能時間
  • リスクとリターン: ジャンプ後のペナルティ
  • 専用アニメーション: 硬直中の状態表示

基本設定

エクスポート変数の定義

extends CharacterBody2D

# エクスポート変数(エディタで調整可能)
@export_group("移動設定")
@export var speed: float = 100.0
@export var run_speed: float = 300.0

@export_group("ジャンプ設定")
@export var jump_velocity: float = -300.0
@export var jump_charge_time: float = 0.3 # ジャンプ溜め時間(秒)
@export var land_lag_time: float = 0.2    # 着地溜め時間(秒)

状態管理変数

# 溜め・ラグ用内部変数
var jump_charge_timer: float = 0.0
var is_jump_charging: bool = false
var jump_queued: bool = false
var land_lag_timer: float = 0.0
var was_on_floor: bool = false

定数定義

# 入力アクション名(定数として定義)
const INPUT_JUMP = "ui_accept"
const INPUT_LEFT = "ui_left"
const INPUT_RIGHT = "ui_right"
const INPUT_RUN = "run"

# アニメーション名(定数として定義)
const ANIM_IDLE = "idle"
const ANIM_WALK = "walk"
const ANIM_RUN = "run"
const ANIM_JUMP = "jump"
const ANIM_JUMP_CHARGE = "jump_charge" # ジャンプ溜めアニメーション
const ANIM_LAND_LAG = "land_lag"      # 着地ラグアニメーション

ジャンプ溜めシステムの実装

溜め処理のメインロジック

# ジャンプ処理(溜め・着地ラグ対応)
func _handle_jump(delta: float) -> void:
	# 着地ラグ中はジャンプ不可
	if land_lag_timer > 0.0:
		land_lag_timer -= delta
		return

	# ジャンプ溜め開始
	if not is_jump_charging and Input.is_action_just_pressed(INPUT_JUMP) and is_on_floor():
		is_jump_charging = true
		jump_charge_timer = jump_charge_time
		jump_queued = true

	# ジャンプ溜め中
	if is_jump_charging:
		jump_charge_timer -= delta
		if jump_charge_timer <= 0.0 and jump_queued and is_on_floor():
			velocity.y = jump_velocity
			is_jump_charging = false
			jump_queued = false
	elif not is_on_floor():
		# 空中に出たら溜め解除
		is_jump_charging = false
		jump_queued = false

溜め中の移動制限

# 水平移動処理
func _handle_horizontal_movement() -> void:
	# 着地ラグ中・ジャンプ溜め中は移動不可
	if land_lag_timer > 0.0 or is_jump_charging:
		velocity.x = 0
		return

	var direction := Input.get_axis(INPUT_LEFT, INPUT_RIGHT)
	var is_running := Input.is_action_pressed(INPUT_RUN)

	if direction != 0:
		var current_speed := run_speed if is_running else speed
		velocity.x = direction * current_speed
		animated_sprite.flip_h = direction < 0
	else:
		velocity.x = 0

着地硬直システムの実装

着地検出と硬直開始

func _physics_process(delta: float) -> void:
	_apply_gravity(delta)
	_handle_jump(delta)
	_handle_horizontal_movement()
	move_and_slide()

	# 着地判定を更新
	var just_landed = is_on_floor() and not was_on_floor
	was_on_floor = is_on_floor()
	_handle_landing(just_landed)
	_update_animation()

# 着地時の処理
func _handle_landing(just_landed: bool) -> void:
	if just_landed:
		land_lag_timer = land_lag_time
		# 溜め中に着地した場合は溜め解除
		is_jump_charging = false
		jump_queued = false

アニメーション連携

状態に応じたアニメーション制御

# アニメーション更新
func _update_animation() -> void:
	# 着地ラグ中は専用アニメーション
	if land_lag_timer > 0.0:
		_play_animation(ANIM_LAND_LAG)
		return

	# ジャンプ溜め中は専用アニメーション
	if is_jump_charging:
		_play_animation(ANIM_JUMP_CHARGE)
		return

	if not is_on_floor():
		_play_animation(ANIM_JUMP)
		return

	var direction := Input.get_axis(INPUT_LEFT, INPUT_RIGHT)
	var is_running := Input.is_action_pressed(INPUT_RUN)

	if direction != 0:
		var animation := ANIM_RUN if is_running else ANIM_WALK
		_play_animation(animation)
	else:
		_play_animation(ANIM_IDLE)

# アニメーション再生(重複再生を避ける)
func _play_animation(animation_name: String) -> void:
	if animated_sprite.animation != animation_name:
		animated_sprite.play(animation_name)

実装のポイント

上記のコード例を組み合わせることで、溜めと硬直システムが実現できます。各関数は独立性を保ちながら連携し、戦略的な操作感を提供します。

カスタマイズ方法

タイミング調整

  • jump_charge_time: 溜め時間の調整(0.1〜0.5秒程度)
  • land_lag_time: 硬直時間の調整(0.1〜0.3秒程度)

段階的溜めシステム

# 溜め段階に応じたジャンプ力変更
var charge_level: int = 0
if jump_charge_timer <= jump_charge_time * 0.3:
    charge_level = 3
elif jump_charge_timer <= jump_charge_time * 0.6:
    charge_level = 2
else:
    charge_level = 1

velocity.y = jump_velocity * charge_level

硬直キャンセル機能

# 特定条件で硬直をキャンセル
if land_lag_timer > 0.0 and Input.is_action_just_pressed("dodge"):
    land_lag_timer = 0.0
    # 回避アクション実行

必要なアニメーション

AnimatedSprite2Dに以下のアニメーションを追加する必要があります:

  • jump_charge: 溜め中のアニメーション(膝を曲げる等)
  • land_lag: 着地硬直のアニメーション(体勢を崩している状態等)

まとめ

溜めと硬直システムを導入することで、単純な移動から戦略性のある操作感に変化します。タイミングを重視したゲームプレイが実現でき、プレイヤーの技術介入度を高められます。

ポイント

  • エクスポート変数でエディタから調整可能
  • 状態管理による確実な制御
  • アニメーション連携で視覚的フィードバック
  • カスタマイズ性の高い設計

このシステムを基にして、格闘ゲームやアクションゲームの操作感を実現してみてください。

参考資料


この記事はGodot 4.4以降を基準としています。