#random #map #world #generate #generator #command-line #command-line-tool

bin+lib world-map-gen

命令行工具和库,用于为 Rust 和 WebAssembly 生成随机游戏世界地图

2 个版本

0.1.1 2019 年 5 月 18 日
0.1.0 2019 年 1 月 25 日

#728 in 游戏开发

MIT 许可证

70KB
1.5K SLoC

随机世界地图生成器

crates.io npm version documentation CI on Linux and macOS CI on Windows

world-map-gen 是一个适用于 Rust 和 WebAssembly 的 CLI 工具和库。它提供生成游戏(如复古战术模拟游戏)的随机世界地图的功能。生成的地图由单元格组成。每个单元格都有其海拔和类型(海洋、城镇、平原、森林、山脉等)。

在浏览器中通过访问 项目页面 或通过安装 CLI 应用程序 在您的终端中尝试它。

屏幕截图

3D 中生成的 120x120 地图示例

screenshot of 3D map

2D 中生成的地图示例

screenshot of 2D map

终端(iTerm2)中生成的地图示例

screenshot of map in terminal

这个项目是我创建一个既能作为普通 Rust 库也能作为 WebAssembly 库良好工作的 Rust 库的个人实践,这比 Rust+Wasm 教程 更具实践性。

我从 这本书 中学习了生成世界地图的算法,并实现了它(进行了一些小的改进)。

安装

在项目页面上尝试随机地图生成

此项目的 gh-page 是一个用于展示此包如何工作的演示页面。该演示网站使用 TypeScript、WebAssembly(归功于 wasm-packwasm-bindgen)和 webpack 构建。页面的源代码在 www/ 目录中。

作为 Rust 库

这个库以 crate 的形式提供。可以使用 cargo 软件包管理器安装。

请在您的项目的 Cargo.toml 中添加依赖项,并运行 cargo build

world-map-gen = "0.1"

需要支持 Rust 2018 版本的 Rust 编译器。

作为 WebAssembly 库

此库作为 WebAssembly 构建,并以 npm 包 提供。

npm install --save world-map-gen

本包包含优化后的 .wasm 二进制文件,.js JS 文件用于在 Wasm 和 JS 之间连接,以及 .d.ts 类型定义文件,以便使用 TypeScript。

作为命令行工具

请使用 cargo 从源代码构建 CLI 工具。

cargo install world-map-gen

它构建了 ~/.cargo/bin/world-map-gen

用法

Rust 库

Rust 库提供了一些模块,用于将世界地图作为填充有单元格的棋盘进行处理。

  • land:代表棋盘上每个单元格的 land::Land 结构体
  • board:代表一个世界地图的 board::Board 结构体。该结构体可使用 serde_json 进行 JSON 序列化
  • draw:将棋盘绘制到终端或作为 JSON 的辅助工具
  • gen:一个随机世界地图生成器,用于构建 board::Board 结构体。它提供三种分辨率的算法;低、中、高
  • error:可能从地图生成器返回的错误类型

请阅读文档以获取更多详细信息。并且 CLI 代码 是了解使用方法的良好示例。

extern world_map_gen;

use world_map_gen::RandomBoardGen;

// Create generator instance with default random number generator
let mut generator = RandomBoardGen::default();

// Generate 40x40 random world map. Map resolution (low, middle, high) is automatically
// determined by its width and height here.
//   - Low: width and height are less than 15
//   - Middle: width and height are less than 120
//   - High: Otherwise
let board = generator.gen_auto(40, 40);

// Iterate each cells per row
for (i, row) in board.rows().enumerate() {
    println!("Row: {}", i);
    for cell in row {
        // cell is a world_map_gen::land::Land instance

        // Lands are categorized with kind (e.g. Sea, Plain, Forest, Mountain, ...)
        println!("Kind: {:?}", cell.kind);

        // Each cell as its altitude. For example, sea's altitude is lower and mountain's is
        // higher
        println!("Altitude: {}", cell.altitude);
    }
}

WebAssembly 库

www/ 目录是展示如何在 TypeScript 和 WebAssembly 中使用此包的绝佳示例。它托管在 gh-pages

npm 包 包含 world_map_gen.wasmworld_map_gen.jsworld_map_gen.js 是入口点。支持 WebAssembly 的打包器,如 webpack,当你的代码导入 world-map-gen 包时,将正确处理 .wasm 文件。

import { Generator, LandKind } from 'world-map-gen';

// Generate a new random map generator
const gen = Generator.new();

// Generate random 200x200 map
const board = gen.gen(200, 200);

for (let x = 0; x < board.width(); x++) {
    for (let y = 0; y < board.height(); y++) {
        // Get cell of specific position
        const cell = board.at(x, y);

        // Get land kind like Sea, Forest, Mountain, ...
        console.log('Kind:', cell.kind, 'at', x, y);

        // Check the cell is town
        console.log('  town?:', cell.kind === LandKind.Town);

        // Get altitude of the cell
        console.log('  Altitude:', cell.altitude);

        // Get color code of the cell as #rrggbb format
        console.log('  Color:', cell.color_code());

        // Get land legend
        console.log(' Legend:', cell.legend());
    }
}

// Get JSON representation of board
console.log(JSON.parse(board.as_json()))

假设此代码作为文件 index.js 存放。

作为你应用程序的入口点,请确保使用 动态导入。这是必要的,因为所有 .wasm 代码都必须异步导入。

import("./index")
  .catch(e => console.error("Error importing `index.js`:", e));

world-map-gen 包还包含 world_map_gen.d.ts 以便与 TypeScript 一起使用。您无需编写 API 的类型定义。TypeScript 编译器会自动检测 .d.ts 文件。

请确保为 TypeScript 编译器的模块解析使用 esNext。它将 TypeScript 的导入语句转换为 ES 模块,webpack 会在之后处理它们。

{
  "compilerOptions": {
    "module": "esNext",
    // ...
  },
  // ...
}

CLI 工具

请阅读 world-map-gen --help 输出以了解接口。

每个单元格用 ██ 表示。使用 ANSI 256 色为单元格着色。某些终端可能无法正常工作。我正在 iTerm2 上测试此 CLI 工具。

默认情况下,它获取终端的宽度和高度,并使用整个终端屏幕来显示地图。您可能需要临时减小字体大小以显示更大的地图。地图的分辨率默认从宽度和高度自动确定。您可以通过命令行选项指定它们。并且--json以JSON格式输出随机生成的地图。

USAGE:
    world-map-gen [FLAGS] [OPTIONS]

FLAGS:
    -a, --altitude    Show altitude instead of squre as cell mainly for debug
        --help        Prints help information
    -j, --json        Output JSON-serialized result to stdout
    -V, --version     Prints version information

OPTIONS:
    -h, --height <INTEGER>       Board height in number of cells
    -r, --resolution <STRING>    Resolution of world map [possible values: low, middle, high]
    -s, --seed <INTEGER>         Seed for random number generator
    -w, --width <INTEGER>        Board width in number of cells

开发

Makefile为此存储库提供了有用的脚本。

要从浏览器调试Wasm包,请使用wasm-pack--features wasm_debug构建此包。

许可证

MIT许可证下分发。

依赖关系

~1.2–4.5MB
~83K SLoC