蚊章汇 - 2020年1月
type: channel
link: https://linuxcn.bwsl.wang/2020/01/
description: Linux中国社区镜像站，没有大保镖。
items: Ubuntu 中的 root 用户：你应该知道的重要事情
items: 开始使用开源待办事项清单管理器
items: 用于联系人管理的三个开源工具
items: 免费电子书《Linux 进程间通信指南》介绍
items: 我的 Linux 故事：在 90 年代学习 Linux
items: 使用公钥/私钥对设定免密的 Linux 登录方式
items: 在你的 Python 平台类游戏中放一些奖励
items: Wine 5.0 发布了！
items: C 还是 Rust：选择哪个用于硬件抽象编程
items: 为什么每个人都在谈论 WebAssembly

Ubuntu 中的 root 用户：你应该知道的重要事情
type: item
date: 2020-01-31T21:05:49+08:00
description: 当你刚开始使用 Linux 时，你将发现与 Windows 的很多不同。其中一个“不同的东西”是 root 用户的概念。在这个初学者系列中，我将解释几个关于 Ubuntu 的 root 用户的重要的东西。请记住，尽管我正在从 Ubuntu 用户的角度编写这篇文章，它应该对大多数的 Linux 发行版也是有效的。你将在这篇文章中学到下面的内容：为什么在 Ubuntu 中禁用 root 用户像 root 用户一样使用命切换为 root 用户解锁 root 用户什么是 root 用户？为什么它在 Ubuntu 中被锁定？在 Linux 中，有一个称为 root 的超级用户。这是超级管理员账号，它可以做任何事以及使用系统的一切东西。它可以在你的 Linux 系统上访问任何文件和运行任何命令。能力越大，责任越大。root 用户给予你完全控制系统的能力，因此，它应该被谨慎地使用。root 用户可以访问系统文件，运行更改系统配置的命令。因此，一个错误的命令可能会破坏系统。这就是为什么 Ubuntu 和其它基于 Ubuntu 的发行版默认锁定 root 用户，以从意外的灾难中挽救你的原因。对于你的日常任务，像移动你家目录中的文件，从互联网下载文件，创建文档等等，你不需要拥有 root 权限。打个比方来更好地理解它。假设你想要切一个水果，你可以使用一把厨房用刀。假设你想要砍一颗树，你就得使用一把锯子。现在，你可以使用锯子来切水果，但是那不明智，不是吗？\_这意味着，你不能是 Ubuntu 中 root 用户或者不能使用 root 权限来使用系统吗？不，你仍然可以在 sudo 的帮助下来拥有 root 权限来访问(在下一节中解释)。要点： 使用于常规任务，root 用户权限太过强大。这就是为什么不建议一直使用 root 用户。你仍然可以使用 root 用户来运行特殊的命令。如何在 Ubuntu 中像 root 用户一样运行命令？对于一些系统的特殊任务来说，你将需要 root 权限。例如。如果你想通过命令行更新 Ubuntu，你不能作为一个常规用户运行该命令。它将给出权限被拒绝的错误。apt update Reading package lists... Done E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied) E: Unable to lock directory /var/lib/apt/lists/ W: Problem unlinking the file /var/cache/apt/pkgcache.bin - RemoveCaches (13: Permission denied) W: Problem unlinking the file /var/cache/apt/srcpkgcache.bin - RemoveCaches (13: Permission denied)那么，你如何像 root 用户一样运行命令？简单的答案是，在命令前添加 sudo，来像 root 用户一样运行。sudo apt updateUbuntu 和很多其它的 Linux 发行版使用一个被称为 sudo 的特殊程序机制。sudo 是一个以 root 用户（或其它用户）来控制运行命令访问的程序。实际上，sudo 是一个非常多用途的工具。它可以配置为允许一个用户像 root 用户一样来运行所有的命令，或者仅仅一些命令。你也可以配置为无需密码即可使用 sudo 运行命令。这个主题内容比较丰富，也许我将在另一篇文章中详细讨论它。就目前而言，你应该知道当你安装 Ubuntu 时，你必须创建一个用户账号。这个用户账号在你系统上以管理员身份来工作，并且按照 Ubuntu 中的默认 sudo 策略，它可以在你的系统上使用 root 用户权限来运行任何命令。sudo 的问题是，运行 sudo 不需要 root 用户密码，而是需要用户自己的密码。并且这就是为什么当你使用 sudo 运行一个命令，会要求输入正在运行 sudo 命令的用户的密码的原因：[email protected]:~$ sudo apt update [sudo] password for abhishek:正如你在上面示例中所见 abhishek 在尝试使用 sudo 来运行 apt update 命令，系统要求输入 abhishek 的密码。如果你对 Linux 完全不熟悉，当你在终端中开始输入密码时，你可能会惊讶，在屏幕上什么都没有发生。这是十分正常的，因为作为默认的安全功能，在屏幕上什么都不会显示。甚至星号（*）都没有。输入你的密码并按回车键。要点：为在 Ubuntu 中像 ro…

