从零开始创建WebAssembly 游戏

本文介绍了一个从零开始使用Rust创建WebAssembly游戏的过程,包括理解wasm和wat,异步加载wasm文件,Rust与JavaScript的交互,内存分配器weealloc的使用,以及如何在JavaScript中创建画布。文章强调了前后端协作的重要性,并提供了项目配置和代码示例。
摘要由CSDN通过智能技术生成

概述

学习一段时间rust,开始使用rust 创建一些小项目,rust的一大用处,结合JS,算法部分使用rust进行编写将编译成webassembly 后通过js调用,提高运行速度
,学习从0开始创建一个WebAssembly 游戏,学习rust如何与web 前端进行整合,该项目重点在于如何将rust编译成WebAssembly结合JS使用,至于游戏界面JS在此不进行详细介绍,直接使用模板编写。

wasm 与 wat

  • 二进制格式(执行): .wasm文件后缀
  • 文本格式:.wat文件后缀 wat 是基于文本助记表示形式WAT, wat 通过WABT工具编译成二进制文件wasm
  • chrome会将wasm 二进制编译成wat
  • wat2wasm 网址:

项目创建

1. cargo new --lib wasm-game
2. 创建www 目录
3. 在www目录下面:
   npm install --save-dev webpack-dev-server
   npm install --save webpack-cli
   npm install --save copy-webpack-plugin
  • 加载wasm 文件必须得异步加载
    wat2wasm
    对于js 的使用wasm , 使用异步的方式对其进行加载
async function run() {
   
    const response = await fetch("yz.wasm");
    const buffer = await response.arrayBuffer();
    // 获取web wasm
    const wasm = await WebAssembly.instantiate(buffer);
    // 从 wasm 获取其中方法
    const addTwoFunction = wasm.instance.exports.addTwo;

    const result = addTwoFunction(10, 20);
    console.log(result);
}

run();

webAssembly中rust与js交互

  • 前后端分离后,前端负责一部分,后端负责一部分内如,做一个互相的review
  • 前往不要rust 写完部分功能后,把Trello卡片一移,交给JS这样主要树沟通成本太高。
1. 下载wasm-pack: https://rustwasm.github.io/wasm-pack/install
2. 配置crate-type
3. 配置wasm-bindgen
4. 配置wasm-opt:
	[package.metadata.wasm-pack.profile.release]
	wasm-opt= false
JS:
    1. wasm-pack build --target web 生成包含wasm文件
    2. 配置npm 的package.json 将PKG目录导入
    3. 调用hello
  • 第一步在Cargo.toml 配置
[package]
name = "wasm_game"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
wasm-bindgen = "0.2.78"

[lib]
crate-type = ["cdylib"]
// 此配置是必须的 不然会报错
[package.metadata.wasm-pack.profile.release]
wasm-opt = false
  • lib.rs 中写调用jS中alert
use wasm_bindgen::prelude::*;

// rust 掉头JS
#[wasm_bindgen]
extern "C" {
   
    // 需要在 rust中表明这个是一个外部的方法
    pub fn alert(s: &str);
}

#[wasm_bindgen]
pub fn hello(name: &str){
   
    alert(name);
}
  • 第二步:在当前rust目录下:
cargo build // 生成target文件
wasm-pack build --target web // 生成wasm pkg目录

  • 在 js的package.json 引入刚才生成的文件
"dependencies": {
   
    "copy-webpack-plugin": "^10.2.0",
    "ts-loader": "^9.2.6",
    "typescript": "^4.5.4",
    "wasm_game": "file:../pkg", // 名称和lib.rs 保持一致
    "webpack": "^5.66.0",
    "webpack-cli": "^4.9.1"
  },

npm install 重新导入, npm run dev 重新运行
效果如下在wasm中调用 js中函数

在这里插入图片描述

weealloc 内存分配,bootstrap.js 捕获错误

wee_alloc webassembly属于一个轻量级的内存分配器

use wasm_bindgen::prelude::*;
use wee_alloc::WeeAlloc;

#[global_allocator]
static ALLOC: WeeAlloc = WeeAlloc::INIT;
// rust 掉头JS
#[wasm_bindgen]
extern "C" {
   
    // 需要在 rust中表明这个是一个外部的方法
    pub fn alert(s: &str);
}

#[wasm_bindgen]
pub fn hello(name: &str){
   
    alert(name);
}
// 用来捕获错误
import ("./index.js").catch((e) => {
   
    console.error("Error", e);
})

js 切换到TS

npm install typescript
npm install --save typescript ts-loader

创建画布

1.使用rust 存储蛇的长度,每个蛇的像素带你位置,向右移动 像素+1,注意边界问题
2. js 中使用canve 创建画布
3. 使用setTime 进行刷新

use wasm_bindgen::prelude::*;
use wee_alloc::WeeAlloc;

#[global_allocator]
static ALLOC: WeeAlloc = WeeAlloc::INIT;

// rust use js module
#[wasm_bindgen(module = "/www/utils/random.js")]
extern "C" {
   
    fn random(max: usize) -> usize;
}

#[wasm_bindgen]
#[derive(Copy, Clone)]
pub enum GameStatus 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值