# 死亡經驗遊戲資料包 1.0.0
## 遊戲概述
遊戲開始後系統會持續發給玩家經驗瓶,而玩家要用手中的經驗瓶來提高其他玩家的經驗等級,當有玩家達到指定的等級時,將會被淘汰,而最後一個留在場上的玩家將會獲勝
## 資料包內容
### 資料包結構
```
death_exp_datapack/
├── pack.mcmeta
├── pack.png
└── data/
├── minecraft/
│ └── tags/
│ └── function/
│ └── tick.json
└── death_exp/
└── function/
├── start_game.mcfunction
├── init.mcfunction
├── give_bottle.mcfunction
├── check_level.mcfunction
├── eliminate.mcfunction
└── winner.mcfunction
```
### pack.mcmeta
```mcmeta
{
"pack": {
"pack_format": 61,
"description": "死亡經驗遊戲資料包"
}
}
```
### tick.json
```json
{
"values": [
"death_exp:give_bottle"
]
}
```
- 遊戲每刻執行的功能
### start_game.mcfunction
```mcfunction=
scoreboard objectives add game_running dummy
scoreboard objectives add players dummy
execute as @a[gamemode=!spectator] run function death_exp:init
scoreboard players set running game_running 1
execute as @a[gamemode=!spectator] run scoreboard players add admin players 1
tellraw @a {"text":"遊戲開始!","color":"green"}
```
- 啟動遊戲,初始化遊戲狀態
### init.mcfunction
```mcfunction=
xp set @s 0 levels
clear @s
give @s minecraft:experience_bottle 1
scoreboard players set running game_running 0
scoreboard players set admin players 0
execute as @a run gamemode adventure @s
```
- 初始化玩家的經驗、物品和記分板
### give_bottle.mcfunction
```mcfunction=
execute as @a[gamemode=!spectator] unless data entity @s Inventory[{Slot:0b}] run give @s minecraft:experience_bottle 1
execute if score running game_running matches 1 run function death_exp:check_level
```
- 確保玩家持有無限經驗瓶
- 有條件觸發`check_level`
### check_level.mcfunction
```mcfunction=
execute as @a[gamemode=!spectator, level=30..] run function death_exp:eliminate
execute if score admin players matches 1 run function death_exp:winner
```
- 檢查玩家經驗是否達到淘汰條件或遊戲結束條件
### eliminate.mcfunction
```mcfunction=
execute as @a[gamemode=!spectator, level=30..] run tellraw @a {"text":"","extra":[{"selector":"@s","color":"yellow"},{"text":" 被淘汰!","color":"red"}]}
execute as @a[gamemode=!spectator, level=30..] run scoreboard players remove admin players 1
execute as @a[gamemode=!spectator, level=30..] run gamemode spectator @s
```
- 處理符合淘汰條件的玩家,並通知其他玩家
### winner.mcfunction
```mcfunction=
execute as @a[gamemode=!spectator, limit=1] run tellraw @a {"text":"","extra":[{"selector":"@s","color":"gold"},{"text":" 獲勝!","color":"green"}]}
function death_exp:init
```
- 宣佈贏家
## 指令碼解釋
### start_game.mcfunction
```mcfunction=
scoreboard objectives add game_running dummy
scoreboard objectives add players dummy
execute as @a[gamemode=!spectator] run function death_exp:init
scoreboard players set running game_running 1
execute as @a[gamemode=!spectator] run scoreboard players add admin players 1
tellraw @a {"text":"遊戲開始!","color":"green"}
```
#### 第一行
```mcfunction
scoreboard objectives add game_running dummy
```
- 功能:
建立一個名為`game_running`的計分板目標
- 語法結構:
```mcfunction
scoreboard objectives add <記分板名稱> <類型> [顯示名稱]
```
- 記分板名稱(`game_running`):自訂的計分板名稱
- 類型(`dummy`):指定此計分板為手動更新
- 顯示名稱(可選):可為此計分板設定玩家可見的名稱(不設則默認使用名稱),格式須為json格式(例如`["ABC"]`,名稱為ABC)
#### 第二行
```mcfunction
scoreboard objectives add players dummy
```
- 功能:
建立一個名為`players`的計分板目標
- 語法結構:
與**第一行**相同
#### 第三行
```mcfunction!
execute as @a[gamemode=!spectator] run function death_exp:init
```
- 功能:
以非旁觀者模式的所有玩家為執行者,執行`death_exp:init`函式
- 語法結構:
```mcfunction
execute as <目標> run <指令或函式>
```
- 目標(`@a[gamemode=!spectator]`):將非旁觀者模式的所有玩家作為執行者
- `run`:執行指定的指令或函式
- 指令或函式(`function death_exp:init`):執行資料包中的名為 `init`的函式
#### 第四行
```mcfunction
scoreboard players set running game_running 1
```
- 功能:
將`game_running`計分板上的一個虛擬玩家`running`的分數設為`1`
- 語法結構:
```mcfunction!
scoreboard players set <玩家或虛擬玩家> <記分板名稱> <分數>
```
- 玩家或虛擬玩家(`running`):這裡的`running`是一個虛擬玩家,不是真正的玩家,而是用來保存數據的名稱
- 記分板名稱(`game_running`):就是計分板的名稱
- 分數(`1`):設定的數值
- 補充:
這行的目的是將`game_running`的狀態設為「運行中」。之後可以用條件檢查這個狀態,例如:
```mcfunction
execute if score running game_running matches 1 run say 遊戲正在進行!
```
#### 第五行
```mcfunction
execute as @a[gamemode=!spectator] run scoreboard players add admin players 1
```
- 功能:
以非旁觀者模式的所有玩家為執行者,執行`scoreboard players add admin players 1`,增加`players`
- 語法結構:
**第三行**和**第四行**的結合,但將第四行的`set`(設定)改為`add`(增加)
#### 第六行
```mcfunction
tellraw @a {"text":"遊戲開始!","color":"green"}
```
- 功能:
向所有玩家宣布遊戲已開始
- 語法結構:
```mcfunction
tellraw <目標> <訊息 JSON>
```
- 目標(`@a`):傳送訊息給的玩家,這裡是所有玩家
- 訊息 JSON:訊息的內容與格式,使用 JSON 格式來定制顯示效果
- `text`:訊息文字
- `color`:文字顏色
- 補充:
要啟動遊戲時只要在聊天欄輸入以下內容:
```mcfunction
/function death_exp:start_game
```
就可以開始遊戲
另外,若要避免重複啟動遊戲,可以使用以下指令
```mcfunction
/execute if score running game_running matches 0 run function death_exp:start_game
```
### init.mcfunction
```mcfunction=
xp set @s 0 levels
clear @s
give @s minecraft:experience_bottle 1
scoreboard players set running game_running 0
scoreboard players set admin players 0
execute as @a run gamemode survival @s
```
#### 第一行
```mcfunction
xp set @s 0 levels
```
- 功能:
將目標的等級經驗設為`0`
- 語法結構:
```mcfunction
xp set <目標> <數值> levels
```
- `set`: 設定目標的經驗值
- 目標(`@s`):要被設定的玩家(這裡是執行`init.mcfunction`的玩家)
- 數值(`0`):設定的等級數值,這裡是`0`
- `levels`:指明是「**等級**」而非「**經驗點數**」
#### 第二行
```mcfunction
clear @s
```
- 功能:
清空目標的背包
- 語法結構:
```mcfunction
clear <目標>
```
- 目標(`@s`):要被清空背包的玩家(這裡是執行`init.mcfunction`的玩家)
#### 第三行
```mcfunction
give @s minecraft:experience_bottle 1
```
- 功能:
給予目標一瓶經驗瓶
- 語法結構:
```mcfunction
give <目標> <物品> [數量]
```
- 目標(`@s`):要被給予的對象(這裡是執行`init.mcfunction`的玩家)
- 物品(`minecraft:experience_bottle`):要給予的物品
- 數量(`1`):要給多少
#### 第四行
```mcfunction
scoreboard players set running game_running 0
```
- 功能:
將`game_running`設為`0`
- 語法結構:
與「**start_game**」**第四行**相同,但將第四行的set(設定)改為add(增加)
#### 第五行
```mcfunction
scoreboard players set admin players 0
```
- 功能:
將`players`設為`0`
- 語法結構:
與**第四行**相同
#### 第六行
```mcfunction
execute as @a run gamemode adventure @s
```
- 功能:
以所有玩家為執行者,將玩家自己設為冒險模式
- 語法結構:
與「**start_game**」**第三行**相同
### give_bottle.mcfunction
```mcfunction=
execute as @a[gamemode=!spectator] unless data entity @s Inventory[{Slot:0b}] run give @s minecraft:experience_bottle 1
execute if score running game_running matches 1 run function death_exp:check_level
```
#### 第一行
```mcfunction
execute as @a[gamemode=!spectator] unless data entity @s Inventory[{Slot:0b}] run give @s minecraft:experience_bottle 1
```
- 功能:
如果玩家物品欄左邊第一格沒有任何東西就給予經驗瓶反之則不給
- 語法結構:
與「start_game.mcfunction」第三行相同,但多了一個`data`條件檢查
```mcfunction
unless data entity @s Inventory[{Slot:0b}]
```
- `unless`:如果指定的條件不成立,則執行(`run`)後面的指令
- `data entity @s`:這部分表示查詢當前執行指令的玩家(@s)的數據(物品欄)
- `Inventory[{Slot:0b}]`:這是查詢玩家物品欄中第 0 格(也就是工具列的第一格)是否有物品
- **如果該位置有物品**,則`Inventory[{Slot:0b}]`會回傳`true`(條件成立),`unless`就不會執行後面的指令
- **如果該位置沒有物品**,則`Inventory[{Slot:0b}]`會回傳`false`(條件不成立),這時候`unless`的條件成立,後面的指令會被執行(給予玩家一個經驗瓶)
#### 第二行
```mcfunction
execute if score running game_running matches 1 run function death_exp:check_level
```
- 功能:
如果遊戲進行中,執行`check_level`函數
- 語法結構:
和剛才差不多,但改成了
```mcfunction
if score running game_running matches 1
```
- `matches`:等於
### check_level.mcfunction
```mcfunction=
execute as @a[gamemode=!spectator, level=30..] run function death_exp:eliminate
execute if score admin players matches 1 run function death_exp:winner
```
#### 第一行
```mcfunction
execute as @a[gamemode=!spectator, level=30..] run function death_exp:eliminate
```
- 功能:
檢查所有非觀察者模式的玩家中,經驗等級是否大於等於30級,對符合條件的玩家執行`death_exp:eliminate`函數
- 語法結構:
與「start_game.mcfunction」第三行相同,但多了一個經驗等級檢查
#### 第二行
```mcfunction
execute if score admin players matches 1 run function death_exp:winner
```
- 功能:
如果`player`等於`1`,執行`death_exp:winner`函數
- 語法結構:
與「give_bottle.mcfunction」第二行相同
### eliminate.mcfunction
```mcfunction=
execute as @a[gamemode=!spectator, level=30..] run tellraw @a {"text":"","extra":[{"selector":"@s","color":"yellow"},{"text":" 被淘汰!","color":"red"}]}
execute as @a[gamemode=!spectator, level=30..] run scoreboard players remove admin players 1
execute as @a[gamemode=!spectator, level=30..] run gamemode spectator @s
```
#### 第一行
```mcfunction
execute as @a[gamemode=!spectator, level=30..] run tellraw @a {"text":"","extra":[{"selector":"@s","color":"yellow"},{"text":" 被淘汰!","color":"red"}]}
```
- 功能:
向所有玩家廣播有玩家被淘汰的訊息
- 語法結構:
與「check_level.mcfunction」第一行相同,比較特別的是第一行後方的`tellraw`指令
```mcfunction
tellraw @a {"text":"","extra":[{"selector":"@s","color":"yellow"},{"text":" 被淘汰!","color":"red"}]}
```
透過`extra`結構拼接文字,類似Python的`f-string`
#### 第二行
```mcfunction
execute as @a[gamemode=!spectator, level=30..] run scoreboard players remove admin players 1
```
- 功能:
讓符合條件的玩家執行後方的指令,指令的功能是將`players`減`1`
- 語法結構:
與「start_game.mcfunction」第五行相同,但增加了經驗檢查並將增加改為減少
#### 第三行
```mcfunction
execute as @a[gamemode=!spectator, level=30..] run gamemode spectator @s
```
- 功能:
讓符合條件的玩家執行後方的指令,指令的功能是將遊戲模式切為旁觀者模式
- 語法結構:
與上一行相同,但運行的指令是將玩家切換為旁觀者模式
### winner.mcfunction
```mcfunction=
execute as @a[gamemode=!spectator, limit=1] run tellraw @a {"text":"","extra":[{"selector":"@s","color":"gold"},{"text":" 獲勝!","color":"green"}]}
function death_exp:init
```
#### 第一行
```mcfunction=
execute as @a[gamemode=!spectator, limit=1] run tellraw @a {"text":"","extra":[{"selector":"@s","color":"gold"},{"text":" 獲勝!","color":"green"}]}
```
- 功能:
廣播獲勝玩家
- 語法結構:
與「eliminate.mcfunction」第一行相同
#### 第二行
```mcfunction
function death_exp:init
```
- 功能:
執行`death_exp:init`函數
## [回到主頁](https://hackmd.io/@Huanyu763/home)