Development/zh: Difference between revisions
No edit summary |
No edit summary |
||
(64 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
<languages /> | |||
<languages/> | |||
本文皆在教您如何对 DDNet | 本文皆在教您如何对 DDNet '''开发''' ,因为这是一款开源游戏(源代码公开),它依赖于一些善良的人们在空余时间的贡献。 | ||
Line 21: | Line 21: | ||
DDNet的源代码使用[https://git-scm.com/ Git]托管,这是一个版本控制系统,也是与多人协作开发的重要工具。 | DDNet的源代码使用[https://git-scm.com/ Git]托管,这是一个版本控制系统,也是与多人协作开发的重要工具。 | ||
如果您的Linux发行版中还没有git,请安装它,例如在大多数基于debian/ubuntu的发行版中,您可以打开终端,输入:<code>sudo | 如果您的Linux发行版中还没有git,请安装它,例如在大多数基于debian/ubuntu的发行版中,您可以打开终端,输入:<code>sudo apt install git</code>。 | ||
Line 29: | Line 29: | ||
源代码位于[https://github.com/ddnet/ddnet Github],您没有帐户的情况下可以通过Clone获得源代码,但如果想更改官方源代码,则需要登录账号。 | 源代码位于[https://github.com/ddnet/ddnet Github],您没有帐户的情况下可以通过Clone获得源代码,但如果想更改官方源代码,则需要登录账号。 | ||
如果您不熟悉git/github,可以在这里学习基 | 如果您不熟悉git/github,可以在这里学习基础知识: | ||
[https://docs.github.com/en/get-started/quickstart/hello-world Hello World - Github] | [https://docs.github.com/en/get-started/quickstart/hello-world Hello World - Github] | ||
<span id="Installing_the_dependencies"></span> | <span id="Installing_the_dependencies"></span> | ||
== | == 安装依赖项 == | ||
如果您在Linux上,您可以通过阅读DDNet github页面上的自述文件来安装所有需要的依赖项:https://github.com/ddnet/ddnet#dependencies- | 如果您在Linux上,您可以通过阅读DDNet github页面上的自述文件来安装所有需要的依赖项:https://github.com/ddnet/ddnet#dependencies-on-linux--macos | ||
对于Arch Linux: | 对于Arch Linux: | ||
控制台输入 | 控制台输入 | ||
<code>sudo pacman -S --needed base-devel cmake curl freetype2 git glew gmock libnotify opusfile python sdl2 sqlite wavpack</code | <code>sudo pacman -S --needed base-devel cmake curl ffmpeg freetype2 git glew glslang gmock libnotify libpng opusfile python rust sdl2 spirv-tools sqlite vulkan-headers vulkan-icd-loader wavpack x264</code> | ||
对于Debian: | |||
控制台输入 | |||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
sudo apt install build-essential cargo cmake git glslang-tools google-mock libavcodec-extra libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libcurl4-openssl-dev libfreetype6-dev libglew-dev libnotify-dev libogg-dev libopus-dev libopusfile-dev libpng-dev libsdl2-dev libsqlite3-dev libssl-dev libvulkan-dev libwavpack-dev libx264-dev | sudo apt install build-essential cargo cmake git glslang-tools google-mock libavcodec-extra libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libcurl4-openssl-dev libfreetype6-dev libglew-dev libnotify-dev libogg-dev libopus-dev libopusfile-dev libpng-dev libsdl2-dev libsqlite3-dev libssl-dev libvulkan-dev libwavpack-dev libx264-dev python3 rustc spirv-tools | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<span id="Compiling_DDNet"></span> | <span id="Compiling_DDNet"></span> | ||
== 编译DDNet == | == 编译DDNet == | ||
我们使用CMake来控制编译进程,如果你所有的依赖项 | 我们使用CMake来控制编译进程,如果你安装完成所有的依赖项,之后只需要简单输入这些命令(确保你在DDNet文件夹下): | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 69: | Line 64: | ||
<span id="General_information"></span> | <span id="General_information"></span> | ||
== | == 基本信息 == | ||
以下是一些 | 以下是一些基本信息: | ||
*目前,源代码是使用C++17标准编译的,但您会看到代码的许多部分更像C,因为只有大多数新代码使用C++17。 | *目前,源代码是使用C++17标准编译的,但您会看到代码的许多部分更像C,因为只有大多数新代码使用C++17。 | ||
*<code>std::string</code>很少使用,字符数组加<code>system.h</code>方法才是常态。 | *<code>std::string</code>很少使用,字符数组加<code>system.h</code>方法才是常态。 | ||
Line 80: | Line 75: | ||
== 源代码布局 == | == 源代码布局 == | ||
现在你可以构建DDNet | 现在你可以构建DDNet并开始编辑它了。 | ||
Line 92: | Line 87: | ||
=== src/engine 目录 === | === src/engine 目录 === | ||
游戏引擎 | 游戏引擎所在位置,它处理大多数与玩法无关的东西,比如图形、声音、网络等。 | ||
Line 98: | Line 93: | ||
=== src/game 目录 === | === src/game 目录 === | ||
所有玩 | 所有玩法的代码所在位置,分为客户端和服务器。 | ||
Line 104: | Line 99: | ||
==== 服务器端 ==== | ==== 服务器端 ==== | ||
这个游戏使用自己的面向对象的实体分级系统,所有其他实体源于主类<code>CEntity</code>,位于<code>src/game/server/e | |||
这个游戏使用自己的 | ntity.h</code>目录。 | ||
游戏世界在<code>src/game/server/gameworld.h</code>路径下,管理这些实体。 | |||
一些重要实体有: | 一些重要实体有: | ||
[https://github.com/ddnet/ddnet/blob/master/src/game/server/entities/character.h CCharacter]: 代表 | * [https://github.com/ddnet/ddnet/blob/master/src/game/server/entities/character.h CCharacter]: 代表一个活着的[[Special:MyLanguage/Common_Terminology#Tee|Tee]] , 当一个Tee生成时会被实例化,当它死亡时会被删除。 | ||
* [https://github.com/ddnet/ddnet/blob/master/src/game/server/player.h CPlayer]包含了其他没有关联[[Special:MyLanguage/Common_Terminology#Tee|Tee]]的信息(昵称、国籍等)。有关玩家在死亡之间的信息,请参阅此项。 | |||
Line 118: | Line 113: | ||
==== 客户端 ==== | ==== 客户端 ==== | ||
< | 客户端由许多组件构成,都是在<code>src/game/client/component.h</code>中定义的继承[https://github.com/ddnet/ddnet/blob/master/src/game/client/component.h CComponent]的类:这些组件通过实现视觉方法来提供功能,例如<code>OnInit</code>,<code>OnMessage</code>等等。 | ||
< | <span id="Networking"></span> | ||
==== | ==== 网络 ==== | ||
网络协议几乎由python脚本生成并输出c++代码,例如说,<code>datasrc/network.py</code>定义了所有网络包。 | |||
< | <span id="Code_conventions"></span> | ||
== | == 代码规范 == | ||
代码规范的讨论还在持续:[https://github.com/ddnet/ddnet/issues/2945 ddnet#2945] | |||
目前已经应用了下面的部分: | |||
< | <span id="Indentation_style"></span> | ||
=== | === 缩进格式 === | ||
采用[https://en.wikipedia.org/wiki/Indentation_style#Allman_style Allman 风格]。 | |||
[https://en.wikipedia.org/wiki/Indentation_style#Allman_style Allman | |||
<blockquote> | <blockquote> | ||
此风格将控制语句关联的大括号放在下一行并且缩进到相同位置,内部语句则缩进到下一级。 | |||
</blockquote> | </blockquote> | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
while(x == y) | while(x == y) | ||
Line 166: | Line 145: | ||
SomethingElse(); | SomethingElse(); | ||
} | } | ||
FinalThing(); | FinalThing(); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
< | <span id="Classes_and_Structs"></span> | ||
=== | === 类和结构体 === | ||
必须带有前缀<code>C</code>(由于历史遗留原因有一些结构体没有遵循,例如图形代码部分)或者代表接口的<code>I</code>。新的结构体需要带前缀<code>S</code>。 | |||
示例: | |||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
class CCharacter : public CEntity | class CCharacter : public CEntity | ||
Line 192: | Line 162: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
< | <span id="Enums_and_constants"></span> | ||
=== | === 枚举和常量 === | ||
应该采用大蛇式命名法[https://en.wikipedia.org/wiki/Snake_case](所有字母大写并且用下划线间隔),例如:<code>MAX_PLAYERS</code> | |||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
enum | enum | ||
Line 216: | Line 181: | ||
}; | }; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
< | <span id="Variable_naming"></span> | ||
=== | === 变量命名 === | ||
* 变量命名有三个部分:修饰和前缀、名字。 | |||
* | * 变量命名应该以大写字母开始,除非是单字符例如:<code>i</code>,<code>x</code>,<code>y</code>。 | ||
* | * 变量可以有多于一个的修饰或前缀,也可以没有。 | ||
* | |||
排列方式:<code>[修饰]_[前缀][名字]</code> | |||
< | <span id="Qualifiers"></span> | ||
==== | ==== 修饰 ==== | ||
* 成员变量<code>m</code>:<code>m_MyVariable</code>。 | |||
* <code>m</code> | * 静态变量<code>s</code>:<code>s_MyStaticVariable</code>, <code>ms_MyStaticMemberVariable</code>。 | ||
* <code>s</code> | * 带外部连接的全局变量<code>g</code>:<code>gs_MyGlobalStaticVar</code>。 | ||
* <code>g</code> | |||
< | <span id="Prefixes"></span> | ||
==== | ==== 前缀 ==== | ||
* 指针前缀<code>p</code>:<code>pMyPointer</code>,<code>m_pCharacter</code>,<code>ppMyPointerToPointer</code>。 | |||
* <code>p</code> | * 数组前缀<code>a</code>:<code>aMyArray</code>,<code>aBuf</code>。 | ||
* <code>a</code> | * 容器(<code>std::vector</code>)前缀<code>v</code>: <code>vMyVector</code>,<code>vpvMyVectorOfPointersToVectors</code>。 | ||
* <code> | * 函数前缀<code>fn</code>:<code>pfnMyCallback</code>,<code>m_papfnMyPointerToArrayOfCallbacks</code>。 | ||
* <code>fn</code> | |||
< | <span id="Common_snippets"></span> | ||
== | == 常用片段 == | ||
下面列出经常出现在代码库的代码: | |||
< | <span id="Formatting_text"></span> | ||
=== | === 格式文本 === | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
char aBuf[128]; | char aBuf[128]; | ||
str_format(aBuf, sizeof(aBuf), "number: %d", 2); | str_format(aBuf, sizeof(aBuf), "number: %d", 2); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
参阅[https://cplusplus.com/reference/cstdio/printf/ printf 文档]查看格式提示符列表。 | |||
=== | === 迭代玩家数组 === | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
for(int i = 0; i < MAX_CLIENTS; i++) | for(int i = 0; i < MAX_CLIENTS; i++) | ||
Line 290: | Line 235: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
< | <span id="Printing_to_the_game_console"></span> | ||
=== | === 输出到游戏控制台 === | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "wikiprint", "Hello from the ddnet wiki!"); | Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "wikiprint", "Hello from the ddnet wiki!"); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<span id="Debug_printing"></span> | |||
=== 调试输出 === | |||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
int i = 2; | int i = 2; | ||
dbg_msg("wikiprint", "Hello from the ddnet wiki: %d", i); | dbg_msg("wikiprint", "Hello from the ddnet wiki: %d", i); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== 在客户端翻译文本 === | |||
=== | <code>Localize</code> 用于在游戏客户端从用户选定的语言文件中获取特定字串的翻译。<syntaxhighlight lang="cpp"> | ||
<code>Localize</code> | |||
DoButton(..., Localize("Connect"), ...); | DoButton(..., Localize("Connect"), ...); | ||
</syntaxhighlight> | </syntaxhighlight>字符串可以包含格式说明符,翻译文本必须包含同样的格式说明符(这可能产生某些排序不一致的问题)。<syntaxhighlight lang="cpp"> | ||
char aBuf[128]; | char aBuf[128]; | ||
str_format(aBuf, sizeof(aBuf), Localize("%d of %d servers"), NumServers, TotalServers); | str_format(aBuf, sizeof(aBuf), Localize("%d of %d servers"), NumServers, TotalServers); | ||
</syntaxhighlight> | </syntaxhighlight>在调用<code>Localize</code>时依靠一个脚本来扫描识别调用代码,然后收集字符串上传翻译文件。由于此原因,调用<code>Localize</code> 不能包含任何其他代码,否则脚本无法正确识别文本。<syntaxhighlight lang="cpp"> | ||
// | // 请勿这样做: | ||
const char *pStr = Localize(Team == TEAM_RED ? "Red team" : "Blue team"); | const char *pStr = Localize(Team == TEAM_RED ? "Red team" : "Blue team"); | ||
// 应该这样做: | |||
// | |||
const char *pStr = Team == TEAM_RED ? Localize("Red team") : Localize("Blue team"); | const char *pStr = Team == TEAM_RED ? Localize("Red team") : Localize("Blue team"); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
< | <span id="External_resources"></span> | ||
== | == 外部资料 == | ||
* [[Special:MyLanguage/User:Ryozuki|Ryozuki]]:[https://edgarluque.com/blog/ui-code-ddnet/ UI Code in DDraceNetwork]。 | |||
* [[Special:MyLanguage/User:Ryozuki|Ryozuki]]:[https://edgarluque.com/blog/intro-to-ddnet/ An intro to the DDraceNetwork game source code]。 | |||
* [[Special:MyLanguage/User:Ryozuki|Ryozuki]]:[https://edgarluque.com/blog/code-conventions-in-ddnet/ Code conventions in DDraceNetwork]。 | |||
* [[Special:MyLanguage/User:Ryozuki|Ryozuki]]:[https://edgarluque.com/blog/chat-command-ddracenetwork/ Implementing a chat command in DDraceNetwork]。 | |||
* [https://codedoc.ddnet.org/ Auto generated docs]。 | |||
* [https://ddnet.org/libtw2-doc/ Technical documentation of Teeworlds file formats and network protocol]。 | |||
* [https://heinrich5991.github.io/blog/blog/one-tick-unfreeze The Anatomy of a One Tick Unfreeze]。 | |||
* [[User:ChillerDragon|ChillerDragon]]:[https://www.youtube.com/playlist?list=PLhJkqAQmOh5LyYOfnMy4PJB6CSZltQyTc Teeworlds programming YouTube tutorial]。 | |||
* [[User:ChillerDragon|ChillerDragon]]:[https://chillerdragon.github.io/teeworlds-protocol/ Teeworlds 0.6/0.7 network protocol documentation] | |||
<span id="About_Tee_Skin_Rendering"></span> | |||
== 关于提交皮肤 == | |||
此部分介绍如何提交皮肤。 | |||
由 Patiga 提供的各种参数值 | |||
特别鸣谢 Jupstar | |||
各部分缩放比例: | |||
身体-body: 100% | |||
* | 脚脚-feet: 150% | ||
* | 眼睛-eyes: 120% | ||
眨眼-eye blink: 45% | |||
* | 手手-hand: 93.75% | ||
位置: | |||
64/64 = 1 = 身体部分的宽高比 | |||
下面给出各部分与边缘距离占总宽或者高的比值 | |||
身体-body: 4/64 上边缘 | |||
脚脚-feet: | |||
10/64 下边缘 | |||
7/64 左右边缘 | |||
眼睛初始位置: | |||
0.125 上边缘 | |||
0.05 左右边缘 | |||
眼动范围-eye movement: | |||
设 dir = 眼睛角度 (辅助线角度), right = 0 | |||
眼睛偏移坐标: | |||
x: cos(dir) * 0.125 | |||
y: sin(dir) * 0.1 | |||
眼间距: | |||
x: abs(cos(dir)) * 0.01 |
Latest revision as of 08:19, 23 May 2024
本文皆在教您如何對 DDNet 開發 ,因為這是一款開源遊戲(原始碼公開),它依賴於一些善良的人們在空餘時間的貢獻。
開發環境
截至目前,基於以下原因,我們強烈推薦使用Linux系統進行DDNet開發:
- 大多數DDNet貢獻者使用Linux,使用Linux與之前的開發者交流起來更加方便。
- 軟體包管理更簡單,您可以輕鬆地安裝所有需要的庫。
- 本文專注於Linux,還沒有涉及Windows。
首先,DDNet由 C++ 語言編寫,開發者需要對它相當熟悉,但您也可以在只有基礎知識的情況下慢慢學習深入。
學習C++的一些有用資源:
- learncpp.com
- cppreference.com
- 瀏覽器搜素引擎。
DDNet的原始碼使用Git託管,這是一個版本控制系統,也是與多人協作開發的重要工具。
如果您的Linux發行版中還沒有git,請安裝它,例如在大多數基於debian/ubuntu的發行版中,您可以打開終端,輸入:sudo apt install git
。
獲取原始碼
原始碼位於Github,您沒有帳戶的情況下可以通過Clone獲得原始碼,但如果想更改官方原始碼,則需要登錄帳號。
如果您不熟悉git/github,可以在這裡學習基礎知識: Hello World - Github
安裝依賴項
如果您在Linux上,您可以通過閱讀DDNet github頁面上的自述文件來安裝所有需要的依賴項:https://github.com/ddnet/ddnet#dependencies-on-linux--macos
對於Arch Linux:
控制台輸入
sudo pacman -S --needed base-devel cmake curl ffmpeg freetype2 git glew glslang gmock libnotify libpng opusfile python rust sdl2 spirv-tools sqlite vulkan-headers vulkan-icd-loader wavpack x264
對於Debian:
控制台輸入
sudo apt install build-essential cargo cmake git glslang-tools google-mock libavcodec-extra libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libcurl4-openssl-dev libfreetype6-dev libglew-dev libnotify-dev libogg-dev libopus-dev libopusfile-dev libpng-dev libsdl2-dev libsqlite3-dev libssl-dev libvulkan-dev libwavpack-dev libx264-dev python3 rustc spirv-tools
編譯DDNet
我們使用CMake來控制編譯進程,如果你安裝完成所有的依賴項,之後只需要簡單輸入這些命令(確保你在DDNet文件夾下):
mkdir build
cd build
cmake ..
make -j$(nproc)
基本信息
以下是一些基本信息:
- 目前,原始碼是使用C++17標準編譯的,但您會看到代碼的許多部分更像C,因為只有大多數新代碼使用C++17。
std::string
很少使用,字符數組加system.h
方法才是常態。- 大多數輸入輸出代碼、格式化和Print都是使用
system.h
提供的方法完成的。
原始碼布局
現在你可以構建DDNet並開始編輯它了。
src/base 目錄
由於DDNet是一個跨平台遊戲,需要一個抽象層來簡化開發,因此該目錄包含許多有用的函數來處理這一問題。
src/engine 目錄
遊戲引擎所在位置,它處理大多數與玩法無關的東西,比如圖形、聲音、網絡等。
src/game 目錄
所有玩法的代碼所在位置,分為客戶端和伺服器。
伺服器端
這個遊戲使用自己的面向對象的實體分級系統,所有其他實體源於主類CEntity
,位於src/game/server/e
ntity.h
目錄。
遊戲世界在src/game/server/gameworld.h
路徑下,管理這些實體。
一些重要實體有:
- CCharacter: 代表一個活著的Tee , 當一個Tee生成時會被實例化,當它死亡時會被刪除。
- CPlayer包含了其他沒有關聯Tee的信息(暱稱、國籍等)。有關玩家在死亡之間的信息,請參閱此項。
客戶端
客戶端由許多組件構成,都是在src/game/client/component.h
中定義的繼承CComponent的類:這些組件通過實現視覺方法來提供功能,例如OnInit
,OnMessage
等等。
網絡
網絡協議幾乎由python腳本生成並輸出c++代碼,例如說,datasrc/network.py
定義了所有網絡包。
代碼規範
代碼規範的討論還在持續:ddnet#2945
目前已經應用了下面的部分:
縮進格式
採用Allman 風格。
此風格將控制語句關聯的大括號放在下一行並且縮進到相同位置,內部語句則縮進到下一級。
while(x == y)
{
Something();
SomethingElse();
}
FinalThing();
類和結構體
必須帶有前綴C
(由於歷史遺留原因有一些結構體沒有遵循,例如圖形代碼部分)或者代表接口的I
。新的結構體需要帶前綴S
。
示例:
class CCharacter : public CEntity
{
// ...
}
枚舉和常量
應該採用大蛇式命名法[1](所有字母大寫並且用下劃線間隔),例如:MAX_PLAYERS
enum
{
FAKETUNE_FREEZE = 1,
FAKETUNE_SOLO = 2,
FAKETUNE_NOJUMP = 4,
FAKETUNE_NOCOLL = 8,
FAKETUNE_NOHOOK = 16,
FAKETUNE_JETPACK = 32,
FAKETUNE_NOHAMMER = 64,
};
變量命名
- 變量命名有三個部分:修飾和前綴、名字。
- 變量命名應該以大寫字母開始,除非是單字符例如:
i
,x
,y
。 - 變量可以有多於一個的修飾或前綴,也可以沒有。
排列方式:[修饰]_[前缀][名字]
修飾
- 成員變量
m
:m_MyVariable
。 - 靜態變量
s
:s_MyStaticVariable
,ms_MyStaticMemberVariable
。 - 帶外部連接的全局變量
g
:gs_MyGlobalStaticVar
。
前綴
- 指針前綴
p
:pMyPointer
,m_pCharacter
,ppMyPointerToPointer
。 - 數組前綴
a
:aMyArray
,aBuf
。 - 容器(
std::vector
)前綴v
:vMyVector
,vpvMyVectorOfPointersToVectors
。 - 函數前綴
fn
:pfnMyCallback
,m_papfnMyPointerToArrayOfCallbacks
。
常用片段
下面列出經常出現在代碼庫的代碼:
格式文本
char aBuf[128];
str_format(aBuf, sizeof(aBuf), "number: %d", 2);
參閱printf 文檔查看格式提示符列表。
迭代玩家數組
for(int i = 0; i < MAX_CLIENTS; i++)
{
// Server-side
CPlayer *pPlayer = GameServer()->m_apPlayers[i];
}
輸出到遊戲控制台
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "wikiprint", "Hello from the ddnet wiki!");
調試輸出
int i = 2;
dbg_msg("wikiprint", "Hello from the ddnet wiki: %d", i);
在客戶端翻譯文本
Localize
用於在遊戲客戶端從用戶選定的語言文件中獲取特定字串的翻譯。
DoButton(..., Localize("Connect"), ...);
字符串可以包含格式說明符,翻譯文本必須包含同樣的格式說明符(這可能產生某些排序不一致的問題)。
char aBuf[128];
str_format(aBuf, sizeof(aBuf), Localize("%d of %d servers"), NumServers, TotalServers);
在調用Localize
時依靠一個腳本來掃描識別調用代碼,然後收集字符串上傳翻譯文件。由於此原因,調用Localize
不能包含任何其他代碼,否則腳本無法正確識別文本。
// 请勿这样做:
const char *pStr = Localize(Team == TEAM_RED ? "Red team" : "Blue team");
// 应该这样做:
const char *pStr = Team == TEAM_RED ? Localize("Red team") : Localize("Blue team");
外部資料
- Ryozuki:UI Code in DDraceNetwork。
- Ryozuki:An intro to the DDraceNetwork game source code。
- Ryozuki:Code conventions in DDraceNetwork。
- Ryozuki:Implementing a chat command in DDraceNetwork。
- Auto generated docs。
- Technical documentation of Teeworlds file formats and network protocol。
- The Anatomy of a One Tick Unfreeze。
- ChillerDragon:Teeworlds programming YouTube tutorial。
- ChillerDragon:Teeworlds 0.6/0.7 network protocol documentation
關於提交皮膚
此部分介紹如何提交皮膚。
由 Patiga 提供的各种参数值 特别鸣谢 Jupstar 各部分缩放比例: 身体-body: 100% 脚脚-feet: 150% 眼睛-eyes: 120% 眨眼-eye blink: 45% 手手-hand: 93.75% 位置: 64/64 = 1 = 身体部分的宽高比 下面给出各部分与边缘距离占总宽或者高的比值 身体-body: 4/64 上边缘 脚脚-feet: 10/64 下边缘 7/64 左右边缘 眼睛初始位置: 0.125 上边缘 0.05 左右边缘 眼动范围-eye movement: 设 dir = 眼睛角度 (辅助线角度), right = 0 眼睛偏移坐标: x: cos(dir) * 0.125 y: sin(dir) * 0.1 眼间距: x: abs(cos(dir)) * 0.01