资讯动态

21、游戏架构设计模式

发布时间:2026/9/14 22:26:16 来源:尧图企业网站定制
第21章 游戏架构设计模式21.1 组合模式# 通过组合节点构建复杂对象而非深层继承 # HealthComponent.gd extends Node signal health_changed(current: int, maximum: int) signal died export var max_health: int 100 var health: int func _ready() - void: health max_health func take_damage(amount: int) - void: health clampi(health - amount, 0, max_health) health_changed.emit(health, max_health) if health 0: died.emit() func heal(amount: int) - void: health clampi(health amount, 0, max_health) health_changed.emit(health, max_health)# HitboxComponent.gd extends Area2D export var damage: int 10 export var knockback: float 300.0# HurtboxComponent.gd extends Area2D signal hurt(damage: int, knockback_dir: Vector2) func _ready() - void: area_entered.connect(_on_area_entered) func _on_area_entered(area: Area2D) - void: if area.get(damage) ! null: var dir : (global_position - area.global_position).normalized() hurt.emit(area.damage, dir * area.knockback)# 使用组合构建角色 # Player (CharacterBody2D) # ├── Sprite2D # ├── CollisionShape2D # ├── HealthComponent # ├── HitboxComponent (攻击判定) # ├── HurtboxComponent (受击区域) # └── InteractionComponent (交互) # Player.gd - 只负责移动和状态不关心具体系统 extends CharacterBody2D func _ready() - void: $HealthComponent.died.connect(_on_died) $HurtboxComponent.hurt.connect(_on_hurt) func _on_hurt(damage: int, knockback: Vector2) - void: $HealthComponent.take_damage(damage) velocity knockback21.2 状态模式# 脚本化状态方案每个状态是一个独立脚本 class_name State extends Node signal finished(next_state: String) var state_machine: Node var actor: CharacterBody2D func enter() - void: pass func exit() - void: pass func update(delta: float) - void: pass func physics_update(delta: float) - void: pass# StateMachine.gd extends Node export var initial_state: State var current_state: State var states: Dictionary {} func _ready() - void: for child in get_children(): if child is State: states[child.name.to_lower()] child child.state_machine self child.actor get_parent() if initial_state: initial_state.enter() current_state initial_state func _process(delta: float) - void: if current_state: current_state.update(delta) func _physics_process(delta: float) - void: if current_state: current_state.physics_update(delta) func transition_to(state_name: String) - void: var new_state states.get(state_name.to_lower()) if new_state null or new_state current_state: return current_state.exit() current_state new_state current_state.enter()# IdleState.gd extends State func enter() - void: actor.velocity.x 0 actor.get_node(AnimatedSprite2D).play(idle) func physics_update(delta: float) - void: var input_dir : Input.get_axis(move_left, move_right) if absf(input_dir) 0.1: finished.emit(run) elif Input.is_action_just_pressed(jump): finished.emit(jump)21.3 观察者模式信号解耦# 使用信号实现松耦合通信 # 发送者不需要知道接收者是谁 # 敌人死亡时发送信号 # Enemy.gd signal died(enemy_type: String, position: Vector2) func die() - void: died.emit(slime, global_position) queue_free() # 任何系统都可以监听 # ScoreSystem.gd func _ready() - void: # 连接到场景中所有敌人的 died 信号 get_tree().node_added.connect(_on_node_added) func _on_node_added(node: Node) - void: if node.has_signal(died): node.died.connect(_on_enemy_died) func _on_enemy_died(type: String, pos: Vector2) - void: GameManager.add_score(get_score_for_type(type))21.4 事件总线# event_bus.gd - Autoload extends Node # 游戏事件 signal enemy_killed(enemy_type: String, position: Vector2) signal item_collected(item_type: String, amount: int) signal player_damaged(damage: int) signal boss_defeated(boss_name: String) signal level_up(new_level: int) # 任何地方都可以发送和监听 # 发送EventBus.enemy_killed.emit(slime, position) # 监听EventBus.enemy_killed.connect(_on_enemy_killed)21.5 依赖注入# 避免硬编码引用通过注入依赖解耦 # ❌ 硬耦合 extends Node2D func _ready() - void: var player get_node(/root/Main/Player) # 路径写死 player.health_changed.connect(_on_health_changed) # ✅ 依赖注入 extends Node2D export var player: CharacterBody2D # 在编辑器中拖入 # ✅ 使用组查找 extends Node2D func _ready() - void: var players : get_tree().get_nodes_in_group(player) if not players.is_empty(): players[0].health_changed.connect(_on_health_changed) # ✅ 使用 Autoload extends Node2D func _ready() - void: EventBus.player_damaged.connect(_on_player_damaged)实操练习练习组件化敌人系统# 创建以下组件 # 1. HealthComponent - 生命值管理 # 2. HitboxComponent - 攻击判定 # 3. HurtboxComponent - 受击区域 # 4. PatrolComponent - 巡逻行为 # 5. ChaseComponent - 追踪行为 # 使用组件组合不同类型的敌人 # Slime Health Hurtbox Patrol # Skeleton Health Hitbox Hurtbox Patrol Chase # Boss Health Hitbox Hurtbox Chase 特殊攻击

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价