Skip to content

Commit 10fb751

Browse files
authored
Merge pull request #111 from zhangshuyx/main
commit translation of Macroquad_game on android
2 parents 63e9764 + 00ce10a commit 10fb751

File tree

4 files changed

+384
-0
lines changed

4 files changed

+384
-0
lines changed

src/chapter_7/Macroquad_game.md

Lines changed: 384 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,384 @@
1+
# 使用Macroquad在Android设备上发布游戏
2+
<img src="../image/Macroquad_game_1.png" width = "550" alt="Macroquad_game_1" align=center />
3+
4+
**译者注:** macroquad是一个简单易用的Rust游戏库。macroquad尝试避免任何Rust特定概念比如生命周期/借用,这使得它对初学者非常友好。
5+
6+
详见https://docs.rs/macroquad/0.3.7/macroquad/index.html
7+
8+
# 1. 简介
9+
10+
这篇教程基于在Google Play商店发布的 [Zemeroth](https://github.com/ozkriff/zemeroth)游戏开发发布过程。目前这款游戏已经公开测试,点击[这里](https://play.google.com/store/apps/details?id=rust.zemeroth)可以试玩!
11+
12+
本篇主题包括:
13+
14+
- 构建一个适用于android设备的macroquad游戏
15+
- 常见问题和调试技巧
16+
- 构建并上传APK包到Google Play商店
17+
18+
# 2.搭建开发环境
19+
20+
## 使用docker配置环境并构建APK包
21+
22+
在已经拉取所有NDK(Native Development Kit原生开发工具包)依赖的docker宿主机上构建开发环境非常简单,
23+
24+
```shell
25+
docker pull not-fl3/cargo-apk
26+
```
27+
28+
推荐大家使用docker来构建适用于android设备的macroquad游戏。
29+
30+
### 基于docker构建APK包
31+
32+
只需一条命令即可完成构建APK包
33+
34+
```shell
35+
docker run
36+
--rm
37+
-v $(pwd):/root/src
38+
-w /root/src
39+
notfl3/cargo-apk cargo quad-apk build --release
40+
```
41+
42+
上面的命令会生成APK包到 `target/android-artifacts/release/apk`
43+
44+
这一步骤可能会耗费较长时间,因为每次docker调用都会完整构建三个android目标文件。
45+
46+
docker命令中加入`-v /tmp/registry\":/usr/local/cargo/registry\"`会使得构建过程稍微快一些。这样做会使docker将宿主机的 `/tmp/registry`目录作为缓存目录注册到cargo,然后docker就无需在每次构建时都重新下载依赖。
47+
48+
另一种方法:运行docker交互模式,在同一个容器中完成多次构建。
49+
50+
```
51+
docker run
52+
--rm
53+
-v $(pwd):/root/src
54+
-w /root/src
55+
-it notfl3/cargo-apk /bin/bash
56+
```
57+
58+
最后,在docker的shell中运行`cargo quad-apk build --release`
59+
60+
## 手工配置环境并构建APK包
61+
62+
docker简化了安装android-sdk和android-ndk的过程。不过,有些时候使用原生构建流程可能会更方便。这里我们不太不推荐这样的构建方式,不过我们可以通过这个构建流程来阐述容器中是如何完成这个过程的。
63+
64+
### 环境配置
65+
66+
命令及路径写法取决于宿主机操作系统,我们这里使用的linux,其他操作系统下也是相同思路。
67+
68+
- 安装JRE或者JDK
69+
70+
这一步骤不同的操作系统差别会很大,这里以ubuntu为例:
71+
72+
```
73+
sudo apt-get install openjdk-8-jdk
74+
```
75+
76+
- 安装Rust android
77+
78+
利用rustup安装android相关库:
79+
80+
```
81+
rustup target add armv7-linux-androideabi
82+
rustup target add aarch64-linux-android
83+
rustup target add i686-linux-android
84+
rustup target add x86_64-linux-android
85+
```
86+
87+
- 安装Android SDK
88+
89+
```
90+
# 创建目录存放所有前置安装内容
91+
mkdir /this/may/be/any/path/android
92+
93+
cd android
94+
wget -q https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip
95+
unzip -q sdk-tools-linux-4333796.zip
96+
rm sdk-tools-linux-4333796.zip
97+
tools/bind/sdkmanager "platform-tools"
98+
tools/bin/sdkmanager "platforms;android-29"
99+
tools/bin/sdkmanager "build-tools;29.0.0"
100+
tools/bin/sdkmanager --update
101+
```
102+
103+
- 安装Android NDK
104+
105+
```
106+
# 到前一步android-sdk的目录
107+
cd /path/from/previous/step/android
108+
109+
wget -q http://dl.google.com/android/repository/android-ndk-r20-linux-x86_64.zip
110+
unzip -q android-ndk-r20-linux-x86_64.zip
111+
rm android-ndk-r20-linux-x86_64.zip
112+
```
113+
114+
- 安装Cargo APK
115+
116+
安装`cargo-quad-apk`cargo扩展。
117+
118+
```
119+
cargo install cargo-quad-apk
120+
```
121+
122+
### 手工构建APK包
123+
124+
```
125+
export ANDROID_HOME=/path/from/previous/step/android
126+
export NDK_HOME=/path/from/previous/step/android/android-ndk-r20
127+
128+
# 构建debug版本
129+
cargo quad-apk build
130+
# 构建release版本
131+
cargo quad-apk build --release
132+
```
133+
134+
构建完成的apk文件在 `target/android-artifacts/debug/apk``target/android-artifacts/release/apk`下。
135+
136+
# 3. 调试android游戏
137+
138+
## 资源目录
139+
140+
假设目录结构如下:
141+
142+
```
143+
.
144+
├── assets
145+
├── └── nice_texture.png
146+
├── src
147+
├── └── main.rs
148+
└── Cargo.toml
149+
```
150+
151+
加入如下内容到你的Cargo.toml以引入资源目录到APK:
152+
153+
```ini
154+
[package.metadata.android]
155+
assets = "assets/"
156+
```
157+
158+
之后通过`load_texture("nice_texture.png")`来加载纹理贴图。
159+
160+
不过,在PC中通常使用`load_texture("assets/nice_texture.png")`,需包含assets到路径中。
161+
162+
为修复这个问题使得android和PC中使用的路径统一,我们需要借助 [set_pc_assets_folder](https://docs.rs/macroquad/0.3.6/macroquad/file/fn.set_pc_assets_folder.html)来解决。
163+
164+
```
165+
macroquad::file::set_pc_assets_folder("assets");
166+
```
167+
168+
这样我们就可以在不同的平台使用统一的`load_texture("nice_texture.png")`来加载纹理贴图了。
169+
170+
## 高DPI适配
171+
172+
<img src="../image/Macroquad_game_2.png" width = "340" alt="Macroquad_game_2" align=center />
173+
174+
*[图片来源](https://developer.android.com/training/multiscreen/screendensities)*
175+
176+
不同android设备具有明显的像素密度差异。默认情况下,android操作系统会尝试用高像素密度来模拟低像素密度显示效果。
177+
178+
这意味着`screen_width()/screen_height()`得到的值低于实际的屏幕像素分辨率,不过之后android操作系统会自动缩放viewport来适配设备屏幕。
179+
180+
这样也许没问题,因为更小的viewport能够获得更高的FPS,如果我们不想让android操作系统自动缩放的话,我们需要告知android操作系统以支持高DPI屏幕。
181+
182+
```rust
183+
fn window_conf() -> window::Conf {
184+
window::Conf {
185+
window_title: "Zemeroth".to_owned(),
186+
high_dpi: true,
187+
..Default::default()
188+
}
189+
}
190+
191+
#[macroquad::main(window_conf)]
192+
async fn main() {
193+
}
194+
```
195+
196+
## 屏幕方向
197+
198+
默认情况下,Macroquad游戏是全屏幕的并且允许任何屏幕方向,我们可以在Cargo.toml文件中加入以下内容来限制支持的屏幕方向:
199+
200+
```ini
201+
[package.metadata.android.activity_attributes]
202+
"android:screenOrientation" = "userLandscape"
203+
```
204+
205+
## 图标
206+
207+
208+
209+
![icon](../image/Macroquad_game_3.jpg)
210+
211+
应用图标在APK内被视为一种特殊资源,我们将res目录加入APK:
212+
213+
```ini
214+
[package.metadata.android]
215+
res = "android_res"
216+
icon = "@mipmap/ic_launcher"
217+
```
218+
219+
不同DPI的图标目录类似下面这样:
220+
221+
```
222+
android_res/
223+
├── mipmap-hdpi
224+
│ └── ic_launcher.png
225+
├── mipmap-mdpi
226+
│ └── ic_launcher.png
227+
├── mipmap-xhdpi
228+
│ └── ic_launcher.png
229+
├── mipmap-xxhdpi
230+
│ └── ic_launcher.png
231+
└── mipmap-xxxhdpi
232+
└── ic_launcher.png
233+
```
234+
235+
不同尺寸的图标需要手工生成。[这里](http://romannurik.github.io/AndroidAssetStudio/icons-launcher.html)提供了一种较为好用的方法。
236+
237+
## 日志调试
238+
239+
macroquad的所有`warn!`/`info!`/`debug!` 消息都会合并到android系统消息。我们可以通过 `adb logcat` 命令来访问,下面是几种过滤 `adb logcat` 的方法。
240+
241+
### 通过tag来过滤 `adb logcat`
242+
243+
tag过滤针对的是macroquad产生的 `warn!`/`info!`/`debug!`消息。
244+
245+
```
246+
adb logcat -v brief SAPP:V "*:S"
247+
```
248+
249+
`-v brief` 会通过隐藏一些log元数据来优化显示结果;
250+
251+
之后的参数是过滤器参数;
252+
253+
SAPP:V - V(verbose)过滤器会应用到tag为SAPP的消息,这些消息都将被输出。*:S - S(silent)过滤器会应用到所有其他tag,这些消息都将被过滤掉。
254+
255+
### 通过PID过滤
256+
257+
一些应用在运行时会产生额外的系统消息,可能是系统警告或者未处理的原生库异常。但是这些消息在应用tag过滤时都将被过滤掉。
258+
259+
PID是进程ID,使用PID过滤可以获得包括任何tag在内的所有应用输出消息。
260+
261+
```
262+
# Find out PID
263+
> adb shell pidof -s rust.CRATENAME
264+
30243
265+
# Get all the messages from a given PID
266+
>adb shell pidof -s 30243
267+
```
268+
269+
以上的命令可以通过命令参数的形式简写如下:
270+
271+
```
272+
adb logcat --pid=$(adb shell pidof -s rust.CRATENAME)
273+
```
274+
275+
# 4. APK签名
276+
277+
默认情况下,`cargo quad-apk`生成调试kestore文件并使用调试key来签名APK。这样的APK包可以在本地安装测试,但是不能上传至Google Play应用商店。
278+
279+
Google Play应用商店要求非调试kestore文件,这个文件将被上传到Play Console来验证开发者身份。
280+
281+
我们需要用`keytool` 来生成key,`keytool` 包含在`openjdk`中。然后使用 `apksigner`给APK签名, `apksigner`内置在Android SDK中。
282+
283+
```
284+
keytool -v -genkey -keystore mygame.keystore -alias mygame -keyalg RSA -validity 10000
285+
```
286+
287+
现在所有的前置环节都已完成,这一步生成的key可以用于构建release包。
288+
289+
首先,我们使用参数通知`cargo-apk`停止使用调试keystore文件来签名APK,
290+
291+
`cargo quad-apk build --release --nosign`
292+
293+
然后再使用非调试keystore文件来签名APK。
294+
295+
```
296+
apksigner sign --ks mygame.keystore my-app.apk --ks-key-alias alias_name
297+
```
298+
299+
最后使用下面的命令进行验证:
300+
301+
```
302+
apksigner verify my-app.apk
303+
```
304+
305+
[点此查看APK签名官方文档](https://developer.android.com/studio/publish/app-signing.html#signing-manually)
306+
307+
## 提示:如何在docker中获取`keytool`/`apksigner`
308+
309+
假设android keystore文件在~/.android目录,并且待签名的.apk文件在当前工作目录:
310+
311+
```
312+
docker run --rm
313+
-v (pwd):/root/src
314+
-v(/home/USER/.android):/root/.android_secrets
315+
-w /root/src -it notfl3/cargo-apk /bin/bash
316+
```
317+
318+
这条命令会启动docker容器,并挂载当前工作目录到容器中`/root/src` ,挂载.android到容器中`/root/.android_secrets` ,然后在容器中使用下面的命令来签名APK:
319+
320+
```
321+
apksigner sign --ks my.keystore my-app.apk --ks-key-alias alias_name
322+
```
323+
324+
## Android目标设备
325+
326+
默认情况下,`cargo quad-apk` 会构建适用于三个不同平台的APK包。为满足Google Play应用商店要求,我们需要添加所有平台如下:
327+
328+
```ini
329+
[package.metadata.android]
330+
..
331+
build_targets = [ "armv7-linux-androideabi", "aarch64-linux-android", "i686-linux-android", "x86_64-linux-android" ]
332+
```
333+
334+
在调试期间为加快构建过程我们可以选择我们的测试设备在用的其中任一个平台。
335+
336+
```ini
337+
[package.metadata.android]
338+
..
339+
build_targets = [ "armv7-linux-androideabi" ]
340+
```
341+
342+
## Google Play版本管理
343+
344+
Google Play应用商店对上传的APK包有它自己的版本管理机制,每个APK都必须有独一无二的`version_code`。否则google开发者控制台会报错:`Version code 1 has already been used. Try another version code.`
345+
346+
在Cargo.toml中设置app版本号`version_code`
347+
348+
```ini
349+
[package.metadata.android]
350+
..
351+
version_code = 2
352+
version_name = "Version Name"
353+
```
354+
355+
[点此查看APK版本管理官方文档](https://developer.android.com/studio/publish/versioning)
356+
357+
## 商店APP预览页面
358+
359+
为了提交游戏到Google Play应用商店用于审核及开放测试、正式发布,我们需要上传用于APP展示页面的游戏截图、描述信息等内容。APP上传过程中很多数据都被标记为必填(*),这里我们至少需要上传下面几种游戏图像:
360+
361+
- 512x512 图标
362+
- 1024x500 banner图
363+
- 两个16:9截图
364+
365+
[关于预览页面的其他信息](https://developer.android.com/studio/publish/versioning)
366+
367+
## 内部测试、开放测试和正式发布
368+
369+
**内部测试、封闭测试和开放测试区别是什么?你可以在发布正式产品之前发布各种测试版本用于测试验证。**
370+
371+
**内部测试:**创建内部测试版本以快速分发至最多100测试用户,进行早期质量保证测试。
372+
373+
不需要搭建商店页面也不需要应用审核。用于帮助开发者确保签名过程有效、应用成功上传至商店。也允许通过邮件方式添加测试用户。
374+
375+
**封闭测试:**分发预发布版本至更大范围的测试用户用于收集更多反馈意见。
376+
377+
接近于开放测试,但是要求添加测试用户邮箱。
378+
379+
**开放测试:**创建开放测试版本可以将你的APP展示到Google Play应用商店进行大规模测试。这种情况下,任何人都可以加入你的测试并提交自己的反馈意见。
380+
381+
接近于正式发布状态,商店页面公开可用,测试用户无需其他额外步骤即可安装使用。
382+
383+
[关于测试发布流程的其他信息](https://support.google.com/googleplay/android-developer/answer/9845334?hl=en)
384+

src/image/Macroquad_game_1.png

156 KB
Loading

src/image/Macroquad_game_2.png

50.4 KB
Loading

src/image/Macroquad_game_3.jpg

4.49 KB
Loading

0 commit comments

Comments
 (0)