208 lines
6.3 KiB
Markdown
208 lines
6.3 KiB
Markdown
# 用 FLTK 做 GUI 抽卡游戏 · 6 课时教程
|
||
|
||
面向 **11 岁左右** 学习者,已完成命令行 C++ 10 课基础(变量、输入、随机、判断、循环、数组、函数、菜单)。本教程用 **FLTK 框架** 制作带窗口和按钮的抽卡游戏。
|
||
|
||
每课约 **30~45 分钟**,建议家长陪同。
|
||
|
||
> 📌 **新版本教程的最大变化**:每课不再"一次给完整源码让你抄",而是**分成 3~5 个小步骤**,每步加几行代码、立刻编译看效果。卡住时再去看 `solutions/` 里的完整答案。
|
||
|
||
---
|
||
|
||
## 前置条件(给家长)
|
||
|
||
孩子需已掌握:
|
||
- `int`、`string` 变量
|
||
- `cin` / `cout`
|
||
- `rand()` / `srand()`
|
||
- `if` / `else if` / `else`
|
||
- `for` 循环
|
||
- `string` 数组
|
||
- `void` 函数
|
||
- `while` 循环与 `break`
|
||
|
||
---
|
||
|
||
## 一次性环境安装
|
||
|
||
### Mac(目标平台)
|
||
|
||
```bash
|
||
brew install fltk cmake
|
||
```
|
||
|
||
> 装 `cmake` 是必需的——FLTK 自己不带编译入口。
|
||
> 如果 `brew` 卡在 "Auto-updating",先 `export HOMEBREW_NO_AUTO_UPDATE=1` 再重试。
|
||
|
||
### Windows(开发用)
|
||
|
||
1. 装 Visual Studio(带 C++ 工作负载)和 CMake。
|
||
2. 装 vcpkg:`git clone https://github.com/microsoft/vcpkg && .\vcpkg\bootstrap-vcpkg.bat`
|
||
3. 装 FLTK:`vcpkg install fltk --triplet x64-windows`
|
||
|
||
---
|
||
|
||
## 仓库结构
|
||
|
||
```
|
||
chouka/
|
||
├── CMakeLists.txt ← 一份通用 CMake,按 -DLESSON=N 切课
|
||
├── lesson_gui_1.cpp ~ 6.cpp ← 每课的「起步骨架」(孩子动手填的)
|
||
├── solutions/
|
||
│ └── lesson_gui_1.cpp ~ 6.cpp ← 老师的完整答案(卡住再看)
|
||
├── 第01课-... ~ 第06课-....md ← 6 课文档
|
||
├── 教程-FLTK抽卡游戏-GUI-6课.md ← 本文件(总目录)
|
||
└── 学习进度与状态-GUI.md ← 进度追踪
|
||
```
|
||
|
||
---
|
||
|
||
## 编译运行(每课都一样)
|
||
|
||
**Mac / Linux:**
|
||
```bash
|
||
cmake -B build -DLESSON=1 # 第一次配置;切课就改这个 1
|
||
cmake --build build
|
||
./build/gacha1
|
||
```
|
||
|
||
**Windows(vcpkg):**
|
||
```bash
|
||
cmake -B build -DLESSON=1 -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||
cmake --build build --config Release
|
||
build\Release\gacha1.exe
|
||
```
|
||
|
||
之后改了 `.cpp` 想再运行:
|
||
```bash
|
||
cmake --build build && ./build/gacha1 # Mac/Linux
|
||
cmake --build build --config Release # Windows,然后 build\Release\gacha1.exe
|
||
```
|
||
|
||
### 看老师写好的完整答案
|
||
|
||
加 `-DUSE_SOLUTION=ON` 重新配置,会从 `solutions/` 编译:
|
||
```bash
|
||
cmake -B build -DLESSON=1 -DUSE_SOLUTION=ON
|
||
cmake --build build && ./build/gacha1
|
||
```
|
||
|
||
> 💡 切换课次或切换骨架/答案后,**必须重新跑一次 `cmake -B build -D...`**,否则会继续编译上次的源文件。
|
||
|
||
---
|
||
|
||
## 关于 emoji(🎴💰🎉 等)
|
||
|
||
教程里偶尔用了 emoji 让按钮更可爱。如果你看到的是空白方块(FLTK 默认字体不一定带 emoji),把它换成普通文字就行,例如:
|
||
- `"🎴 抽一张!"` → `"[抽一张]"`
|
||
- `"💰"` → `"$"`
|
||
|
||
效果不变,只是外观区别。
|
||
|
||
---
|
||
|
||
## 总说明
|
||
|
||
- **原则**:每课都能跑出一个**看得见**的进步——从空窗口到完整游戏,每一步都能编译运行。
|
||
- **抽卡**:用随机数模拟概率,不涉及真实金钱。
|
||
- **FLTK**:一个轻量 GUI 库,编译出的程序只有几 MB。
|
||
- **跨平台**:同一份代码在 Windows / Mac / Linux 都能编译运行。
|
||
|
||
---
|
||
|
||
## 第 1 课:GUI 你好窗口
|
||
|
||
**目标**:自己一步步写出第一个 GUI 程序——一个窗口、一行欢迎语。
|
||
|
||
**FLTK 新概念**:`Fl_Window`(窗口)、`Fl_Box`(文字标签)、`Fl::run()`(事件循环)
|
||
|
||
**对比旧知识**:`std::cout` 把字打在命令行 → `Fl_Box` 把字显示在窗口里
|
||
|
||
详见:`第01课-GUI你好窗口.md`
|
||
|
||
---
|
||
|
||
## 第 2 课:按钮与回调
|
||
|
||
**目标**:放一个按钮,点击后文字会变——理解"事件驱动"。
|
||
|
||
**FLTK 新概念**:`Fl_Button`(按钮)、`callback`(回调函数)、全局指针
|
||
|
||
**核心思想**:和命令行不同,GUI 程序"等"用户操作,而不是按顺序执行。
|
||
|
||
详见:`第02课-按钮与回调.md`
|
||
|
||
---
|
||
|
||
## 第 3 课:随机抽卡——核心来了
|
||
|
||
**目标**:点击按钮 → 随机出普通/稀有/超稀有,显示在窗口里。
|
||
|
||
**复用旧知识**:`rand()` / `srand()`、`if` / `else if` / `else`
|
||
|
||
**FLTK 新概念**:在回调里更新控件、`label()` 方法、`sprintf` 拼字符串
|
||
|
||
详见:`第03课-随机抽卡.md`
|
||
|
||
---
|
||
|
||
## 第 4 课:十连抽
|
||
|
||
**目标**:一个按钮抽 10 次,结果一起显示。
|
||
|
||
**复用旧知识**:`for` 循环、`std::string` 拼接
|
||
|
||
**FLTK 新概念**:多行显示(`\n` 换行)、文字对齐
|
||
|
||
详见:`第04课-十连抽.md`
|
||
|
||
---
|
||
|
||
## 第 5 课:卡片名字与布局
|
||
|
||
**目标**:给每种稀有度配上具体的卡片名字,让抽卡更有趣。学会让界面更整齐。
|
||
|
||
**复用旧知识**:`std::string` 数组、下标
|
||
|
||
**FLTK 新概念**:控件位置计算、`box()` 与 `color()`
|
||
|
||
详见:`第05课-卡片名字与布局.md`
|
||
|
||
---
|
||
|
||
## 第 6 课:完整抽卡游戏
|
||
|
||
**目标**:整合前面全部内容,做一个完整的抽卡游戏——多个按钮、金币系统、统计面板。
|
||
|
||
**复用旧知识**:全部旧知识
|
||
|
||
**FLTK 新概念**:多按钮协作、综合布局、函数复用
|
||
|
||
详见:`第06课-完整抽卡游戏.md`
|
||
|
||
---
|
||
|
||
## 知识点对照表
|
||
|
||
| 课次 | FLTK 新概念 | 复用的 C++ 知识 |
|
||
|------|------------|----------------|
|
||
| 1 | `Fl_Window`、`Fl_Box`、`Fl::run()`、`new` | `main`、`#include` |
|
||
| 2 | `Fl_Button`、`callback`、全局指针 | `void` 函数 |
|
||
| 3 | `label()` 更新、回调中用随机 | `rand`/`srand`、`if`/`else`、`%` |
|
||
| 4 | 多行 label、字符串拼接 | `for`、`std::string`、`+=` |
|
||
| 5 | 控件定位、`box()`/`color()` | `string` 数组、下标、`rand()%N` |
|
||
| 6 | 多按钮回调、综合布局 | 全部知识综合 |
|
||
|
||
---
|
||
|
||
## 给小朋友的 GUI 比喻
|
||
|
||
- **窗口** 像一张画纸。
|
||
- **控件**(Widget)像贴在画纸上的便利贴——文字标签、按钮。
|
||
- **回调函数** 像"按钮被按时要做什么"的说明书。
|
||
- **事件循环**(`Fl::run()`)像一个永不休息的保安,一直等用户操作。
|
||
- 命令行程序像"一口气读完的清单",GUI 程序像"一直等着你来的游戏机"。
|
||
|
||
---
|
||
|
||
*每课详细步骤见对应文档。学完一课,记得在 `学习进度与状态-GUI.md` 里打个勾。*
|