7. 关卡推进
2026/4/14大约 5 分钟
7. 咸鱼之王——关卡推进
7.1 什么是关卡系统?
想象你爬一座塔。一楼很简单,二楼稍微难一点,到了十楼就是Boss了,打败它才能上二楼。每一层都比上一层更难,但你也会变得更强。
关卡系统就是这座"塔"。玩家从第1关开始,一关一关地往上推。每通过一关,就能获得金币奖励,同时解锁下一关。每10关有一个Boss,更难打但奖励更丰厚。
关卡结构
第1章(新手村)
├── 第1关 怪物HP: 200 金币奖励: 20
├── 第2关 怪物HP: 240 金币奖励: 40
├── 第3关 怪物HP: 280 金币奖励: 60
├── ...
├── 第9关 怪物HP: 520 金币奖励: 180
└── 第10关 [Boss] 怪物HP: 3000 金币奖励: 400
第2章(幽暗森林)
├── 第11关 怪物HP: 600 金币奖励: 220
├── ...7.2 难度递增曲线
关卡的难度不是"均匀增长"的,而是有一定的曲线设计:
| 关卡段 | 难度增长 | 设计目的 |
|---|---|---|
| 1~30关 | 缓慢增长 | 新手引导期,让玩家快速体验 |
| 31~60关 | 中等增长 | 需要开始认真培养英雄 |
| 61~100关 | 快速增长 | 需要抽到稀有英雄、强化装备 |
| 100关+ | 指数增长 | 后期挑战,需要传说英雄满级 |
难度计算公式
// 怪物血量 = 基础血量 x (1 + 关卡号 x 0.2)
// Boss关额外 x 5
int enemyHp = 200 * (1 + (stageId - 1) * 0.2);
if (isBoss) enemyHp *= 5;7.3 关卡管理器
C
using Godot;
using System.Collections.Generic;
/// <summary>
/// 关卡管理器——管理关卡进度和扫荡
/// </summary>
public partial class StageManager : Node
{
private int _highestClearedStage = 0; // 已通过的最高关卡
private HashSet<int> _sweepableStages = new(); // 可扫荡的关卡
// 信号
[Signal] public delegate void StageClearedEventHandler(
int stageId, StageData stageData);
[Signal] public delegate void SweepCompletedEventHandler(
int stageId, int totalGold);
/// <summary>
/// 获取关卡数据
/// </summary>
public StageData GetStage(int stageId)
{
return StageData.Generate(stageId);
}
/// <summary>
/// 获取章节信息
/// </summary>
public (int chapter, int totalStages) GetChapterInfo(int stageId)
{
int chapter = (stageId - 1) / IdleConstants.StagesPerChapter + 1;
return (chapter, IdleConstants.StagesPerChapter);
}
/// <summary>
/// 检查关卡是否已通过(可扫荡)
/// </summary>
public bool IsStageCleared(int stageId)
{
return stageId <= _highestClearedStage;
}
/// <summary>
/// 扫荡已通过的关卡
/// </summary>
public void SweepStage(int stageId)
{
if (!IsStageCleared(stageId))
{
GD.Print("该关卡尚未通过,无法扫荡!");
return;
}
var stage = StageData.Generate(stageId);
GameManager.Instance.AddGold(stage.GoldReward);
GD.Print($"扫荡 {stage.Name},获得 {stage.GoldReward} 金币");
EmitSignal(SignalName.SweepCompleted, stageId, stage.GoldReward);
}
/// <summary>
/// 批量扫荡(一键扫荡当前章节所有已通关关卡)
/// </summary>
public void SweepChapter(int chapter)
{
int startStage = (chapter - 1) * IdleConstants.StagesPerChapter + 1;
int endStage = Mathf.Min(
startStage + IdleConstants.StagesPerChapter - 1,
_highestClearedStage);
int totalGold = 0;
int stagesSwept = 0;
for (int i = startStage; i <= endStage; i++)
{
var stage = StageData.Generate(i);
totalGold += stage.GoldReward;
stagesSwept++;
}
GameManager.Instance.AddGold(totalGold);
GD.Print($"扫荡第{chapter}章 {stagesSwept}关," +
$"共获得 {totalGold} 金币");
EmitSignal(SignalName.SweepCompleted, startStage, totalGold);
}
/// <summary>
/// 获取当前可挑战的关卡
/// </summary>
public int GetCurrentStage()
{
return _highestClearedStage + 1;
}
/// <summary>
/// 关卡通关
/// </summary>
public void OnStageCleared(int stageId)
{
if (stageId > _highestClearedStage)
{
_highestClearedStage = stageId;
}
var stage = StageData.Generate(stageId);
EmitSignal(SignalName.StageCleared, stageId, stage);
}
/// <summary>
/// 获取推图进度信息
/// </summary>
public string GetProgressText()
{
int chapter = (_highestClearedStage / IdleConstants.StagesPerChapter) + 1;
int stageInChapter = _highestClearedStage % IdleConstants.StagesPerChapter;
if (stageInChapter == 0 && _highestClearedStage > 0)
{
chapter--;
stageInChapter = IdleConstants.StagesPerChapter;
}
return $"第{chapter}章 第{stageInChapter}关";
}
}GDScript
extends Node
## 关卡管理器——管理关卡进度和扫荡
var _highest_cleared_stage: int = 0
var _sweepable_stages: Array[int] = []
# 信号
signal stage_cleared(stage_id: int, stage_data: Dictionary)
signal sweep_completed(stage_id: int, total_gold: int)
## 获取关卡数据
func get_stage(stage_id: int) -> Dictionary:
return StageData.generate(stage_id)
## 检查关卡是否已通过
func is_stage_cleared(stage_id: int) -> bool:
return stage_id <= _highest_cleared_stage
## 扫荡已通过的关卡
func sweep_stage(stage_id: int) -> void:
if not is_stage_cleared(stage_id):
print("该关卡尚未通过,无法扫荡!")
return
var stage = StageData.generate(stage_id)
GameManager._gold += stage.gold_reward
print("扫荡 ", stage.name, ",获得 ", stage.gold_reward, " 金币")
sweep_completed.emit(stage_id, stage.gold_reward)
## 批量扫荡章节
func sweep_chapter(chapter: int) -> void:
var start_stage: int = (chapter - 1) * IdleConstants.STAGES_PER_CHAPTER + 1
var end_stage: int = mini(
start_stage + IdleConstants.STAGES_PER_CHAPTER - 1,
_highest_cleared_stage
)
var total_gold: int = 0
var stages_swept: int = 0
for i in range(start_stage, end_stage + 1):
var stage = StageData.generate(i)
total_gold += stage.gold_reward
stages_swept += 1
GameManager._gold += total_gold
print("扫荡第%d章 %d关,共获得 %d 金币" % [chapter, stages_swept, total_gold])
sweep_completed.emit(start_stage, total_gold)
## 关卡通关
func on_stage_cleared(stage_id: int) -> void:
if stage_id > _highest_cleared_stage:
_highest_cleared_stage = stage_id
var stage = StageData.generate(stage_id)
stage_cleared.emit(stage_id, stage)
## 获取推图进度
func get_progress_text() -> String:
var chapter: int = _highest_cleared_stage / IdleConstants.STAGES_PER_CHAPTER + 1
var stage_in_chapter: int = _highest_cleared_stage % IdleConstants.STAGES_PER_CHAPTER
if stage_in_chapter == 0 and _highest_cleared_stage > 0:
chapter -= 1
stage_in_chapter = IdleConstants.STAGES_PER_CHAPTER
return "第%d章 第%d关" % [chapter, stage_in_chapter]7.4 扫荡系统
扫荡(Sweep)是放置游戏的标配功能。当你已经通关了某个关卡后,不需要再打一遍,可以一键获取奖励。就像你已经看过一部电影了,不需要重新看一遍,直接拿"观影记录"就行。
| 功能 | 说明 |
|---|---|
| 单关扫荡 | 对已通关的单个关卡,一键获取金币奖励 |
| 章节扫荡 | 对整个章节所有已通关关卡,批量获取奖励 |
| 扫荡条件 | 必须先手动通过至少一次才能扫荡 |
7.5 Boss关设计
每章第10关是Boss关,Boss有以下特点:
| 特点 | 说明 |
|---|---|
| 血量x5 | Boss的血量是普通怪的5倍 |
| 攻击力更高 | Boss攻击力为普通怪的2倍 |
| 特殊技能 | Boss有独特技能(如群体攻击) |
| 丰厚奖励 | 通关奖励是普通关的10倍以上 |
7.6 关卡选择UI
┌──────────────────────────────────────┐
│ 第 3 章 │
│ 幽暗森林 │
│ │
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │ 1 │ │ 2 │ │ 3 │ │ 4 │ │ 5 │ │
│ │ ✓ │ │ ✓ │ │ ✓ │ │ ✓ │ │ ✓ │ │
│ └───┘ └───┘ └───┘ └───┘ └───┘ │
│ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │
│ │ 6 │ │ 7 │ │ 8 │ │ 9 │ │10 │ │
│ │ ✓ │ │ ✓ │ │ ✓ │ │ ✓ │ │ ✓ │ │
│ └───┘ └───┘ └───┘ └───┘ └───┘ │
│ │
│ 当前进度: 第4章 第3关 │
│ [一键扫荡第3章] │
└──────────────────────────────────────┘7.7 本章小结
| 知识点 | 说明 |
|---|---|
| 章节结构 | 每章10关+1Boss,难度递增 |
| 难度曲线 | 前期缓慢、中期中等、后期指数增长 |
| 扫荡功能 | 已通关关卡可一键获取奖励 |
| Boss关 | 血量x5、攻击x2、特殊技能、丰厚奖励 |
| 推图进度 | 记录最高通关关卡,自动挑战下一关 |
下一章我们将搭建完整的游戏界面。