开始使用开源待办事项清单管理器
type: item
date: 2020-01-31T19:11:22+08:00
description: 待办事项清单是跟踪任务列表的强大方法。在我们的 20 个使用开源提升生产力的系列的第七篇文章中了解如何使用它。去年，我在 19 天里给你介绍了 19 个新（对你而言）的生产力工具。今年，我换了一种方式：使用你在使用或者还没使用的工具，构建一个使你可以在新一年更加高效的环境。使用 todo 跟踪任务任务管理和待办事项清单是我非常喜欢0的东西。我是一位生产效率的狂热粉丝（以至于我为此做了一个播客），我尝试了各种不同的应用。我甚至为此做了演讲并写了些文章。因此，当我谈到提高工作效率时，肯定会出现任务管理和待办事项清单工具。说实话，由于简单、跨平台且易于同步，用 todo.txt 肯定不会错。它是我不断反复提到的两个待办事项清单以及任务管理应用之一（另一个是 Org 模式）。让我反复使用它的原因是它简单、可移植、易于理解，并且有许多很好的附加组件，并且当一台机器有附加组件，而另一台没有，也不会破坏它。由于它是一个 Bash shell 脚本，我还没发现一个无法支持它的系统。设置 todo.txt首先，你需要安装基本 shell 脚本并将默认配置文件复制到 ~/.todo 目录：git clone https://github.com/todotxt/todo.txt-cli.git cd todo.txt-cli make sudo make install mkdir ~/.todo cp todo.cfg ~/.todo/config接下来，设置配置文件。一般，我想取消对颜色设置的注释，但必须马上设置的是 TODO_DIR 变量：export TODO_DIR="$HOME/.todo"添加待办事件要添加第一个待办事件，只需输入 todo.sh add <NewTodo> 就能添加。这还将在 $HOME/.todo/ 中创建三个文件：todo.txt、done.txt 和 reports.txt。添加几个项目后，运行 todo.sh ls 查看你的待办事项。管理任务你可以通过给项目设置优先级来稍微改善它。要向项目添加优先级，运行 todo.sh pri # A。数字是列表中任务的数量，而字母 A 是优先级。你可以将优先级设置为从 A 到 Z，因为这是它的排序方式。要完成任务，运行 todo.sh do # 来标记项目已完成并将它移动到 done.txt。运行 todo.sh report 会向 report.txt 写入已完成和未完成项的数量。所有这三个文件的格式都有详细的说明，因此你可以使用你的文本编辑器修改。todo.txt 的基本格式是：(Priority) YYYY-MM-DD Task该日期表示任务的到期日期（如果已设置）。手动编辑文件时，只需在任务前面加一个 x 来标记为已完成。运行 todo.sh archive 会将这些项目移动到 done.txt，你可以编辑该文本文件，并在有时间时将已完成的项目归档。设置重复任务我有很多重复的任务，我需要以每天/周/月来计划。这就是 todo.txt 的灵活性所在。通过在 ~/.todo.actions.d/ 中使用附加组件，你可以添加命令并扩展基本 todo.sh 的功能。附加组件基本上是实现特定命令的脚本。对于重复执行的任务，插件 ice\_recur 应该符合要求。按照其页面上的说明操作，你可以设置任务以非常灵活的方式重复执行。在该附加组件目录中有很多附加组件，包括同步到某些云服务，也有链接到桌面或移动端应用的组件，这样你可以随时看到待办列表。我只是简单介绍了这个代办事项清单功能，请花点时间深入了解这个工具的强大！它确实可以帮助我每天完成任务。via: https://opensource.com/article/20/1/open-source-to-do-list作者：Kevin Sonney 选题：lujun9972 译者：geekpi 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出

