# skill_tree_game

`游戏开发入门技能树`是[技能森林](https://gitcode.net/csdn/skill_tree)的一部分。

## 编辑环境初始化

```
pip install -r requirements.txt
```


## 目录结构说明

技能树编辑仓库的 data 目录是主要的编辑目录，目录的结构是固定的

* 技能树`骨架文件`：
    * 位置：`data/tree.json` 
    * 说明：该文件是执行 `python main.py` 生成的，请勿人工编辑
* 技能树`根节点`配置文件：
    * 位置：`data/config.json`
    * 说明：可编辑配置关键词等字段，其中 `node_id` 字段是生成的，请勿编辑
* 技能树`难度节点`：
    * 位置：`data/xxx`，例如: `data/1.游戏开发入门初阶`
    * 说明：
        * 每个技能树有 3 个等级，目录前的序号是必要的，用来保持文件夹目录的顺序
        * 每个目录下有一个 `config.json` 可配置关键词信息，其中 `node_id` 字段是生成的，请勿编辑
* 技能树`章节点`：
    * 位置：`data/xxx/xxx`，例如：`data/1.游戏开发入门初阶/1.简易游戏`
    * 说明：
        * 每个技能树的每个难度等级有 n 个章节，目录前的序号是必要的，用来保持文件夹目录的顺序
        * 每个目录下有一个 `config.json` 可配置关键词信息，其中 `node_id` 字段是生成的，请勿编辑
* 技能树`知识节点`：
    * 位置：`data/xxx/xxx`，例如：`data/1.游戏开发入门初阶/1.简易游戏`
    * 说明：
        * 每个技能树的每章有 n 个知识节点，目录前的序号是必要的，用来保持文件夹目录的顺序
        * 每个目录下有一个 `config.json`
            * 其中 `node_id` 字段是生成的，请勿编辑
            * 其中 `keywords` 可配置关键字字段
            * 其中 `children` 可配置该`知识节点`下的子树结构信息，参考后面描述
            * 其中 `export` 可配置该`知识节点`下的导出习题信息，参考后面描述

## `知识节点` 子树信息结构

例如 `data/1.游戏开发入门初阶/1.简易游戏/1.HelloGame/config.json` 里配置对该知识节点子树信息结构，这个配置是可选的：
```json
{
    // ...

    "children": [
    {
        "游戏开发入门": {
          "keywords": [
            "游戏开发",
            "入门"
          ],
          "children": [],
          "keywords_must": [
            "起源"
          ],
          "keywords_forbid": []
        }
    }
  ],
}
```

## `知识节点` 的导出习题编辑

例如 `data/1.游戏开发入门初阶/1.简易游戏/1.HelloGame/config.json` 里配置对该知识节点导出的习题

```json
{
    // ...
    "export": [
        "helloworld.json"
    ]
}
```

helloworld.json 的格式如下：
```bash
{
  "type": "code_options",
  "author": "huanhuilong",
  "source": "helloworld.md",
  "notebook_enable": false,
  "exercise_id": "c821a21bb363442eab64f0aea124f3bd"
}
```

其中 
* "type": "code_options" 是固定的
* "author" 可以放作者的 CSDN id，
* "source" 指向了习题 MarkDown文件
* "notebook_enable" 目前都是false
* "exercise_id" 是工具生成的，不填


示例 helloworld.md 如下：

````mardown
# 一个简单的 Python 小游戏

我们可以使用 python 的 pygame 快速建立一个弹球游戏，环境依赖
* 安装 python
* 使用 python 的包管理程序，安装依赖的 pygame 包：`pip install pygame`

编写你的第一游戏代码`game.py`，代码如下：

```python
import sys
import pygame

# 初始化
pygame.init()

# 游戏对话框大小
size = width, height = 320, 240

# 小球移动速度
speed = [2, 2]

# 黑色背景
black = 0, 0, 0

# 创建游戏屏幕
screen = pygame.display.set_mode(size)

# 加载小球 gif
ball = pygame.image.load("ball.gif")

# 获取游戏图片的矩形框
ballrect = ball.get_rect()

# 游戏循环
while 1:
    # 判断是否退出
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

    # 按 speed 速度，计算移动小球后的矩形框
    ballrect = ballrect.move(speed)

    # 更新速度（大小和方向）
    if ballrect.left < 0 or ballrect.right > width:
        speed[0] = -speed[0]
    if ballrect.top < 0 or ballrect.bottom > height:
        speed[1] = -speed[1]

    # 绘制黑色背景
    screen.fill(black)

    # 绘制小球
    screen.blit(ball, ballrect)

    # 使用双缓存机制刷新屏幕
    pygame.display.flip()
```

其中小球 gif 资源如下：

![](./test/ball.gif)

使用命令`python game.py`启动游戏，游戏启动后的画面如下

![](./test/ball_game.gif)

以下关于上述游戏代码说法错误的是？

## 答案

编写游戏只能使用 pygame

## 选项

### A

一个游戏程序，一般有一个死循环，返回绘制游戏画面

### B

许多游戏的渲染，都会采用双缓存机制，在背后的帧里面做渲染，再一次性刷新到前台帧

### C

在游戏循环里，可以检测各种交互事件，并响应事件，从而完成游戏玩家和游戏的互动，例如：退出游戏
````

## 技能树合成

在根目录下执行 `python main.py` 会合成技能树文件，合成的技能树文件: `data/tree.json`
* 合成过程中，会自动检查每个目录下 `config.json` 里的 `node_id` 是否存在，不存在则生成
* 合成过程中，会自动检查每个知识点目录下 `config.json` 里的 `export` 里导出的习题配置，检查是否存在`exercise_id` 字段，如果不存在则生成
* 在 节 目录下根据需要，可以添加一些子目录用来测试代码，例如在 data/1.游戏开发入门进阶/1.简易游戏/1.HelloGame/ 节目录下，为了测试方便，增加了一个 test/ 子目录，放测试游戏代码
* 开始游戏入门技能树构建之旅，GoodLuck! 
