战斗场景搭建
本文最后更新于12 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

场景模板:battle_data

基于这个战斗场景元模板(BattleData),可以自定义以下战斗场景的各个方面:

🎯 基础信息配置

  • 战斗标题 ( battle_title ) – 设置战斗的名称
  • 战斗描述 ( battle_description ) – 多行文本描述,用于战斗日志或介绍

🎨 视觉与音频

  • 战斗背景 ( battle_background ) – 设置战斗场景的背景图片(Texture2D)
  • 战斗音乐 ( battle_music ) – 设置战斗时的背景音乐(AudioStream)

👥 角色配置

  • 敌人数据列表 ( enemy_data_list ) – 字典结构,键为CharacterData(角色数据),值为Vector2(战场位置)
  • 玩家角色数据列表 ( player_data_list ) – 可选,如果为空则使用全局玩家队伍,同样包含角色数据和位置

⏱️ 战斗规则

  • 最大回合数 ( max_turn_count ) – 设置战斗的最大回合数,超过自动失败(0表示无限制)
  • 是否允许逃跑 ( allow_escape ) – 控制玩家是否可以逃跑

🏆 战斗结果

  • 胜利场景 ( victory_scene ) – 战斗胜利后跳转的场景文件(.tscn)
  • 失败场景 ( defeat_scene ) – 战斗失败后跳转的场景文件(.tscn)

💰 奖励系统

  • 经验奖励 ( exp_reward ) – 战斗胜利后获得的经验值
  • 金币奖励 ( gold_reward ) – 战斗胜利后获得的金币数量
  • 物品奖励 ( item_rewards ) – 数组,包含战斗胜利后获得的物品

🎪 特殊战斗设置

  • Boss战标识 ( is_boss_battle ) – 标记是否为Boss战斗
  • 特殊条件 ( special_conditions ) – 字典结构,可以存储自定义的特殊战斗条件

🔧 实用功能

  • 获取敌人数量 ( get_enemy_count() ) – 方法,返回敌人数量
  • 获取玩家数量 ( get_player_count() ) – 方法,返回玩家角色数量
  • 数据有效性检查 ( is_valid() ) – 方法,检查战斗数据是否有效(至少需要敌人数据)


**总结一下 `main.gd` 的作用**:它就像一个启动器。当 `Main` 节点准备就绪时,它会创建并显示战斗场景,然后使用在编辑器里配置好的战斗数据来初始化这个场景。

接下来,为了完整地理解整个初始化流程,我们需要查看 `BattleScene` 和 `BattleData` 相关的脚本。我现在就来查找并分析这些脚本。



好的,我已经分析了 `battle_scene.gd` 和 `battle_data.gd` 的代码。现在,我们可以将所有信息串联起来,完整地了解一个战斗场景是如何被初始化的。

整个流程可以分为三个主要部分:**数据准备**、**场景加载** 和 **场景初始化**。

### 1. 数据准备 (`battle_data.gd`)

首先,我们来看 `d:\Desktop\Godot\course\43最终打磨\scripts\resources\battle_data.gd`。

gdscript
extends Resource
class_name BattleData

战斗标题

@export var battle_title: String = “战斗”

战斗背景

@export var battle_background: Texture2D

战斗音乐

@export var battle_music: AudioStream

敌人数据列表

@export var enemy_data_list: Dictionary[CharacterData, Vector2] = {}

玩家角色数据列表

@export var player_data_list: Dictionary[CharacterData, Vector2] = {}

… 其他战斗相关数据

这个脚本定义了一个 `BattleData` 资源。在 Godot 中,`Resource` 是一种纯粹的数据容器,非常适合用来存储配置信息。

-   **`@export`**: 你会看到大量的 `@export` 关键字。这意味着你可以在 Godot 编辑器的“检查器”面板中,像填写表单一样,为一场战斗配置所有需要的数据,而无需修改任何代码。
-   **核心数据**: 对于场景初始化来说,最重要的两个属性是:
    *   `player_data_list`: 一个字典,存储了所有**玩家角色**的数据 (`CharacterData`) 以及他们在场景中的初始**位置** (`Vector2`)。
    *   `enemy_data_list`: 与上面类似,但用于存储**敌人角色**的数据和位置。
-   **其他数据**: 还包括战斗的背景音乐 (`battle_music`)、标题、胜利/失败条件等。