用于联系人管理的三个开源工具
type: item
date: 2020-01-31T03:48:39+08:00
description: 通过将联系人同步到本地从而更快访问它。在我们的 20 个使用开源提升生产力的系列的第六篇文章中了解该如何做。去年，我在 19 天里给你介绍了 19 个新（对你而言）的生产力工具。今年，我换了一种方式：使用你在使用或者还没使用的工具，构建一个使你可以在新一年更加高效的环境。用于联系人管理的开源工具在本系列之前的文章中，我解释了如何在本地同步你的邮件和日历。希望这些加速了你访问邮件和日历。现在，我将讨论联系人同步，你可以给他们发送邮件和日历邀请。我目前收集了很多邮件地址。管理这些数据可能有点麻烦。有基于 Web 的服务，但它们不如本地副本快。几天前，我谈到了用于管理日历的 vdirsyncer。vdirsyncer 还使用 CardDAV 协议处理联系人。vdirsyncer 除了可以使用文件系统存储日历外，还支持通过 google\_contacts 和 carddav 进行联系人同步，但 fileext 设置会被更改，因此你无法在日历文件中存储联系人。我在配置文件添加了一块配置，并从 Google 镜像了我的联系人。设置它需要额外的步骤。从 Google 镜像完成后，配置非常简单：[pair address_sync] a = "googlecard" b = "localcard" collections = ["from a", "from b"] conflict_resolution = "a wins" [storage googlecard] type = "google_contacts" token_file = "~/.vdirsyncer/google_token" client_id = "my_client_id" client_secret = "my_client_secret" [storage localcard] type = "filesystem" path = "~/.calendars/Addresses/" fileext = ".vcf"现在，当我运行 vdirsyncer discover 时，它会找到我的 Google 联系人，并且 vdirsyncer sync 将它们复制到我的本地计算机。但同样，这只进行到一半。现在我想查看和使用联系人。需要 khard 和 abook。为什么选择两个应用？因为每个都有它自己的使用场景，在这里，越多越好。khard 用于管理地址，类似于 khal 用于管理日历条目。如果你的发行版附带了旧版本，你可能需要通过 pip 安装最新版本。安装 khard 后，你需要创建 ~/.config/khard/khard.conf，因为 khard 没有与 khal 那样漂亮的配置向导。我的看起来像这样：[addressbooks] addresses path = ~/.calendars/Addresses/default/ [general] debug = no default_action = list editor = vim, -i, NONE merge_editor = vimdiff [contact table] display = first_name group_by_addressbook = no reverse = no show_nicknames = yes show_uids = no sort = last_name localize_dates = yes [vcard] preferred_version = 3.0 search_in_source_files = yes skip_unparsable = no这会定义源通讯簿（并给它一个友好的名称）、显示内容和联系人编辑程序。运行 khard list 将列出所有条目，khard list <some@email.adr> 可以搜索特定条目。如果要添加或编辑条目，add 和 edit 命令将使用相同的基本模板打开配置的编辑器，唯一的区别是 add 命令的模板将为空。abook 需要你导入和导出 VCF 文件，但它为查找提供了一些不错的功能。要将文件转换为 abook 格式，请先安装 abook 并创建 ~/.abook 默认目录。然后让 abook 解析所有文件，并将它们放入 ~/.abook/addresses 文件中：apt install abook ls ~/.calendars/Addresses/default/* | xargs cat | abook --convert --informat vcard --outformat abook > ~/.abook/addresses现在运行 abook，你将有一个非常漂亮的 UI 来浏览…

免费电子书《Linux 进程间通信指南》介绍
type: item
date: 2020-01-30T19:56:51+08:00
description: 这本免费的电子书使经验丰富的程序员更深入了解 Linux 中进程间通信（IPC）的核心概念和机制。让一个软件过程与另一个软件过程进行对话是一个微妙的平衡行为。但是，它对于应用程序而言可能是至关重要的功能，因此这是任何从事复杂项目的程序员都必须解决的问题。你的应用程序是否需要启动由其它软件处理的工作；监视外设或网络上正在执行的操作；或者检测来自其它来源的信号，当你的软件需要依赖其自身代码之外的东西来知道下一步做什么或什么时候做时，你就需要考虑 进程间通信 inter-process communication （IPC）。这在 Unix 操作系统上已经由来已久了，这可能是因为人们早期预期软件会来自各种来源。按照相同的传统，Linux 提供了一些同样的 IPC 接口和一些新接口。Linux 内核具有多种 IPC 方法，util-linux 包包含了 ipcmk、ipcrm、ipcs 和 lsipc 命令，用于监视和管理 IPC 消息。显示进程间通信信息在尝试 IPC 之前，你应该知道系统上已经有哪些 IPC 设施。lsipc 命令提供了该信息。RESOURCE DESCRIPTION LIMIT USED USE% MSGMNI Number of message queues 32000 0 0.00% MSGMAX Max size of message (byt.. 8192 - - MSGMNB Default max size of queue 16384 - - SHMMNI Shared memory segments 4096 79 1.93% SHMALL Shared memory pages 184[...] 25452 0.00% SHMMAX Max size of shared memory 18446744073692774399 SHMMIN Min size of shared memory 1 - - SEMMNI Number of semaphore ident 32000 0 0.00% SEMMNS Total number of semaphore 1024000.. 0 0.00% SEMMSL Max semaphores per semap 32000 - - SEMOPM Max number of operations p 500 - - SEMVMX Semaphore max value 32767 - -你可能注意到，这个示例清单包含三种不同类型的 IPC 机制，每种机制在 Linux 内核中都是可用的：消息（MSG）、共享内存（SHM）和信号量（SEM）。你可以用 ipcs 命令查看每个子系统的当前活动：$ ipcs ------ Message Queues Creators/Owners --- msqid perms cuid cgid [...] ------ Shared Memory Segment Creators/Owners shmid perms cuid cgid [...] 557056 700 seth users [...] 3571713 700 seth users [...] 2654210 600 seth users [...] 2457603 700 seth users [...] ------ Semaphore Arrays Creators/Owners --- semid perms cuid cgid [...]这表明当前没有消息或信号量阵列，但是使用了一些共享内存段。你可以在系统上执行一个简单的示例，这样就可以看到正在工作的系统之一。它涉及到一些 C 代码，所以你必须在系统上有构建工具。必须安装这些软件包才能从源代码构建软件，这些软件包的名称取决于发行版，因此请参考文档以获取详细信息。例如，在基于 Debian 的发行版上，你可以在 wiki 的构建教程部分了解构建需求，而在基于 Fedora 的发行版上，你可以参考该文档的从源代码安装软件部分。创建一个消息队列你的系统已经有一个默认的消息队列，但是你可以使用 ipcmk 命令创建你自己的消息队列：$ ipcmk --queue Message queue id: 32764编写一个简单的 IPC 消息发送器，为了简单，在队列 ID 中硬编码：#include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <string.h> struct msgbuffer { char text[24]; } message; int main() { int msqid = 32764; strcpy…

我的 Linux 故事：在 90 年代学习 Linux
type: item
date: 2020-01-30T05:38:00+08:00
description: 这是一个关于我如何在 WiFi 时代之前学习 Linux 的故事，那时的发行版还以 CD 的形式出现。大部分人可能不记得 1996 年时计算产业或日常生活世界的样子。但我很清楚地记得那一年。我那时候是堪萨斯中部一所高中的二年级学生，那是我的自由与开源软件（FOSS）旅程的开端。我从这里开始进步。我在 1996 年之前就开始对计算机感兴趣。我在我家的第一台 Apple ][e 上启蒙成长，然后多年之后是 IBM Personal System/2。（是的，在这过程中有一些代际的跨越。）IBM PS/2 有一个非常激动人心的特性：一个 1200 波特的 Hayes 调制解调器。我不记得是怎样了，但在那不久之前，我得到了一个本地 BBS 的电话号码。一旦我拨号进去，我可以得到本地的一些其他 BBS 的列表，我的网络探险就此开始了。在 1995 年，足够幸运的人拥有了家庭互联网连接，每月可以使用不到 30 分钟。那时的互联网不像我们现代的服务那样，通过卫星、光纤、有线电视同轴电缆或任何版本的铜线提供。大多数家庭通过一个调制解调器拨号，它连接到他们的电话线上。（这时离移动电话无处不在的时代还早得很，大多数人只有一部家庭电话。）尽管这还要取决你所在的位置，但我不认为那时有很多独立的互联网服务提供商（ISP），所以大多数人从仅有的几家大公司获得服务，包括 America Online，CompuServe 以及 Prodigy。你能获取到的服务速率非常低，甚至在拨号上网革命性地达到了顶峰的 56K，你也只能期望得到最高 3.5Kbps 的速率。如果你想要尝试 Linux，下载一个 200MB 到 800MB 的 ISO 镜像或（更加切合实际的）一套软盘镜像要贡献出时间、决心，以及减少电话的使用。我走了一条简单一点的路：在 1996 年，我从一家主要的 Linux 发行商订购了一套 “tri-Linux” CD 集。这些光盘提供了三个发行版，我的这套包含了 Debian 1.1（Debian 的第一个稳定版本）、Red Hat Linux 3.0.3 以及 Slackware 3.1（代号 Slackware ‘96）。据我回忆，这些光盘是从一家叫做 Linux Systems Labs 的在线商店购买的。这家在线商店如今已经不存在了，但在 90 年代和 00 年代早期，这样的发行商很常见。这些是多光盘 Linux 套件。这是 1998 年的一套光盘，你可以了解到他们都包含了什么：在 1996 年夏天一个命中注定般的日子，那时我住在堪萨斯一个新的并且相对较为乡村的城市，我做出了安装并使用 Linux 的第一次尝试。在 1996 年的整个夏天，我尝试了那套三张 Linux CD 套件里的全部三个发行版。他们都在我母亲的老 Pentium 75MHz 电脑上完美运行。我最终选择了 Slackware 3.1 作为我的首选发行版，相比其它发行版可能更多的是因为它的终端的外观，这是决定选择一个发行版前需要考虑的重要因素。我将系统设置完毕并运行了起来。我连接到一家 “不太知名的” ISP（一家这个区域的本地服务商），通过我家的第二条电话线拨号（为了满足我的所有互联网使用而订购）。那就像在天堂一样。我有一台完美运行的双系统（Microsoft Windows 95 和 Slackware 3.1）电脑。我依然拨号进入我所知道和喜爱的 BBS，游玩在线 BBS 游戏，比如 Trade Wars、Usurper 以及 Legend of the Red Dragon。我能够记得在 EFNet（IRC）上 #Linux 频道上渡过的日子，帮助其他用户，回答他们的 Linux 问题以及和版主们互动。在我第一次在家尝试使用 Linux 系统的 20 多年后，已经是我进入作为 Red Hat 顾问的第五年，我仍然在使用 Linux（现在是 Fedora）作为我的日常系统，并且依然在 IRC 上帮助想要使用 Linux 的人们。via: https://opensource.com/article/19/11/learning-linux-90s作者：Mike Harris 选题：lujun9972 译者：alim0x 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出

使用公钥/私钥对设定免密的 Linux 登录方式
type: item
date: 2020-01-29T22:10:00+08:00
description: 使用一组公钥/私钥对让你不需要密码登录到远程 Linux 系统或使用 ssh 运行命令，这会非常方便，但是设置过程有点复杂。下面是帮助你的方法和脚本。在 Linux 系统上设置一个允许你无需密码即可远程登录或运行命令的帐户并不难，但是要使它正常工作，你还需要掌握一些繁琐的细节。在本文，我们将完成整个过程，然后给出一个可以帮助处理琐碎细节的脚本。设置好之后，如果希望在脚本中运行 ssh 命令，尤其是希望配置自动运行的命令，那么免密访问特别有用。需要注意的是，你不需要在两个系统上使用相同的用户帐户。实际上，你可以把公用密钥用于系统上的多个帐户或多个系统上的不同帐户。设置方法如下。在哪个系统上启动？首先，你需要从要发出命令的系统上着手。那就是你用来创建 ssh 密钥的系统。你还需要可以访问远程系统上的帐户并在其上运行这些命令。为了使角色清晰明了，我们将场景中的第一个系统称为 “boss”，因为它将发出要在另一个系统上运行的命令。因此，命令提示符如下：boss$如果你还没有在 boss 系统上为你的帐户设置公钥/私钥对，请使用如下所示的命令创建一个密钥对。注意，你可以在各种加密算法之间进行选择。（一般使用 RSA 或 DSA。）注意，要在不输入密码的情况下访问系统，你需要在下面的对话框中的两个提示符出不输入密码。如果你已经有一个与此帐户关联的公钥/私钥对，请跳过此步骤。boss$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/myself/.ssh/id_rsa): Enter passphrase (empty for no passphrase): <== 按下回车键即可 Enter same passphrase again: <== 按下回车键即可 Your identification has been saved in /home/myself/.ssh/id_rsa. Your public key has been saved in /home/myself/.ssh/id_rsa.pub. The key fingerprint is: SHA256:1zz6pZcMjA1av8iyojqo6NVYgTl1+cc+N43kIwGKOUI myself@boss The key's randomart image is: +---[RSA 3072]----+ | . .. | | E+ .. . | | .+ .o + o | | ..+.. .o* . | | ... So+*B o | | + ...==B . | | . o . ....++. | |o o . . o..o+ | |=..o.. ..o o. | +----[SHA256]-----+上面显示的命令将创建公钥和私钥。其中公钥用于加密，私钥用于解密。因此，这些密钥之间的关系是关键的，私有密钥绝不应该被共享。相反，它应该保存在 boss 系统的 .ssh 文件夹中。注意，在创建时，你的公钥和私钥将会保存在 .ssh 文件夹中。下一步是将公钥复制到你希望从 boss 系统免密访问的系统。你可以使用 scp 命令来完成此操作，但此时你仍然需要输入密码。在本例中，该系统称为 “target”。boss$ scp .ssh/id_rsa.pub myacct@target:/home/myaccount myacct@target's password:你需要安装公钥在 target 系统（将运行命令的系统）上。如果你没有 .ssh 目录（例如，你从未在该系统上使用过 ssh），运行这样的命令将为你设置一个目录：target$ ssh localhost date target$ ls -la .ssh total 12 drwx------ 2 myacct myacct 4096 Jan 19 11:48 . drwxr-xr-x 6 myacct myacct 4096 Jan 19 11:49 .. -rw-r--r-- 1 myacct myacct 222 Jan 19 11:48 known_hosts仍然在目标系统上，你需要将从“boss”系统传输的公钥添加到 .ssh/authorized_keys 文件中。如果该文件已经存在，使用下面的命令将把它添加到文件的末尾；如果文件不存在，则创建该文件并添加密钥。target$ cat id_rsa.pub >> .ssh/authorized_keys下一步，你需要确保你的 authorized_keys 文件权限为 600。如果还不是，执…

在你的 Python 平台类游戏中放一些奖励
type: item
date: 2020-01-29T21:12:48+08:00
description: 这部分是关于在使用 Python 的 Pygame 模块开发的视频游戏总给你的玩家提供收集的宝物和经验值的内容。这是正在进行的关于使用 Python 3 的 Pygame 模块创建视频游戏的系列文章的第十部分。以前的文章有:通过构建一个简单的掷骰子游戏去学习怎么用 Python 编程使用 Python 和 Pygame 模块构建一个游戏框架如何在你的 Python 游戏中添加一个玩家用 Pygame 使你的游戏角色移动起来如何向你的 Python 游戏中添加一个敌人在 Pygame 游戏中放置平台在你的 Python 游戏中模拟引力为你的 Python 平台类游戏添加跳跃功能使你的 Python 游戏玩家能够向前和向后跑如果你已经阅读了本系列的前几篇文章，那么你已经了解了编写游戏的所有基础知识。现在你可以在这些基础上，创造一个全功能的游戏。当你第一次学习时，遵循本系列代码示例，这样的“用例”是有帮助的，但是，用例也会约束你。现在是时候运用你学到的知识，以新的方式应用它们了。如果说，说起来容易做起来难，这篇文章展示了一个如何将你已经了解的内容用于新目的的例子中。具体来说，就是它涵盖了如何使用你以前的课程中已经了解到的来实现奖励系统。在大多数电子游戏中，你有机会在游戏世界中获得“奖励”或收集到宝物和其他物品。奖励通常会增加你的分数或者你的生命值，或者为你的下一次任务提供信息。游戏中包含的奖励类似于编程平台。像平台一样，奖励没有用户控制，随着游戏世界的滚动进行，并且必须检查与玩家的碰撞。创建奖励函数奖励和平台非常相似，你甚至不需要一个奖励的类。你可以重用 Platform 类，并将结果称为“奖励”。由于奖励类型和位置可能因关卡不同而不同，如果你还没有，请在你的 Level 中创建一个名为 loot 的新函数。因为奖励物品不是平台，你也必须创建一个新的 loot_list 组，然后添加奖励物品。与平台、地面和敌人一样，该组用于检查玩家碰撞: def loot(lvl,lloc): if lvl == 1: loot_list = pygame.sprite.Group() loot = Platform(300,ty*7,tx,ty, 'loot_1.png') loot_list.add(loot) if lvl == 2: print(lvl) return loot_list你可以随意添加任意数量的奖励对象；记住把每一个都加到你的奖励清单上。Platform 类的参数是奖励图标的 X 位置、Y 位置、宽度和高度（通常让你的奖励精灵保持和所有其他方块一样的大小最为简单），以及你想要用作的奖励的图片。奖励的放置可以和贴图平台一样复杂，所以使用创建关卡时需要的关卡设计文档。在脚本的设置部分调用新的奖励函数。在下面的代码中，前三行是上下文，所以只需添加第四行:enemy_list = Level.bad( 1, eloc ) ground_list = Level.ground( 1,gloc,tx,ty ) plat_list = Level.platform( 1,tx,ty ) loot_list = Level.loot(1,tx,ty)正如你现在所知道的，除非你把它包含在你的主循环中，否则奖励不会被显示到屏幕上。将下面代码示例的最后一行添加到循环中: enemy_list.draw(world) ground_list.draw(world) plat_list.draw(world) loot_list.draw(world)启动你的游戏看看会发生什么。你的奖励将会显示出来，但是当你的玩家碰到它们时，它们不会做任何事情，当你的玩家经过它们时，它们也不会滚动。接下来解决这些问题。滚动奖励像平台一样，当玩家在游戏世界中移动时，奖励必须滚动。逻辑与平台滚动相同。要向前滚动奖励物品，添加最后两行: for e in enemy_list: e.rect.x -= scroll for l in loot_list: l.rect.x -= scroll要向后滚动，请添加最后两行： for e in enemy_list: e.rect.x += scroll for l in loot_list: l.rect.x += scroll再次启动你的游戏，看看你的奖励物品现在表现得像在游戏世界里一样了，而不是仅仅画在上面。检测碰撞就像平台和敌人一样，你可以检查奖励物品和玩家之间的碰撞。逻辑与其他碰撞相同，除了撞击不会（必然）影响重力或生命值。取而代之的是，命中会导致奖励物品会消失并增加玩家的分数。当你的玩家触摸到一个奖励对象时，你可以从 loot_list 中移除该对象。这意味着当你的主循环在 loot_list 中重绘所有奖励物品时，…

Wine 5.0 发布了！
type: item
date: 2020-01-28T22:15:23+08:00
description: Wine 的一个新的主要版本发布了。使用 Wine 5.0，在 Linux 上运行 Windows 应用程序和游戏的体验得到进一步改进。通过一些努力，你可以使用 Wine 在 Linux 上运行 Windows 应用程序。当你必须使用一个仅在 Windows 上可用的软件时，Wine 是一个可以尝试的工具。它支持许多这样的软件。Wine 的一个新的主要发布版本已经降临，即 Wine 5.0，几乎距它的 4.0 发布一年之后。Wine 5.0 发布版本引进了几个主要特性和很多显著的更改/改进。在这篇文章中，我将重点介绍新的特性是什么，并且也将提到安装说明。在 Wine 5.0 中有什么新的特性？如他们的官方声明所述，这是 5.0 发布版本中的关键更改：PE 格式的内置模块。支持多显示器。重新实现了 XAudio2。支持 Vulkan 1.1。支持微软安装程序（MSI）补丁文件。性能提升。因此，随着 Vulkan 1.1 和对多显示器的支持 —— Wine 5.0 发布版本是一件大事。除了上面强调的这些关键内容以外，在新的版本中包含成千上万的更改/改进中，你还可以期待对控制器的支持更好。值得注意的是，此版本特别纪念了 Józef Kucia（vkd3d 项目的首席开发人员）。他们也已经在发布说明中提到这一点：这个发布版本特别纪念了 Józef Kucia，他于 2019 年 8 月去世，年仅 30 岁。Józef 是 Wine 的 Direct3D 实现的一个主要贡献者，并且是 vkd3d 项目的首席开发人员。我们都非常怀念他的技能和友善。如何在 Ubuntu 和 Linux Mint 上安装 Wine 5.0注意：如果你在以前安装过 Wine，你应该将其完全移除，以（如你希望的）避免一些冲突。此外，WineHQ 存储库的密钥最近已被更改，针对你的 Linux 发行版的更多的操作指南，你可以参考它的下载页面。Wine 5.0 的源码可在它的官方网站上获得。为了使其工作，你可以阅读更多关于构建 Wine 的信息。基于 Arch 的用户应该很快就会得到它。在这里，我将向你展示在 Ubuntu 和其它基于 Ubuntu 的发行版上安装 Wine 5.0 的步骤。请耐心，并按照步骤一步一步安装和使用 Wine。这里涉及几个步骤。请记住，Wine 安装了太多软件包。你会看到大量的软件包列表，下载大小约为 1.3 GB。在 Ubuntu 上安装 Wine 5.0（不适用于 Linux Mint）首先，使用这个命令来移除现存的 Wine：sudo apt remove winehq-stable wine-stable wine1.6 wine-mono wine-geco winetricks然后确保添加 32 位体系结构支持：sudo dpkg --add-architecture i386下载并添加官方 Wine 存储库密钥：wget -qO - https://dl.winehq.org/wine-builds/winehq.key | sudo apt-key add -现在，接下来的步骤需要添加存储库，为此, 你需要首先知道你的 Ubuntu 版本。对于 Ubuntu 18.04 和 19.04，用这个 PPA 添加 FAudio 依赖， Ubuntu 19.10 不需要它：sudo add-apt-repository ppa:cybermax-dexter/sdl2-backport现在使用此命令添加存储库：sudo apt-add-repository "deb https://dl.winehq.org/wine-builds/ubuntu $(lsb_release -cs) main"现在你已经添加了正确的存储库，可以使用以下命令安装 Wine 5.0：sudo apt update && sudo apt install --install-recommends winehq-stable请注意，尽管在软件包列表中将 Wine 5 列为稳定版，但你仍可能会看到 winehq-stable 的 wine 4.0.3。也许它不会传播到所有地理位置。从今天早上开始，我可以看到 Wine 5.0。在 Linux Mint 19.1、19.2 和 19.3 中安装 Wine 5.0正如一些读者通知我的那样，apt-add 存储库命令不适用于 Linux Mint 19.x 系列。这是添加自定义存储库的另一种方法。你必须执行与 Ubuntu 相同的步骤。如删除现存的 Wine 包：sudo apt remove winehq-stable wine-stable wine1.6 wine-mono wine-geco winetr…

C 还是 Rust：选择哪个用于硬件抽象编程
type: item
date: 2020-01-28T20:35:00+08:00
description: 在 Rust 中使用类型级编程可以使硬件抽象更加安全。Rust 是一种日益流行的编程语言，被视为硬件接口的最佳选择。通常会将其与 C 的抽象级别相比较。本文介绍了 Rust 如何通过多种方式处理按位运算，并提供了既安全又易于使用的解决方案。语言诞生于官方描述总览C1972 年C 是一种通用编程语言，具有表达式简约、现代的控制流和数据结构，以及丰富的运算符集等特点。（来源：CS 基础知识）C 是（一种）命令式语言，旨在以相对简单的方式进行编译，从而提供对内存的低级访问。（来源：W3schools.in）Rust2010 年一种赋予所有人构建可靠、高效的软件的能力的语言（来源：Rust 网站）Rust 是一种专注于安全性（尤其是安全并发性）的多范式系统编程语言。（来源：维基百科)）在 C 语言中对寄存器值进行按位运算在系统编程领域，你可能经常需要编写硬件驱动程序或直接与内存映射设备进行交互，而这些交互几乎总是通过硬件提供的内存映射寄存器来完成的。通常，你通过对某些固定宽度的数字类型进行按位运算来与这些寄存器进行交互。例如，假设一个 8 位寄存器具有三个字段：+----------+------+-----------+---------+ | (unused) | Kind | Interrupt | Enabled | +----------+------+-----------+---------+ 5-7 2-4 1 0字段名称下方的数字规定了该字段在寄存器中使用的位。要启用该寄存器，你将写入值 1（以二进制表示为 0000_0001）来设置 Enabled 字段的位。但是，通常情况下，你也不想干扰寄存器中的现有配置。假设你要在设备上启用中断功能，但也要确保设备保持启用状态。为此，必须将 Interrupt 字段的值与 Enabled 字段的值结合起来。你可以通过按位操作来做到这一点：1 | (1 << 1)通过将 1 和 2（1 左移一位得到）进行“或”（|）运算得到二进制值 0000_0011 。你可以将其写入寄存器，使其保持启用状态，但也启用中断功能。你的头脑中要记住很多事情，特别是当你要在一个完整的系统上和可能有数百个之多的寄存器打交道时。在实践上，你可以使用助记符来执行此操作，助记符可跟踪字段在寄存器中的位置以及字段的宽度（即它的上边界是什么）下面是这些助记符之一的示例。它们是 C 语言的宏，用右侧的代码替换它们的出现的地方。这是上面列出的寄存器的简写。＆ 的左侧是该字段的起始位置，而右侧则限制该字段所占的位：#define REG_ENABLED_FIELD(x) (x << 0) & 1 #define REG_INTERRUPT_FIELD(x) (x << 1) & 2 #define REG_KIND_FIELD(x) (x << 2) & (7 << 2)然后，你可以使用这些来抽象化寄存器值的操作，如下所示：void set_reg_val(reg* u8, val u8); fn enable_reg_with_interrupt(reg* u8) { set_reg_val(reg, REG_ENABLED_FIELD(1) | REG_INTERRUPT_FIELD(1)); }这就是现在的做法。实际上，这就是大多数驱动程序在 Linux 内核中的使用方式。有没有更好的办法？如果能够基于对现代编程语言研究得出新的类型系统，就可能能够获得安全性和可表达性的好处。也就是说，如何使用更丰富、更具表现力的类型系统来使此过程更安全、更持久？在 Rust 语言中对寄存器值进行按位运算继续用上面的寄存器作为例子：+----------+------+-----------+---------+ | (unused) | Kind | Interrupt | Enabled | +----------+------+-----------+---------+ 5-7 2-4 1 0你想如何用 Rust 类型来表示它呢？你将以类似的方式开始，为每个字段的偏移定义常量（即，距最低有效位有多远）及其掩码。掩码是一个值，其二进制表示形式可用于更新或读取寄存器内部的字段：const ENABLED_MASK: u8 = 1; const ENABLED_OFFSET: u8 = 0; const INTERRUPT_MASK: u8 = 2; const INTERRUPT_OFFSET: u8 = 1; const KIND_MASK: u8 = 7 << 2; const KIND_OFFSET: u8 = 2;接下来，你将声明一个 Field 类型并进行操作，将给定值转换为与其位置相关的值，以供在寄存器内使用：st…

为什么每个人都在谈论 WebAssembly
type: item
date: 2020-01-27T20:54:39+08:00
description: 了解有关在 Web 浏览器中运行任何代码的最新方法的更多信息。如果你还没有听说过 WebAssembly，那么你很快就会知道。这是业界最保密的秘密之一，但它无处不在。所有主流的浏览器都支持它，并且它也将在服务器端使用。它很快，它能用于游戏编程。这是主要的国际网络标准组织万维网联盟（W3C）的一个开放标准。你可能会说：“哇，这听起来像是我应该学习编程的东西！”你可能是对的，但也是错的。你不需要用 WebAssembly 编程。让我们花一些时间来学习这种通常被缩写为“Wasm”的技术。它从哪里来？大约十年前，人们越来越认识到，广泛使用的 JavaScript 不够快速，无法满足许多目的。JavaScript 无疑是成功和方便的。它可以在任何浏览器中运行，并启用了今天我们认为理所当然的动态网页类型。但这是一种高级语言，在设计时并没有考虑到计算密集型工作负载。然而，尽管负责主流 web 浏览器的工程师们对性能问题的看法大体一致，但他们对如何解决这个问题却意见不一。出现了两个阵营，谷歌开始了它的 原生客户端 Native Client 项目，后来又推出了 可移植原生客户端 Portable Native Client 变体，着重于允许用 C/C++ 编写的游戏和其它软件在 Chrome 的一个安全隔间中运行。与此同时，Mozilla 赢得了微软对 asm.js 的支持。该方法更新了浏览器，因此它可以非常快速地运行 JavaScript 指令的低级子集（有另一个项目可以将 C/C++ 代码转换为这些指令）。由于这两个阵营都没有得到广泛采用，各方在 2015 年同意围绕一种称为 WebAssembly 的新标准，以 asm.js 所采用的基本方法为基础，联合起来。如 CNET 的 Stephen Shankland 当时所写，“在当今的 Web 上，浏览器的 JavaScript 将这些指令转换为机器代码。但是，通过 WebAssembly，程序员可以在此过程的早期阶段完成很多工作，从而生成介于两种状态之间的程序。这使浏览器摆脱了创建机器代码的繁琐工作，但也实现了 Web 的承诺 —— 该软件将在具有浏览器的任何设备上运行，而无需考虑基础硬件的细节。”在 2017 年，Mozilla 宣布了它的最小可行的产品（MVP），并使其脱离预览版阶段。到该年年底，所有主流的浏览器都采用了它。2019 年 12 月，WebAssembly 工作组发布了三个 W3C 推荐的 WebAssembly 规范。WebAssembly 定义了一种可执行程序的可移植二进制代码格式、相应的文本汇编语言以及用于促进此类程序与其宿主环境之间的交互接口。WebAssembly 代码在低级虚拟机中运行，这个可运行于许多微处理器之上的虚拟机可模仿这些处理器的功能。通过即时（JIT）编译或解释，WebAssembly 引擎可以以近乎原生平台编译代码的速度执行。为什么现在感兴趣？当然，最近对 WebAssembly 感兴趣的部分原因是最初希望在浏览器中运行更多计算密集型代码。尤其是笔记本电脑用户，越来越多的时间都花在浏览器上（或者，对于 Chromebook 用户来说，基本上是所有时间）。这种趋势已经迫切需要消除在浏览器中运行各种应用程序的障碍。这些障碍之一通常是性能的某些方面，这正是 WebAssembly 及其前身最初旨在解决的问题。但是，WebAssembly 并不仅仅适用于浏览器。在 2019 年，Mozilla 宣布了一个名为 WASI（ WebAssembly 系统接口 WebAssembly System Interface ）的项目，以标准化 WebAssembly 代码如何与浏览器上下文之外的操作系统进行交互。通过将浏览器对 WebAssembly 和 WASI 的支持结合在一起，编译后的二进制文件将能够以接近原生的速度，跨不同的设备和操作系统在浏览器内外运行。WebAssembly 的低开销立即使它可以在浏览器之外使用，但这无疑是赌注；显然，还有其它不会引入性能瓶颈的运行应用程序的方法。为什么要专门使用 WebAssembly？一个重要的原因是它的可移植性。如今，像 C++ 和 Rust 这样的广泛使用的编译语言可能是与 WebAssembly 关联最紧密的语言。但是，各种各样的其他语言可以编译为 WebAssembly 或拥有它们的 WebAssembly 虚拟机。此外，尽管 WebAssembly 为其执行环境假定了某些先决条件，但它被设计为在各种操作系统和指令集体系结构上有效执行。因此，WebAssembly 代码可以使用多种语言编写，并可以在多种操作系统和处理器类型上运行。另一个 WebAssembly 优势源于这样一个事实：代码在虚拟机中运行。因此，…