用rust编写一个wasm贪吃蛇小游戏:day1

560 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

最近12月更文活动开始了。

刚好趁着最近上班摸鱼,来把之前写一个wasm贪吃蛇小游戏记录下来。

那么废话少说,下面我们直接开始吧。

安装依赖&wasm-pack

首先安装需要的依赖 cargo-generate

cargo install cargo-generate

当然还有 wasm-pack的相关依赖。

直接点击页面中的wasm-pack-init.exe下载安装包安装即可。

image.png

安装好对应的依赖之后,就可以创建项目了。这里直接clonewasm-pack提供的仓库模板:

cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name wasm_snake

然后打包一下:

wasm-pack build --target web

打包targetweb,即输出的JS文件可以在浏览器中作为ES模块导入,但WebAssembly必须手动实例化和加载。

文件目录就会变成现在这样:

1665305633130.png

pkg文件夹里面的wasm_snake_bg.wasm文件就是后面我们将会用到的wasm文件

创建web项目

在项目根目录下创建web文件夹,用pnpm/yarn/npm初始化web项目

这里我用yarn:

yarn init -y

然后往package.json里面添加打包web项目的项目依赖:

{
  "name": "web",
  "version": "1.0.0",
  "main": "index.js",
  "author": "Linken",
  "license": "MIT",
  "scripts": {
    "build": "node esbuild.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    "esbuild": "^0.15.10",
    "typescript": "^4.8.4",
    "wasm_snake": "file:../pkg"
  },
  "keywords": []
}

这里,我们会用到tsesbuild进行项目编写和打包。wasm_snake这个包,则是直接引入了本地的pkg文件,通过file进行引入。

接着下载依赖包:

yarn install

然后新建esbuild.js文件,加入下面代码:

require('esbuild')
  .build({
    entryPoints: ['index.ts'],
    bundle: true,
    target: ['es2020'],
    format: 'esm',
    outdir: 'public'
  })
  .catch(() => process.exit(1))

这里简单定义好打包的入口index.ts和输出文件夹publictarget指定JavaScript语言版本为es2020(因为这个版本才支持import.meta),format设置了生成的JavaScript文件的输出格式为esm(在浏览器中作为ES模块导入)。另外,不要忘记新建public文件目录和index.ts入口文件。

最后跑下脚本,测试一下打包:

yarn run build

最终的项目目录应该是这样的:

1665307261727.png

运行项目

public文件夹下继续新建一个index.html文件:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style type="text/css">
      .container {
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        position: absolute;
        display: flex;
        align-items: center;
        justify-content: center;
        flex-direction: column;
      }
      .tools {
        margin-bottom: 20px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="tools">
        <button id="game_control">开始游戏</button>
        <button id="game_stop">暂停游戏</button>
      </div>
      <canvas id="snake-canvas"></canvas>
    </div>
  </body>
  <script type="module" src="index.js"></script>
</html>

同时在index.ts文件引入wasm:

import init, { greet } from "wasm_snake";

init().then(wasm => {
  greet();
});

cdweb文件目录下,删除之前的依赖node_modules文件目录,重新下载一次依赖和打包:

yarn install

yarn run build

打包完之后,在public文件目录下会生成index.js文件。 然后把pkg文件目录中的wasm_snake_bg.wasm复制一份到public目录下,用浏览器打开index.html文件即可。(别问我为什么还要复制一遍wasm到public目录,因为我也不知道esbuild怎么把wasm文件打包过去😂,学艺不精,等后面有空再研究研究😭)

这时候,项目的文件目录应该是这样的:

6UHJZ_Z_7$@(81E6JL)R{{P.png

打开浏览器时,应该会有弹窗:

9IH}PWOJXSNAD)ESJZSU)2F.png