所以,在战斗开始前,开发者会先创建一个 `BattleData` 资源文件,并在编辑器里填好这场战斗的所有细节。

### 2. 场景加载 (`main.gd`)

接下来是 `d:\Desktop\Godot\course\43最终打磨\main.gd`,它是整个流程的起点。

gdscript
extends Node2D
class_name Main

const BATTLE_SCENE = preload(“res://scenes/battle/battle_scene.tscn”)

@export var battle_data : BattleData

func _ready() -> void:
var battle_scene : BattleScene = BATTLE_SCENE.instantiate()
add_child(battle_scene)
battle_scene.initialize_battle(battle_data)

`main.gd` 的作用非常直接:

1.  **持有数据**: 它有一个 `@export var battle_data : BattleData` 成员。这意味着你可以在主场景中选中挂载了 `main.gd` 的节点,然后将我们第一步中创建的 `BattleData` 资源文件拖拽到这个变量上。
2.  **实例化场景**: 在 `_ready` 函数(当节点准备就绪时自动执行)中,它实例化了预加载的战斗场景 `battle_scene.tscn`。
3.  **传递数据**: 最关键的一步是,它调用了新建战斗场景实例的 `initialize_battle` 方法,并将持有的 `battle_data` 作为参数传递了过去。

### 3. 场景初始化 (`battle_scene.gd`)

最后,我们来看 `d:\Desktop\Godot\course\43最终打磨\scenes\battle\battle_scene.gd` 中的 `initialize_battle` 函数,这是初始化的核心。

gdscript
func initialize_battle(battle_data: BattleData) -> void:
# 1. 清理旧角色 (如果有的话)
for player in player_area.get_children():
player.queue_free()
for enemy in enemy_area.get_children():
enemy.queue_free()

# 2. 根据数据生成玩家角色
for player_data in battle_data.player_data_list:
    var pos : Vector2 = battle_data.player_data_list[player_data]
    var player: Character = _spawn_character(player_data, pos)
    player_area.add_child(player)
    battle_manager.add_character(player, true)

# 3. 根据数据生成敌人角色
for enemy_data in battle_data.enemy_data_list:
    var pos : Vector2 = battle_data.enemy_data_list[enemy_data]
    var enemy: Character = _spawn_character(enemy_data, pos)
    enemy.is_player = false
    enemy_area.add_child(enemy)
    battle_manager.add_character(enemy, false)

# 4. 设置音乐并播放
stream_player.stream = battle_data.battle_music
stream_player.play()

# 5. 连接信号并开始战斗
_connect_character_click_signals()
battle_manager.start_battle()

“`

这个函数接收到 battle_data 后,执行了以下一系列操作:

  1. 清场: 首先,它会清空 player_areaenemy_area 两个区域,确保不会有上一场战斗的角色残留。
  2. 生成玩家: 遍历 battle_data 中的 player_data_list。对列表中的每一个 player_data
    • 调用 _spawn_character 函数,这个函数会创建一个通用的 Character 场景实例。
    • player_data (包含角色的名字、属性、技能等) 赋值给这个新创建的 Character 实例。
    • 设置角色的位置。
    • 将角色添加到 player_area 节点下,使其显示在屏幕的玩家区域。
    • 将角色注册到 battle_manager(战斗管理器)中,并标记为玩家单位。
  3. 生成敌人: 重复与生成玩家几乎完全相同的步骤,但这次是遍历 enemy_data_list,并将角色添加到 enemy_area
  4. 设置音乐: 从 battle_data 中读取战斗音乐并开始播放。
  5. 开始战斗: 最后,调用 battle_manager.start_battle(),这会启动战斗的逻辑,比如决定哪个角色先行动。

总结

整个初始化流程是一个清晰的、数据驱动的设计模式:

编辑器配置 -> main.gd 读取配置并加载场景 -> battle_scene.gd 接收配置并动态构建场景

这种方式的好处是高度灵活。如果你想创建一场新的战斗,你不需要修改任何代码,只需要:

  1. 创建一个新的 CharacterData 资源来定义新敌人。
  2. 创建一个新的 BattleData 资源,在里面配置好敌人列表、玩家列表和音乐等。
  3. 在主场景中,将这个新的 BattleData 资源赋给 Main 节点的 battle_data 变量。
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