Compare commits
No commits in common. "main" and "20a14de05d89e9360390542cf86f203e4a24eecc" have entirely different histories.
main
...
20a14de05d
40
.drone.yml
40
.drone.yml
|
@ -1,40 +0,0 @@
|
|||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: test
|
||||
image: rust
|
||||
pull: always
|
||||
commands:
|
||||
- rustup component add clippy rustfmt
|
||||
- cargo fmt --check
|
||||
- cargo test --all-features
|
||||
- cargo clippy --all-features
|
||||
- name: release
|
||||
image: rust
|
||||
pull: always
|
||||
commands:
|
||||
- cargo publish
|
||||
when:
|
||||
event:
|
||||
- tag
|
||||
environment:
|
||||
CARGO_REGISTRY_TOKEN:
|
||||
from_secret: cargo_registry_token
|
||||
- name: discord notification
|
||||
image: appleboy/drone-discord
|
||||
when:
|
||||
status: [success, failure]
|
||||
settings:
|
||||
webhook_id:
|
||||
from_secret: discord_webhook_id
|
||||
webhook_token:
|
||||
from_secret: discord_webhook_token
|
||||
tts: true
|
||||
message: >
|
||||
{{#success build.status}}
|
||||
{{repo.name}} build {{build.number}} succeeded: <{{build.link}}>
|
||||
{{else}}
|
||||
{{repo.name}} build {{build.number}} failed: <{{build.link}}>
|
||||
{{/success}}
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -3,5 +3,4 @@
|
|||
Cargo.lock
|
||||
.vscode/
|
||||
pkg/
|
||||
package-lock.json
|
||||
.DS_Store
|
||||
package-lock.json
|
4
.travis.yml
Normal file
4
.travis.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
language: rust
|
||||
rust:
|
||||
- stable
|
||||
- beta
|
36
CHANGELOG.md
36
CHANGELOG.md
|
@ -1,36 +0,0 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## Version 0.3.0 - 2023-02-22
|
||||
|
||||
### Features
|
||||
|
||||
- Add optional map serialization.
|
||||
|
||||
## Version 0.2.1 - 2023-01-31
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Resolve clippy warnings and add a bounds check.
|
||||
|
||||
## Version 0.2.0 - 2022-08-27
|
||||
|
||||
### Refactor
|
||||
|
||||
- `map.at` now returns `Option<&Tile>` rather than a wall tile when requested coordinates are out-of-bounds.
|
||||
|
||||
## Version 0.1.1 - 2022-03-18
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- More automated release configuration.
|
||||
|
||||
## Version 0.1.0 - 2022-03-18
|
||||
|
||||
### Miscellaneous Tasks
|
||||
|
||||
- Rename crate and set up automated releases.
|
||||
- Remove demo.
|
||||
|
||||
<!-- generated by git-cliff -->
|
20
Cargo.toml
20
Cargo.toml
|
@ -1,20 +1,14 @@
|
|||
[package]
|
||||
name = "here_be_dragons"
|
||||
version = "0.3.0"
|
||||
authors = ["Nolan Darilek <nolan@thewordnerd.info>", "Krzysztof Langner <klangner@gmail.com>"]
|
||||
description = "Map generator for games"
|
||||
name = "mapgen"
|
||||
version = "0.5.2"
|
||||
authors = ["Krzysztof Langner <klangner@gmail.com>"]
|
||||
description = "Map generator for games (dungeons, worlds etc.)"
|
||||
keywords = ["game", "map", "map-generator"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://labs.lightsout.games/projects/here_be_dragons"
|
||||
documentation = "https://docs.rs/here_be_dragons"
|
||||
repository = "https://github.com/klangner/mapgen.rs"
|
||||
homepage = "https://github.com/klangner/mapgen.rs"
|
||||
documentation = "https://docs.rs/mapgen"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
rand = "0.8"
|
||||
serde = { version = "1", optional = true, features = ["derive"]}
|
||||
|
||||
[package.metadata.release]
|
||||
publish = false
|
||||
push = false
|
||||
pre-release-hook = ["git-cliff", "-o", "CHANGELOG.md", "--tag", "{{version}}"]
|
||||
pre-release-commit-message = "Release"
|
||||
|
|
37
README.md
37
README.md
|
@ -1,17 +1,15 @@
|
|||
# Here Be Dragons
|
||||
# Game Map Generator
|
||||
|
||||
[![Crates.io](https://img.shields.io/crates/v/here_be_dragons.svg)](https://crates.io/crates/here_be_dragons)
|
||||
[![here_be_dragons](https://docs.rs/here_be_dragons/badge.svg)](https://docs.rs/here_be_dragons/)
|
||||
[![Build Status](https://travis-ci.org/klangner/mapgen.rs.svg?branch=master)](https://travis-ci.org/klangner/mapgen.rs)
|
||||
[![Crates.io](https://img.shields.io/crates/v/mapgen.svg)](https://crates.io/crates/mapgen)
|
||||
[![mapgen.rs](https://docs.rs/mapgen/badge.svg)](https://docs.rs/mapgen/)
|
||||
|
||||
Generate procedural maps for games.
|
||||
Generate procedural maps for games. [Try it in the browser](https://klangner.github.io/mapgen.rs/) using WebAssembly.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
This crate is based on [mapgen.rs](https://github.com/klangner/mapgen.rs). Thanks to Krzysztof Langner for doing the hard work of implementing the many map generation algorithms this crate includes.
|
||||
|
||||
## Map filters
|
||||
|
||||
This library consists of different map filters which can be combined to create custom map generators.
|
||||
This library consists of different map filters which can be combined to create custom map generator.
|
||||
|
||||
### Implemented filters
|
||||
|
||||
|
@ -31,19 +29,20 @@ This library consists of different map filters which can be combined to create c
|
|||
* [x] Voronoi hive
|
||||
* [ ] Wave Function Collapse
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Add the dependency to your project
|
||||
Add dependency to your project
|
||||
```
|
||||
here_be_dragons = "0.1"
|
||||
mapgen = "0.4"
|
||||
```
|
||||
|
||||
Using single map generator:
|
||||
|
||||
```rust
|
||||
use rand::prelude::*;
|
||||
use here_be_dragons::{Map, MapFilter};
|
||||
use here_be_dragons::filter::CellularAutomata;
|
||||
use mapgen::{Map, MapFilter};
|
||||
use mapgen::filter::CellularAutomata;
|
||||
|
||||
let mut rng = StdRng::seed_from_u64(100);
|
||||
let gen = CellularAutomata::new();
|
||||
|
@ -53,7 +52,7 @@ let map = gen.modify_map(&mut rng, &Map::new(80, 50));
|
|||
Use MapBuilder for chaining map generator and modifiers
|
||||
|
||||
```rust
|
||||
use here_be_dragons::{
|
||||
use mapgen::{
|
||||
MapBuilder,
|
||||
filter::{
|
||||
NoiseGenerator,
|
||||
|
@ -73,11 +72,14 @@ let map = MapBuilder::new(80, 50)
|
|||
.build();
|
||||
```
|
||||
|
||||
For more information check the [docs](https://docs.rs/here_be_dragons).
|
||||
For more information check the [doc](https://docs.rs/mapgen)
|
||||
|
||||
This library is based on the code from the [Roguelike tutorial](https://github.com/thebracket/rustrogueliketutorial). I highly recommend it for learning how to write a Roguelike in Rust.
|
||||
|
||||
## License
|
||||
This library is based on the code from the [Roguelike tutorial](https://github.com/thebracket/rustrogueliketutorial).
|
||||
I highly recommend it for learning how to write Roguelike in Rust.
|
||||
|
||||
|
||||
# License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
|
@ -86,8 +88,9 @@ Licensed under either of
|
|||
|
||||
at your option.
|
||||
|
||||
|
||||
**Contributions**
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
|
||||
dual licensed as above, without any additional terms or conditions.
|
||||
dual licensed as above, without any additional terms or conditions.
|
||||
|
|
60
cliff.toml
60
cliff.toml
|
@ -1,60 +0,0 @@
|
|||
# configuration file for git-cliff (0.1.0)
|
||||
|
||||
[changelog]
|
||||
# changelog header
|
||||
header = """
|
||||
# Changelog\n
|
||||
All notable changes to this project will be documented in this file.\n
|
||||
"""
|
||||
# template for the changelog body
|
||||
# https://tera.netlify.app/docs/#introduction
|
||||
body = """
|
||||
{% if version %}\
|
||||
## Version {{ version | trim_start_matches(pat="v") }} - {{ timestamp | date(format="%Y-%m-%d") }}
|
||||
{% else %}\
|
||||
## Unreleased
|
||||
{% endif %}\
|
||||
{% for group, commits in commits | group_by(attribute="group") %}
|
||||
### {{ group | upper_first }}
|
||||
{% for commit in commits %}
|
||||
- {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}\
|
||||
{% endfor %}
|
||||
{% endfor %}\n
|
||||
"""
|
||||
# remove the leading and trailing whitespace from the template
|
||||
trim = true
|
||||
# changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
|
||||
[git]
|
||||
# parse the commits based on https://www.conventionalcommits.org
|
||||
conventional_commits = true
|
||||
# filter out the commits that are not conventional
|
||||
filter_unconventional = true
|
||||
# regex for parsing and grouping commits
|
||||
commit_parsers = [
|
||||
{ message = "^feat", group = "Features"},
|
||||
{ message = "^fix", group = "Bug Fixes"},
|
||||
{ message = "^doc", group = "Documentation"},
|
||||
{ message = "^perf", group = "Performance"},
|
||||
{ message = "^refactor", group = "Refactor"},
|
||||
{ message = "^style", group = "Styling"},
|
||||
{ message = "^test", group = "Testing"},
|
||||
{ message = "^chore\\(release\\): prepare for", skip = true},
|
||||
{ message = "^chore", group = "Miscellaneous Tasks"},
|
||||
{ body = ".*security", group = "Security"},
|
||||
]
|
||||
# filter out the commits that are not matched by commit parsers
|
||||
filter_commits = false
|
||||
# glob pattern for matching git tags
|
||||
tag_pattern = "v[0-9]*"
|
||||
# regex for skipping tags
|
||||
skip_tags = ""
|
||||
# regex for ignoring tags
|
||||
ignore_tags = ""
|
||||
# sort the tags chronologically
|
||||
date_order = false
|
||||
# sort the commits inside sections by oldest/newest order
|
||||
sort_commits = "oldest"
|
BIN
demo/.DS_Store
vendored
Normal file
BIN
demo/.DS_Store
vendored
Normal file
Binary file not shown.
28
demo/Cargo.toml
Normal file
28
demo/Cargo.toml
Normal file
|
@ -0,0 +1,28 @@
|
|||
[package]
|
||||
name = "mapgen-demo"
|
||||
version = "0.1.2"
|
||||
authors = ["Krzysztof Langner <klangner@gmail.com>"]
|
||||
description = "Map generator demo"
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/klangner/mapgen.rs"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
mapgen = {path=".."}
|
||||
getrandom = { version = "0.2", features = ["js"] }
|
||||
rand = "0.8"
|
||||
wasm-bindgen = "0.2"
|
||||
js-sys = "0.3"
|
||||
|
||||
[dependencies.web-sys]
|
||||
version = "0.3.4"
|
||||
features = [
|
||||
'Document',
|
||||
'Element',
|
||||
'HtmlElement',
|
||||
'Node',
|
||||
'Window',
|
||||
]
|
201
demo/LICENSE-APACHE
Normal file
201
demo/LICENSE-APACHE
Normal file
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2017 Krzysztof Langner
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
18
demo/README.md
Normal file
18
demo/README.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Demo application for mapgen
|
||||
|
||||
## Build the project:
|
||||
|
||||
```
|
||||
wasm-pack build
|
||||
cd www
|
||||
npm run server
|
||||
```
|
||||
|
||||
Deply application
|
||||
```
|
||||
cd www
|
||||
npm run build
|
||||
```
|
||||
|
||||
This app uses:
|
||||
* [Urizen OneBit Tilesets](https://vurmux.itch.io/urizen-onebit-tilesets)
|
BIN
demo/assets/texture/ascii.png
Normal file
BIN
demo/assets/texture/ascii.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
8
demo/assets/texture/ascii.ron
Normal file
8
demo/assets/texture/ascii.ron
Normal file
|
@ -0,0 +1,8 @@
|
|||
#![enable(implicit_some)]
|
||||
|
||||
Grid((
|
||||
texture_width: 320,
|
||||
texture_height: 320,
|
||||
columns: 16,
|
||||
rows: 16,
|
||||
))
|
BIN
demo/assets/texture/basic.png
Normal file
BIN
demo/assets/texture/basic.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
8
demo/assets/texture/basic.ron
Normal file
8
demo/assets/texture/basic.ron
Normal file
|
@ -0,0 +1,8 @@
|
|||
#![enable(implicit_some)]
|
||||
|
||||
Grid((
|
||||
texture_width: 261,
|
||||
texture_height: 261,
|
||||
columns: 20,
|
||||
rows: 20,
|
||||
))
|
203
demo/src/lib.rs
Normal file
203
demo/src/lib.rs
Normal file
|
@ -0,0 +1,203 @@
|
|||
use wasm_bindgen::prelude::*;
|
||||
use web_sys;
|
||||
use rand::prelude::*;
|
||||
use mapgen::{Map, MapBuilder, NoData, geometry::Point};
|
||||
use mapgen::filter::*;
|
||||
use mapgen::metric;
|
||||
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum Cell {
|
||||
Floor = 0,
|
||||
Wall = 1,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct World {
|
||||
width: u32,
|
||||
height: u32,
|
||||
tiles: Vec<Cell>,
|
||||
map: Map<NoData>,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct Position {
|
||||
col: usize,
|
||||
row: usize,
|
||||
}
|
||||
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl World {
|
||||
|
||||
fn new(width: u32, height: u32, map: Map<NoData>) -> World {
|
||||
let tiles = (0..map.tiles.len())
|
||||
.map(|i| if map.tiles[i].is_walkable() {Cell::Floor} else {Cell::Wall})
|
||||
.collect();
|
||||
World { width, height, tiles, map }
|
||||
}
|
||||
|
||||
pub fn new_cellular_automata(width: u32, height: u32, seed: u32) -> World {
|
||||
World::print_map_info(format!("Cellular Automata with the seed: {}", seed));
|
||||
let mut rng = StdRng::seed_from_u64(seed as u64);
|
||||
let map = MapBuilder::new(width as usize, height as usize)
|
||||
.with(NoiseGenerator::uniform())
|
||||
.with(CellularAutomata::new())
|
||||
.with(AreaStartingPosition::new(XStart::CENTER, YStart::CENTER))
|
||||
.with(CullUnreachable::new())
|
||||
.with(DistantExit::new())
|
||||
.build_with_rng(&mut rng);
|
||||
World::print_map_metrics(&map);
|
||||
World::new(width, height, map)
|
||||
}
|
||||
|
||||
pub fn new_simple_rooms(width: u32, height: u32, seed: u32) -> World {
|
||||
World::print_map_info(format!("Simple Rooms with the seed: {}", seed));
|
||||
let mut rng = StdRng::seed_from_u64(seed as u64);
|
||||
let map = MapBuilder::new(width as usize, height as usize)
|
||||
.with(SimpleRooms::new())
|
||||
.with(NearestCorridors::new())
|
||||
.with(AreaStartingPosition::new(XStart::LEFT, YStart::TOP))
|
||||
.with(DistantExit::new())
|
||||
.build_with_rng(&mut rng);
|
||||
World::print_map_metrics(&map);
|
||||
World::new(width, height, map)
|
||||
}
|
||||
|
||||
pub fn new_bsp_rooms(width: u32, height: u32, seed: u32) -> World {
|
||||
World::print_map_info(format!("BSP Rooms with the seed: {}", seed));
|
||||
let mut rng = StdRng::seed_from_u64(seed as u64);
|
||||
let map = MapBuilder::new(width as usize, height as usize)
|
||||
.with(BspRooms::new())
|
||||
.with(NearestCorridors::new())
|
||||
.with(AreaStartingPosition::new(XStart::LEFT, YStart::BOTTOM))
|
||||
.with(DistantExit::new())
|
||||
.build_with_rng(&mut rng);
|
||||
World::print_map_metrics(&map);
|
||||
World::new(width, height, map)
|
||||
}
|
||||
|
||||
pub fn new_bsp_interior(width: u32, height: u32, seed: u32) -> World {
|
||||
World::print_map_info(format!("BSP Interior with the seed: {}", seed));
|
||||
let mut rng = StdRng::seed_from_u64(seed as u64);
|
||||
let map = MapBuilder::new(width as usize, height as usize)
|
||||
.with(BspInterior::new())
|
||||
.with(AreaStartingPosition::new(XStart::CENTER, YStart::CENTER))
|
||||
.with(CullUnreachable::new())
|
||||
.with(DistantExit::new())
|
||||
.build_with_rng(&mut rng);
|
||||
World::print_map_metrics(&map);
|
||||
World::new(width, height, map)
|
||||
}
|
||||
|
||||
pub fn new_drunkard(width: u32, height: u32, seed: u32) -> World {
|
||||
World::print_map_info(format!("Drunkard with the seed: {}", seed));
|
||||
let mut rng = StdRng::seed_from_u64(seed as u64);
|
||||
let map = MapBuilder::new(width as usize, height as usize)
|
||||
.with(DrunkardsWalk::open_halls())
|
||||
.with(AreaStartingPosition::new(XStart::RIGHT, YStart::BOTTOM))
|
||||
.with(CullUnreachable::new())
|
||||
.with(DistantExit::new())
|
||||
.build_with_rng(&mut rng);
|
||||
World::print_map_metrics(&map);
|
||||
World::new(width, height, map)
|
||||
}
|
||||
|
||||
pub fn new_maze(width: u32, height: u32, seed: u32) -> World {
|
||||
World::print_map_info(format!("Maze with the seed: {}", seed));
|
||||
let mut rng = StdRng::seed_from_u64(seed as u64);
|
||||
let map = MapBuilder::new(width as usize, height as usize)
|
||||
.with(MazeBuilder::new())
|
||||
.with(AreaStartingPosition::new(XStart::LEFT, YStart::TOP))
|
||||
.with(DistantExit::new())
|
||||
.build_with_rng(&mut rng);
|
||||
World::print_map_metrics(&map);
|
||||
World::new(width, height, map)
|
||||
}
|
||||
|
||||
pub fn new_voronoi(width: u32, height: u32, seed: u32) -> World {
|
||||
World::print_map_info(format!("Voronoi Hive with the seed: {}", seed));
|
||||
let mut rng = StdRng::seed_from_u64(seed as u64);
|
||||
let map = MapBuilder::new(width as usize, height as usize)
|
||||
.with(VoronoiHive::new())
|
||||
.with(AreaStartingPosition::new(XStart::LEFT, YStart::TOP))
|
||||
.with(DistantExit::new())
|
||||
.build_with_rng(&mut rng);
|
||||
World::print_map_metrics(&map);
|
||||
World::new(width, height, map)
|
||||
}
|
||||
|
||||
pub fn new_random(width: u32, height: u32, seed: u32) -> World {
|
||||
let mut rng = rand::thread_rng();
|
||||
let px = rng.gen::<f32>();
|
||||
if px < 1.0/6.0 {
|
||||
World::new_cellular_automata(width, height, seed)
|
||||
} else if px < 2.0/6.0 {
|
||||
World::new_simple_rooms(width, height, seed)
|
||||
} else if px < 3.0/6.0 {
|
||||
World::new_drunkard(width, height, seed)
|
||||
} else if px < 4.0/6.0 {
|
||||
World::new_bsp_rooms(width, height, seed)
|
||||
} else if px < 5.0/6.0 {
|
||||
World::new_bsp_rooms(width, height, seed)
|
||||
} else {
|
||||
World::new_maze(width, height, seed)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn width(&self) -> u32 {
|
||||
self.width
|
||||
}
|
||||
|
||||
pub fn height(&self) -> u32 {
|
||||
self.height
|
||||
}
|
||||
|
||||
pub fn tiles(&self) -> *const Cell {
|
||||
self.tiles.as_ptr()
|
||||
}
|
||||
|
||||
pub fn player_pos(&self) -> Position {
|
||||
let p = self.map.starting_point.unwrap_or(Point::new(0, 0));
|
||||
Position { col: p.x, row: p.y }
|
||||
}
|
||||
|
||||
pub fn exit_pos(&self) -> Position {
|
||||
let p = self.map.exit_point.unwrap_or(Point::new(0, 0));
|
||||
Position { col: p.x, row: p.y }
|
||||
}
|
||||
|
||||
fn print_map_info(info: String) {
|
||||
let window = web_sys::window().expect("no global `window` exists");
|
||||
let document = window.document().expect("should have a document on window");
|
||||
let div = document.get_element_by_id("map-info").expect("Need div with id: map-info");
|
||||
div.set_inner_html(&info);
|
||||
}
|
||||
|
||||
fn print_map_metrics(map: &Map<NoData>) {
|
||||
let window = web_sys::window().expect("no global `window` exists");
|
||||
let document = window.document().expect("should have a document on window");
|
||||
let div = document.get_element_by_id("map-metrics").expect("Need div with id: map-metrics");
|
||||
let density = metric::density(map);
|
||||
let path_length = metric::path_length(map);
|
||||
let info = format!("Metrics: density: {}, path length: {}", density, path_length);
|
||||
div.set_inner_html(&info);
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Position {
|
||||
pub fn new(col: usize, row: usize) -> Position {
|
||||
Position { col, row }
|
||||
}
|
||||
|
||||
pub fn col(&self) -> usize {
|
||||
self.col
|
||||
}
|
||||
|
||||
pub fn row(&self) -> usize {
|
||||
self.row
|
||||
}
|
||||
}
|
12
demo/src/utils.rs
Normal file
12
demo/src/utils.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
pub fn set_panic_hook() {
|
||||
// When the `console_error_panic_hook` feature is enabled, we can call the
|
||||
// `set_panic_hook` function at least once during initialization, and then
|
||||
// we will get better error messages if our code ever panics.
|
||||
//
|
||||
// For more details see
|
||||
// https://github.com/rustwasm/console_error_panic_hook#readme
|
||||
#[cfg(feature = "console_error_panic_hook")]
|
||||
console_error_panic_hook::set_once();
|
||||
}
|
||||
|
BIN
demo/www/.DS_Store
vendored
Normal file
BIN
demo/www/.DS_Store
vendored
Normal file
Binary file not shown.
4
demo/www/.gitignore
vendored
Normal file
4
demo/www/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
node_modules
|
||||
dist
|
||||
.bin/
|
||||
package-lock.json
|
BIN
demo/www/assets/favicon.ico
Normal file
BIN
demo/www/assets/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
BIN
demo/www/assets/tiles.png
Normal file
BIN
demo/www/assets/tiles.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
5
demo/www/bootstrap.js
vendored
Normal file
5
demo/www/bootstrap.js
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
// A dependency graph that contains any wasm must all be imported
|
||||
// asynchronously. This `bootstrap.js` file does the single async import, so
|
||||
// that no one else needs to worry about it again.
|
||||
import("./index.js")
|
||||
.catch(e => console.error("Error importing `index.js`:", e));
|
71
demo/www/index.html
Normal file
71
demo/www/index.html
Normal file
|
@ -0,0 +1,71 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="icon" type="image/png" href="assets/favicon.ico" />
|
||||
<title>Mapgen demo</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
|
||||
integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
|
||||
<style>
|
||||
body {
|
||||
background-color: lightgrey;
|
||||
}
|
||||
canvas {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<script src="./bootstrap.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#">Mapgen demo</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
|
||||
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="mx-auto" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav">
|
||||
<span class="navbar-text mr-2">Generator</span>
|
||||
<li class="nav-item dropdown">
|
||||
<button class="btn btn-secondary dropdown-toggle mr-2" type="button" id="generatorDropdown"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Random
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="generatorDropdown">
|
||||
<a class="dropdown-item" id="cellular-automata-option">Cellular Automata</a>
|
||||
<a class="dropdown-item" id="simple-rooms-option">Simple Rooms</a>
|
||||
<a class="dropdown-item" id="bsp-rooms-option">BSP Rooms</a>
|
||||
<a class="dropdown-item" id="bsp-interior-option">BSP Interior</a>
|
||||
<a class="dropdown-item" id="drunkard-option">Drunkard Walk</a>
|
||||
<a class="dropdown-item" id="maze-option">Maze</a>
|
||||
<a class="dropdown-item" id="voronoi-option">Voronoi Hive</a>
|
||||
<a class="dropdown-item" id="random-option">Random</a>
|
||||
</div>
|
||||
</li>
|
||||
<span class="navbar-text mr-2">Seed</span>
|
||||
<input class="form-control mr-sm-2 w-25" id="seed" type="search" placeholder="random" aria-label="Seed">
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit" id="refresh">Refresh</button>
|
||||
</ul>
|
||||
</div>
|
||||
<a class="github-button" href="https://github.com/klangner/mapgen.rs" data-icon="octicon-star"
|
||||
aria-label="Star ntkme/github-buttons on GitHub">Star</a>
|
||||
</nav>
|
||||
|
||||
<canvas id="mapgen-canvas"></canvas>
|
||||
<div id="map-info" style="text-align: center"></div>
|
||||
<div id="map-metrics" style="text-align: center"></div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
|
||||
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
|
||||
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"
|
||||
integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||
<script async defer src="https://buttons.github.io/buttons.js"></script>
|
||||
</body>
|
||||
</html>
|
173
demo/www/index.js
Normal file
173
demo/www/index.js
Normal file
|
@ -0,0 +1,173 @@
|
|||
import {Cell, World} from "mapgen-demo";
|
||||
import { memory } from "mapgen-demo/mapgen_demo_bg";
|
||||
|
||||
const CANVAS_SIZE = 750;
|
||||
const GRID_COLS = 80;
|
||||
const GRID_ROWS = 50;
|
||||
const CELL_SIZE = CANVAS_SIZE/GRID_ROWS;
|
||||
const TILE_SIZE = 39;
|
||||
|
||||
// Init canvas
|
||||
const canvas = document.getElementById("mapgen-canvas");
|
||||
canvas.height = CELL_SIZE * GRID_ROWS;
|
||||
canvas.width = CELL_SIZE * GRID_COLS;
|
||||
const ctx = canvas.getContext('2d');
|
||||
// Info box
|
||||
const infoDiv = document.getElementById('map-info');
|
||||
// API to the WASM
|
||||
let world = null;
|
||||
|
||||
// Load tiles bitmap
|
||||
let tiles_image = new Image();
|
||||
tiles_image.src = 'assets/tiles.png';
|
||||
|
||||
// Take provided seed or generate new one
|
||||
function get_seed() {
|
||||
var seed_text = document.getElementById("seed").value;
|
||||
if( seed_text.length > 0) {
|
||||
return Number(seed_text);
|
||||
}
|
||||
return Date.now();
|
||||
}
|
||||
|
||||
|
||||
function setGenerator(e) {
|
||||
document.getElementById("generatorDropdown").innerHTML = e.target.innerText;
|
||||
}
|
||||
|
||||
// Map generators
|
||||
function refreshMap() {
|
||||
var generator_name = document.getElementById("generatorDropdown").innerHTML;
|
||||
|
||||
switch(generator_name){
|
||||
case "Cellular Automata":
|
||||
world = World.new_cellular_automata(GRID_COLS, GRID_ROWS, get_seed());
|
||||
break;
|
||||
|
||||
case "Simple Rooms":
|
||||
world = World.new_simple_rooms(GRID_COLS, GRID_ROWS, get_seed());
|
||||
break;
|
||||
|
||||
case "BSP Rooms":
|
||||
world = World.new_bsp_rooms(GRID_COLS, GRID_ROWS, get_seed());
|
||||
break;
|
||||
|
||||
case "BSP Interior":
|
||||
world = World.new_bsp_interior(GRID_COLS, GRID_ROWS, get_seed());
|
||||
break;
|
||||
|
||||
case "Drunkard Walk":
|
||||
world = World.new_drunkard(GRID_COLS, GRID_ROWS, get_seed());
|
||||
break;
|
||||
|
||||
case "Maze":
|
||||
world = World.new_maze(GRID_COLS, GRID_ROWS, get_seed());
|
||||
break;
|
||||
|
||||
case "Voronoi Hive":
|
||||
world = World.new_voronoi(GRID_COLS, GRID_ROWS, get_seed());
|
||||
break;
|
||||
|
||||
default:
|
||||
world = World.new_random(GRID_COLS, GRID_ROWS, get_seed());
|
||||
}
|
||||
|
||||
requestAnimationFrame(renderLoop);
|
||||
}
|
||||
|
||||
// Main loop
|
||||
function renderLoop() {
|
||||
// universe.tick();
|
||||
drawCells();
|
||||
requestAnimationFrame(renderLoop);
|
||||
};
|
||||
|
||||
const getIndex = (row, column) => {
|
||||
return row * GRID_COLS + column;
|
||||
};
|
||||
|
||||
const is_inner_wall = (tiles, col, row) => {
|
||||
for (let c = Math.max(col - 1, 0); c < Math.min(col + 2, GRID_COLS); c++) {
|
||||
for (let r = Math.max(row - 1, 0); r < Math.min(row + 2, GRID_ROWS); r++) {
|
||||
if ((c != col || r != row) && tiles[getIndex(r, c)] == Cell.Floor) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const draw_tile = (ctx, row, col, tile_type) => {
|
||||
var tile_x = 0;
|
||||
var tile_y = 0;
|
||||
if (tile_type == "floor") {
|
||||
tile_x = 3;
|
||||
tile_y = 2;
|
||||
} else if (tile_type == "wall") {
|
||||
tile_x = 0;
|
||||
tile_y = 3;
|
||||
} else if (tile_type == "player") {
|
||||
tile_x = 0;
|
||||
tile_y = 8;
|
||||
} else if (tile_type == "exit") {
|
||||
tile_x = 10;
|
||||
tile_y = 1;
|
||||
} else {
|
||||
tile_x = 18;
|
||||
tile_y = 0;
|
||||
}
|
||||
|
||||
ctx.drawImage(
|
||||
tiles_image,
|
||||
tile_x * TILE_SIZE + 3,
|
||||
tile_y * TILE_SIZE + 3,
|
||||
TILE_SIZE - 3,
|
||||
TILE_SIZE - 3,
|
||||
col * CELL_SIZE,
|
||||
row * CELL_SIZE,
|
||||
CELL_SIZE,
|
||||
CELL_SIZE);
|
||||
|
||||
}
|
||||
|
||||
const drawCells = () => {
|
||||
const tilesPtr = world.tiles();
|
||||
const tiles = new Uint8Array(memory.buffer, tilesPtr, GRID_COLS * GRID_ROWS);
|
||||
|
||||
// tiles
|
||||
for (let row = 0; row < GRID_ROWS; row++) {
|
||||
for (let col = 0; col < GRID_COLS; col++) {
|
||||
const idx = getIndex(row, col);
|
||||
if (tiles[idx] == Cell.Floor) {
|
||||
draw_tile(ctx, row, col, "floor");
|
||||
} else if (is_inner_wall(tiles, col, row)){
|
||||
draw_tile(ctx, row, col, "inner-wall");
|
||||
} else {
|
||||
draw_tile(ctx, row, col, "wall");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Player position
|
||||
let player = world.player_pos();
|
||||
draw_tile(ctx, player.row(), player.col(), "player");
|
||||
|
||||
// Exit position
|
||||
let exit = world.exit_pos();
|
||||
draw_tile(ctx, exit.row(), exit.col(), "exit");
|
||||
};
|
||||
|
||||
// Connect UI element
|
||||
document.getElementById('cellular-automata-option').addEventListener('click', setGenerator);
|
||||
document.getElementById('simple-rooms-option').addEventListener('click', setGenerator);
|
||||
document.getElementById('bsp-rooms-option').addEventListener('click', setGenerator);
|
||||
document.getElementById('drunkard-option').addEventListener('click', setGenerator);
|
||||
document.getElementById('bsp-interior-option').addEventListener('click', setGenerator);
|
||||
document.getElementById('maze-option').addEventListener('click', setGenerator);
|
||||
document.getElementById('voronoi-option').addEventListener('click', setGenerator);
|
||||
document.getElementById('random-option').addEventListener('click', setGenerator);
|
||||
|
||||
document.getElementById('refresh').addEventListener('click', refreshMap);
|
||||
|
||||
refreshMap();
|
41
demo/www/package.json
Normal file
41
demo/www/package.json
Normal file
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"name": "create-wasm-app",
|
||||
"version": "0.1.0",
|
||||
"description": "create an app to consume rust-generated wasm packages",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
"create-wasm-app": ".bin/create-wasm-app.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack --config webpack.config.js",
|
||||
"server": "webpack-dev-server",
|
||||
"deploy": "gh-pages -d dist"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/rustwasm/create-wasm-app.git"
|
||||
},
|
||||
"keywords": [
|
||||
"webassembly",
|
||||
"wasm",
|
||||
"rust",
|
||||
"webpack"
|
||||
],
|
||||
"author": "Ashley Williams <ashley666ashley@gmail.com>",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"bugs": {
|
||||
"url": "https://github.com/rustwasm/create-wasm-app/issues"
|
||||
},
|
||||
"homepage": "https://github.com/rustwasm/create-wasm-app#readme",
|
||||
"dependencies": {
|
||||
"gh-pages": "^3.1.0",
|
||||
"mapgen-demo": "file:../pkg"
|
||||
},
|
||||
"devDependencies": {
|
||||
"hello-wasm-pack": "^0.1.0",
|
||||
"webpack": "^4.29.3",
|
||||
"webpack-cli": "^3.1.0",
|
||||
"webpack-dev-server": "^3.1.5",
|
||||
"copy-webpack-plugin": "^5.0.0"
|
||||
}
|
||||
}
|
14
demo/www/webpack.config.js
Normal file
14
demo/www/webpack.config.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
entry: "./bootstrap.js",
|
||||
output: {
|
||||
path: path.resolve(__dirname, "../../docs"),
|
||||
filename: "bootstrap.js",
|
||||
},
|
||||
mode: "development",
|
||||
plugins: [
|
||||
new CopyWebpackPlugin(['index.html', { from: 'assets', to: 'assets' }])
|
||||
],
|
||||
};
|
72
docs/0.bootstrap.js
Normal file
72
docs/0.bootstrap.js
Normal file
File diff suppressed because one or more lines are too long
BIN
docs/3450392053799dfed08d.module.wasm
Normal file
BIN
docs/3450392053799dfed08d.module.wasm
Normal file
Binary file not shown.
BIN
docs/3bda724f23e860df0b9c.module.wasm
Normal file
BIN
docs/3bda724f23e860df0b9c.module.wasm
Normal file
Binary file not shown.
BIN
docs/98c7bb1ad7a2b17fcade.module.wasm
Normal file
BIN
docs/98c7bb1ad7a2b17fcade.module.wasm
Normal file
Binary file not shown.
BIN
docs/assets/favicon.ico
Normal file
BIN
docs/assets/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
BIN
docs/assets/tiles.png
Normal file
BIN
docs/assets/tiles.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
348
docs/bootstrap.js
vendored
Normal file
348
docs/bootstrap.js
vendored
Normal file
|
@ -0,0 +1,348 @@
|
|||
/******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // install a JSONP callback for chunk loading
|
||||
/******/ function webpackJsonpCallback(data) {
|
||||
/******/ var chunkIds = data[0];
|
||||
/******/ var moreModules = data[1];
|
||||
/******/
|
||||
/******/
|
||||
/******/ // add "moreModules" to the modules object,
|
||||
/******/ // then flag all "chunkIds" as loaded and fire callback
|
||||
/******/ var moduleId, chunkId, i = 0, resolves = [];
|
||||
/******/ for(;i < chunkIds.length; i++) {
|
||||
/******/ chunkId = chunkIds[i];
|
||||
/******/ if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {
|
||||
/******/ resolves.push(installedChunks[chunkId][0]);
|
||||
/******/ }
|
||||
/******/ installedChunks[chunkId] = 0;
|
||||
/******/ }
|
||||
/******/ for(moduleId in moreModules) {
|
||||
/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
|
||||
/******/ modules[moduleId] = moreModules[moduleId];
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ if(parentJsonpFunction) parentJsonpFunction(data);
|
||||
/******/
|
||||
/******/ while(resolves.length) {
|
||||
/******/ resolves.shift()();
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ };
|
||||
/******/
|
||||
/******/
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // object to store loaded and loading chunks
|
||||
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
||||
/******/ // Promise = chunk loading, 0 = chunk loaded
|
||||
/******/ var installedChunks = {
|
||||
/******/ "main": 0
|
||||
/******/ };
|
||||
/******/
|
||||
/******/
|
||||
/******/
|
||||
/******/ // script path function
|
||||
/******/ function jsonpScriptSrc(chunkId) {
|
||||
/******/ return __webpack_require__.p + "" + chunkId + ".bootstrap.js"
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // object to store loaded and loading wasm modules
|
||||
/******/ var installedWasmModules = {};
|
||||
/******/
|
||||
/******/ function promiseResolve() { return Promise.resolve(); }
|
||||
/******/
|
||||
/******/ var wasmImportObjects = {
|
||||
/******/ "../pkg/mapgen_demo_bg.wasm": function() {
|
||||
/******/ return {
|
||||
/******/ "./mapgen_demo_bg.js": {
|
||||
/******/ "__wbindgen_object_drop_ref": function(p0i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbindgen_object_drop_ref"](p0i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_getRandomValues_c73f06b5ed8b878d": function(p0i32,p1i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_getRandomValues_c73f06b5ed8b878d"](p0i32,p1i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_randomFillSync_5fa0a72035c7bfd9": function(p0i32,p1i32,p2i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_randomFillSync_5fa0a72035c7bfd9"](p0i32,p1i32,p2i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_self_23b14d60c8dbf9da": function() {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_self_23b14d60c8dbf9da"]();
|
||||
/******/ },
|
||||
/******/ "__wbg_static_accessor_MODULE_ff1e47f7076e0ee1": function() {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_static_accessor_MODULE_ff1e47f7076e0ee1"]();
|
||||
/******/ },
|
||||
/******/ "__wbg_require_1dab18ea211c4fa1": function(p0i32,p1i32,p2i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_require_1dab18ea211c4fa1"](p0i32,p1i32,p2i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_crypto_df96f3577c8a9bae": function(p0i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_crypto_df96f3577c8a9bae"](p0i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_msCrypto_331efcdb9be40d7c": function(p0i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_msCrypto_331efcdb9be40d7c"](p0i32);
|
||||
/******/ },
|
||||
/******/ "__wbindgen_is_undefined": function(p0i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbindgen_is_undefined"](p0i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_instanceof_Window_adf3196bdc02b386": function(p0i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_instanceof_Window_adf3196bdc02b386"](p0i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_document_6cc8d0b87c0a99b9": function(p0i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_document_6cc8d0b87c0a99b9"](p0i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_getElementById_0cb6ad9511b1efc0": function(p0i32,p1i32,p2i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_getElementById_0cb6ad9511b1efc0"](p0i32,p1i32,p2i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_setinnerHTML_4ff235db1a3cb4d8": function(p0i32,p1i32,p2i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_setinnerHTML_4ff235db1a3cb4d8"](p0i32,p1i32,p2i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_call_8e95613cc6524977": function(p0i32,p1i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_call_8e95613cc6524977"](p0i32,p1i32);
|
||||
/******/ },
|
||||
/******/ "__wbindgen_object_clone_ref": function(p0i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbindgen_object_clone_ref"](p0i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_newnoargs_f3b8a801d5d4b079": function(p0i32,p1i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_newnoargs_f3b8a801d5d4b079"](p0i32,p1i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_self_07b2f89e82ceb76d": function() {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_self_07b2f89e82ceb76d"]();
|
||||
/******/ },
|
||||
/******/ "__wbg_window_ba85d88572adc0dc": function() {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_window_ba85d88572adc0dc"]();
|
||||
/******/ },
|
||||
/******/ "__wbg_globalThis_b9277fc37e201fe5": function() {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_globalThis_b9277fc37e201fe5"]();
|
||||
/******/ },
|
||||
/******/ "__wbg_global_e16303fe83e1d57f": function() {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_global_e16303fe83e1d57f"]();
|
||||
/******/ },
|
||||
/******/ "__wbg_buffer_49131c283a06686f": function(p0i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_buffer_49131c283a06686f"](p0i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_length_2b13641a9d906653": function(p0i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_length_2b13641a9d906653"](p0i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_new_9b295d24cf1d706f": function(p0i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_new_9b295d24cf1d706f"](p0i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_set_3bb960a9975f3cd2": function(p0i32,p1i32,p2i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_set_3bb960a9975f3cd2"](p0i32,p1i32,p2i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_newwithlength_3c570aeea9a95954": function(p0i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_newwithlength_3c570aeea9a95954"](p0i32);
|
||||
/******/ },
|
||||
/******/ "__wbg_subarray_4eaeb3de00cf1955": function(p0i32,p1i32,p2i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbg_subarray_4eaeb3de00cf1955"](p0i32,p1i32,p2i32);
|
||||
/******/ },
|
||||
/******/ "__wbindgen_throw": function(p0i32,p1i32) {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbindgen_throw"](p0i32,p1i32);
|
||||
/******/ },
|
||||
/******/ "__wbindgen_memory": function() {
|
||||
/******/ return installedModules["../pkg/mapgen_demo_bg.js"].exports["__wbindgen_memory"]();
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/ },
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId]) {
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // This file contains only the entry chunk.
|
||||
/******/ // The chunk loading function for additional chunks
|
||||
/******/ __webpack_require__.e = function requireEnsure(chunkId) {
|
||||
/******/ var promises = [];
|
||||
/******/
|
||||
/******/
|
||||
/******/ // JSONP chunk loading for javascript
|
||||
/******/
|
||||
/******/ var installedChunkData = installedChunks[chunkId];
|
||||
/******/ if(installedChunkData !== 0) { // 0 means "already installed".
|
||||
/******/
|
||||
/******/ // a Promise means "currently loading".
|
||||
/******/ if(installedChunkData) {
|
||||
/******/ promises.push(installedChunkData[2]);
|
||||
/******/ } else {
|
||||
/******/ // setup Promise in chunk cache
|
||||
/******/ var promise = new Promise(function(resolve, reject) {
|
||||
/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject];
|
||||
/******/ });
|
||||
/******/ promises.push(installedChunkData[2] = promise);
|
||||
/******/
|
||||
/******/ // start chunk loading
|
||||
/******/ var script = document.createElement('script');
|
||||
/******/ var onScriptComplete;
|
||||
/******/
|
||||
/******/ script.charset = 'utf-8';
|
||||
/******/ script.timeout = 120;
|
||||
/******/ if (__webpack_require__.nc) {
|
||||
/******/ script.setAttribute("nonce", __webpack_require__.nc);
|
||||
/******/ }
|
||||
/******/ script.src = jsonpScriptSrc(chunkId);
|
||||
/******/
|
||||
/******/ // create error before stack unwound to get useful stacktrace later
|
||||
/******/ var error = new Error();
|
||||
/******/ onScriptComplete = function (event) {
|
||||
/******/ // avoid mem leaks in IE.
|
||||
/******/ script.onerror = script.onload = null;
|
||||
/******/ clearTimeout(timeout);
|
||||
/******/ var chunk = installedChunks[chunkId];
|
||||
/******/ if(chunk !== 0) {
|
||||
/******/ if(chunk) {
|
||||
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
|
||||
/******/ var realSrc = event && event.target && event.target.src;
|
||||
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
|
||||
/******/ error.name = 'ChunkLoadError';
|
||||
/******/ error.type = errorType;
|
||||
/******/ error.request = realSrc;
|
||||
/******/ chunk[1](error);
|
||||
/******/ }
|
||||
/******/ installedChunks[chunkId] = undefined;
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/ var timeout = setTimeout(function(){
|
||||
/******/ onScriptComplete({ type: 'timeout', target: script });
|
||||
/******/ }, 120000);
|
||||
/******/ script.onerror = script.onload = onScriptComplete;
|
||||
/******/ document.head.appendChild(script);
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // Fetch + compile chunk loading for webassembly
|
||||
/******/
|
||||
/******/ var wasmModules = {"0":["../pkg/mapgen_demo_bg.wasm"]}[chunkId] || [];
|
||||
/******/
|
||||
/******/ wasmModules.forEach(function(wasmModuleId) {
|
||||
/******/ var installedWasmModuleData = installedWasmModules[wasmModuleId];
|
||||
/******/
|
||||
/******/ // a Promise means "currently loading" or "already loaded".
|
||||
/******/ if(installedWasmModuleData)
|
||||
/******/ promises.push(installedWasmModuleData);
|
||||
/******/ else {
|
||||
/******/ var importObject = wasmImportObjects[wasmModuleId]();
|
||||
/******/ var req = fetch(__webpack_require__.p + "" + {"../pkg/mapgen_demo_bg.wasm":"98c7bb1ad7a2b17fcade"}[wasmModuleId] + ".module.wasm");
|
||||
/******/ var promise;
|
||||
/******/ if(importObject instanceof Promise && typeof WebAssembly.compileStreaming === 'function') {
|
||||
/******/ promise = Promise.all([WebAssembly.compileStreaming(req), importObject]).then(function(items) {
|
||||
/******/ return WebAssembly.instantiate(items[0], items[1]);
|
||||
/******/ });
|
||||
/******/ } else if(typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
/******/ promise = WebAssembly.instantiateStreaming(req, importObject);
|
||||
/******/ } else {
|
||||
/******/ var bytesPromise = req.then(function(x) { return x.arrayBuffer(); });
|
||||
/******/ promise = bytesPromise.then(function(bytes) {
|
||||
/******/ return WebAssembly.instantiate(bytes, importObject);
|
||||
/******/ });
|
||||
/******/ }
|
||||
/******/ promises.push(installedWasmModules[wasmModuleId] = promise.then(function(res) {
|
||||
/******/ return __webpack_require__.w[wasmModuleId] = (res.instance || res).exports;
|
||||
/******/ }));
|
||||
/******/ }
|
||||
/******/ });
|
||||
/******/ return Promise.all(promises);
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
/******/
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
/******/
|
||||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = function(exports) {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // create a fake namespace object
|
||||
/******/ // mode & 1: value is a module id, require it
|
||||
/******/ // mode & 2: merge all properties of value into the ns
|
||||
/******/ // mode & 4: return value when already ns object
|
||||
/******/ // mode & 8|1: behave like require
|
||||
/******/ __webpack_require__.t = function(value, mode) {
|
||||
/******/ if(mode & 1) value = __webpack_require__(value);
|
||||
/******/ if(mode & 8) return value;
|
||||
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
||||
/******/ var ns = Object.create(null);
|
||||
/******/ __webpack_require__.r(ns);
|
||||
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
||||
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
||||
/******/ return ns;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ function getDefault() { return module['default']; } :
|
||||
/******/ function getModuleExports() { return module; };
|
||||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Object.prototype.hasOwnProperty.call
|
||||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||
/******/
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "";
|
||||
/******/
|
||||
/******/ // on error function for async loading
|
||||
/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; };
|
||||
/******/
|
||||
/******/ // object with all WebAssembly.instance exports
|
||||
/******/ __webpack_require__.w = {};
|
||||
/******/
|
||||
/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
|
||||
/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
|
||||
/******/ jsonpArray.push = webpackJsonpCallback;
|
||||
/******/ jsonpArray = jsonpArray.slice();
|
||||
/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
|
||||
/******/ var parentJsonpFunction = oldJsonpFunction;
|
||||
/******/
|
||||
/******/
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(__webpack_require__.s = "./bootstrap.js");
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ({
|
||||
|
||||
/***/ "./bootstrap.js":
|
||||
/*!**********************!*\
|
||||
!*** ./bootstrap.js ***!
|
||||
\**********************/
|
||||
/*! no static exports found */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
eval("// A dependency graph that contains any wasm must all be imported\n// asynchronously. This `bootstrap.js` file does the single async import, so\n// that no one else needs to worry about it again.\n__webpack_require__.e(/*! import() */ 0).then(__webpack_require__.bind(null, /*! ./index.js */ \"./index.js\"))\n .catch(e => console.error(\"Error importing `index.js`:\", e));\n\n\n//# sourceURL=webpack:///./bootstrap.js?");
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
BIN
docs/f22182091a16774e383e.module.wasm
Normal file
BIN
docs/f22182091a16774e383e.module.wasm
Normal file
Binary file not shown.
BIN
docs/fa6c9d72e1d9a518ed31.module.wasm
Normal file
BIN
docs/fa6c9d72e1d9a518ed31.module.wasm
Normal file
Binary file not shown.
71
docs/index.html
Normal file
71
docs/index.html
Normal file
|
@ -0,0 +1,71 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="icon" type="image/png" href="assets/favicon.ico" />
|
||||
<title>Mapgen demo</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
|
||||
integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
|
||||
<style>
|
||||
body {
|
||||
background-color: lightgrey;
|
||||
}
|
||||
canvas {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<script src="./bootstrap.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a class="navbar-brand" href="#">Mapgen demo</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
|
||||
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="mx-auto" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav">
|
||||
<span class="navbar-text mr-2">Generator</span>
|
||||
<li class="nav-item dropdown">
|
||||
<button class="btn btn-secondary dropdown-toggle mr-2" type="button" id="generatorDropdown"
|
||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Random
|
||||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="generatorDropdown">
|
||||
<a class="dropdown-item" id="cellular-automata-option">Cellular Automata</a>
|
||||
<a class="dropdown-item" id="simple-rooms-option">Simple Rooms</a>
|
||||
<a class="dropdown-item" id="bsp-rooms-option">BSP Rooms</a>
|
||||
<a class="dropdown-item" id="bsp-interior-option">BSP Interior</a>
|
||||
<a class="dropdown-item" id="drunkard-option">Drunkard Walk</a>
|
||||
<a class="dropdown-item" id="maze-option">Maze</a>
|
||||
<a class="dropdown-item" id="voronoi-option">Voronoi Hive</a>
|
||||
<a class="dropdown-item" id="random-option">Random</a>
|
||||
</div>
|
||||
</li>
|
||||
<span class="navbar-text mr-2">Seed</span>
|
||||
<input class="form-control mr-sm-2 w-25" id="seed" type="search" placeholder="random" aria-label="Seed">
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit" id="refresh">Refresh</button>
|
||||
</ul>
|
||||
</div>
|
||||
<a class="github-button" href="https://github.com/klangner/mapgen.rs" data-icon="octicon-star"
|
||||
aria-label="Star ntkme/github-buttons on GitHub">Star</a>
|
||||
</nav>
|
||||
|
||||
<canvas id="mapgen-canvas"></canvas>
|
||||
<div id="map-info" style="text-align: center"></div>
|
||||
<div id="map-metrics" style="text-align: center"></div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
|
||||
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
|
||||
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"
|
||||
integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
||||
<script async defer src="https://buttons.github.io/buttons.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,4 +1,4 @@
|
|||
use here_be_dragons::*;
|
||||
use mapgen::*;
|
||||
use rand::prelude::*;
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use here_be_dragons::*;
|
||||
use mapgen::*;
|
||||
use rand::prelude::*;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use here_be_dragons::{
|
||||
use mapgen::{
|
||||
filter::{
|
||||
AreaStartingPosition, CellularAutomata, CullUnreachable, NoiseGenerator, XStart, YStart,
|
||||
},
|
||||
|
@ -16,8 +16,8 @@ impl MapFilter<MyData> for IncrementData {
|
|||
fn modify_map(
|
||||
&self,
|
||||
_rng: &mut rand::prelude::StdRng,
|
||||
map: &here_be_dragons::Map<MyData>,
|
||||
) -> here_be_dragons::Map<MyData> {
|
||||
map: &mapgen::Map<MyData>,
|
||||
) -> mapgen::Map<MyData> {
|
||||
let mut map = map.clone();
|
||||
map.data.value += 1;
|
||||
map
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use here_be_dragons::{
|
||||
use mapgen::{
|
||||
filter::{
|
||||
AreaStartingPosition, CellularAutomata, CullUnreachable, NoiseGenerator, XStart, YStart,
|
||||
},
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
//! ---
|
||||
//! use rand::prelude::*;
|
||||
//! use crate::common::geometry::Point;
|
||||
//! use here_be_dragons::dungeon::{
|
||||
//! use mapgen::dungeon::{
|
||||
//! MapModifier,
|
||||
//! map::{Map, TileType},
|
||||
//! starting_point::{AreaStartingPosition, XStart, YStart}
|
||||
|
@ -63,7 +63,7 @@ impl<D: Clone + Default> DijkstraMap<D> {
|
|||
/// WARNING: Will give incorrect results when used with non-uniform exit costs. Much slower
|
||||
/// algorithm required to support that.
|
||||
fn build(&mut self, map: &Map<D>) {
|
||||
let mapsize = self.size_x * self.size_y;
|
||||
let mapsize: usize = (self.size_x * self.size_y) as usize;
|
||||
let mut open_list: VecDeque<((usize, usize), f32)> = VecDeque::with_capacity(mapsize);
|
||||
|
||||
if let Some(pos) = map.starting_point {
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
//! Example generator usage:
|
||||
//! ```
|
||||
//! use rand::prelude::*;
|
||||
//! use here_be_dragons::{Map, MapFilter, NoData};
|
||||
//! use here_be_dragons::filter::{
|
||||
//! use mapgen::{Map, MapFilter, NoData};
|
||||
//! use mapgen::filter::{
|
||||
//! BspInterior
|
||||
//! };
|
||||
//!
|
||||
|
@ -130,12 +130,12 @@ mod tests {
|
|||
let gen = BspInterior::<NoData>::new();
|
||||
let map = gen.modify_map(&mut rng, &Map::new(80, 50));
|
||||
for i in 0..80 {
|
||||
assert!(map.at(i, 0).unwrap().is_blocked());
|
||||
assert!(map.at(i, 49).unwrap().is_blocked());
|
||||
assert!(map.at(i, 0).is_blocked());
|
||||
assert!(map.at(i, 49).is_blocked());
|
||||
}
|
||||
for j in 0..50 {
|
||||
assert!(map.at(0, j).unwrap().is_blocked());
|
||||
assert!(map.at(79, j).unwrap().is_blocked());
|
||||
assert!(map.at(0, j).is_blocked());
|
||||
assert!(map.at(79, j).is_blocked());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
//! Example generator usage:
|
||||
//! ```
|
||||
//! use rand::prelude::*;
|
||||
//! use here_be_dragons::{Map, MapFilter, NoData};
|
||||
//! use here_be_dragons::filter::BspRooms;
|
||||
//! use mapgen::{Map, MapFilter, NoData};
|
||||
//! use mapgen::filter::BspRooms;
|
||||
//!
|
||||
//! let mut rng = StdRng::seed_from_u64(100);
|
||||
//! let gen = BspRooms::<NoData>::new();
|
||||
|
@ -110,8 +110,8 @@ impl<D: Clone + Default> BspRooms<D> {
|
|||
let rect_width = rect.width();
|
||||
let rect_height = rect.height();
|
||||
|
||||
let w = usize::max(3, rng.random_range(1, usize::min(rect_width, 20))) + 1;
|
||||
let h = usize::max(3, rng.random_range(1, usize::min(rect_height, 20))) + 1;
|
||||
let w = usize::max(3, rng.random_range(1, usize::min(rect_width as usize, 20))) + 1;
|
||||
let h = usize::max(3, rng.random_range(1, usize::min(rect_height as usize, 20))) + 1;
|
||||
|
||||
result.x1 += rng.random_range(0, 6);
|
||||
result.y1 += rng.random_range(0, 6);
|
||||
|
@ -150,12 +150,8 @@ impl<D: Clone + Default> BspRooms<D> {
|
|||
if y < 1 {
|
||||
can_build = false;
|
||||
}
|
||||
if can_build {
|
||||
if let Some(tile) = map.at(x, y) {
|
||||
if tile.is_walkable() {
|
||||
can_build = false;
|
||||
}
|
||||
}
|
||||
if can_build && map.at(x as usize, y as usize).is_walkable() {
|
||||
can_build = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -178,12 +174,12 @@ mod tests {
|
|||
let gen = BspRooms::<NoData>::new();
|
||||
let map = gen.modify_map(&mut rng, &Map::new(80, 50));
|
||||
for i in 0..80 {
|
||||
assert!(map.at(i, 0).unwrap().is_blocked());
|
||||
assert!(map.at(i, 49).unwrap().is_blocked());
|
||||
assert!(map.at(i, 0).is_blocked());
|
||||
assert!(map.at(i, 49).is_blocked());
|
||||
}
|
||||
for j in 0..50 {
|
||||
assert!(map.at(0, j).unwrap().is_blocked());
|
||||
assert!(map.at(79, j).unwrap().is_blocked());
|
||||
assert!(map.at(0, j).is_blocked());
|
||||
assert!(map.at(79, j).is_blocked());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
//! Example usage:
|
||||
//! ```
|
||||
//! use rand::prelude::*;
|
||||
//! use here_be_dragons::{Map, MapFilter, NoData};
|
||||
//! use here_be_dragons::filter::CellularAutomata;
|
||||
//! use mapgen::{Map, MapFilter, NoData};
|
||||
//! use mapgen::filter::CellularAutomata;
|
||||
//!
|
||||
//! let mut rng = StdRng::seed_from_u64(100);
|
||||
//! let gen = CellularAutomata::<NoData>::new();
|
||||
|
@ -76,7 +76,7 @@ fn apply_iteration<D: Clone + Default>(map: &Map<D>) -> Map<D> {
|
|||
];
|
||||
let neighbors = idxs
|
||||
.iter()
|
||||
.filter(|(x, y)| map.at(*x, *y).unwrap().is_blocked())
|
||||
.filter(|(x, y)| map.at(*x, *y).is_blocked())
|
||||
.count();
|
||||
|
||||
if neighbors > 4 || neighbors == 0 {
|
||||
|
@ -103,7 +103,7 @@ mod tests {
|
|||
fn test_iteration_wal() {
|
||||
let map = Map::<NoData>::new(3, 3);
|
||||
let new_map = apply_iteration(&map);
|
||||
assert!(new_map.at(1, 1).unwrap().is_blocked());
|
||||
assert!(new_map.at(1, 1).is_blocked());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -115,6 +115,6 @@ mod tests {
|
|||
}
|
||||
}
|
||||
let new_map = apply_iteration(&map);
|
||||
assert!(new_map.at(1, 1).unwrap().is_walkable());
|
||||
assert!(new_map.at(1, 1).is_walkable());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! Example generator usage:
|
||||
//! ```
|
||||
//! use rand::prelude::*;
|
||||
//! use here_be_dragons::{Map, MapFilter, NoData};
|
||||
//! use here_be_dragons::filter::DrunkardsWalk;
|
||||
//! use mapgen::{Map, MapFilter, NoData};
|
||||
//! use mapgen::filter::DrunkardsWalk;
|
||||
//!
|
||||
//! let mut rng = StdRng::seed_from_u64(100);
|
||||
//! let gen = DrunkardsWalk::<NoData>::open_area();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! Example generator usage:
|
||||
//! ```
|
||||
//! use rand::prelude::*;
|
||||
//! use here_be_dragons::{Map, MapFilter, NoData};
|
||||
//! use here_be_dragons::filter::MazeBuilder;
|
||||
//! use mapgen::{Map, MapFilter, NoData};
|
||||
//! use mapgen::filter::MazeBuilder;
|
||||
//!
|
||||
//! let mut rng = StdRng::seed_from_u64(100);
|
||||
//! let gen = MazeBuilder::<NoData>::new();
|
||||
|
@ -160,7 +160,7 @@ impl<'a, D: Clone + Default> Grid<'a, D> {
|
|||
if neighbors.len() == 1 {
|
||||
return Some(neighbors[0]);
|
||||
} else {
|
||||
return Some(neighbors[(self.rng.roll_dice(1, neighbors.len()) - 1)]);
|
||||
return Some(neighbors[(self.rng.roll_dice(1, neighbors.len()) - 1) as usize]);
|
||||
}
|
||||
}
|
||||
None
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
//! Example usage:
|
||||
//! ```
|
||||
//! use rand::prelude::*;
|
||||
//! use here_be_dragons::{Map, MapFilter, NoData};
|
||||
//! use here_be_dragons::filter::NoiseGenerator;
|
||||
//! use mapgen::{Map, MapFilter, NoData};
|
||||
//! use mapgen::filter::NoiseGenerator;
|
||||
//!
|
||||
//! let mut rng = StdRng::seed_from_u64(100);
|
||||
//! let gen = NoiseGenerator::<NoData>::uniform();
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
//! Example generator usage:
|
||||
//! ```
|
||||
//! use rand::prelude::*;
|
||||
//! use here_be_dragons::{MapFilter, Map, NoData};
|
||||
//! use here_be_dragons::filter::SimpleRooms;
|
||||
//! use mapgen::{MapFilter, Map, NoData};
|
||||
//! use mapgen::filter::SimpleRooms;
|
||||
//!
|
||||
//! let mut rng = StdRng::seed_from_u64(100);
|
||||
//! let gen = SimpleRooms::<NoData>::new();
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
//! Example modifier usage:
|
||||
//! ```
|
||||
//! use rand::prelude::*;
|
||||
//! use here_be_dragons::{MapFilter, Map, NoData, Tile};
|
||||
//! use here_be_dragons::filter::starting_point::{AreaStartingPosition, XStart, YStart};
|
||||
//! use here_be_dragons::geometry::Point;
|
||||
//! use mapgen::{MapFilter, Map, NoData, Tile};
|
||||
//! use mapgen::filter::starting_point::{AreaStartingPosition, XStart, YStart};
|
||||
//! use mapgen::geometry::Point;
|
||||
//!
|
||||
//! let mut rng = StdRng::seed_from_u64(100);
|
||||
//! let mut map = Map::<NoData>::new(80, 50);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! Example generator usage:
|
||||
//! ```
|
||||
//! use rand::prelude::*;
|
||||
//! use here_be_dragons::{Map, MapFilter, NoData};
|
||||
//! use here_be_dragons::filter::VoronoiHive;
|
||||
//! use mapgen::{Map, MapFilter, NoData};
|
||||
//! use mapgen::filter::VoronoiHive;
|
||||
//!
|
||||
//! let mut rng = StdRng::seed_from_u64(100);
|
||||
//! let gen = VoronoiHive::<NoData>::new();
|
||||
|
@ -47,7 +47,7 @@ impl<D: Clone + Default> VoronoiHive<D> {
|
|||
let seeds = self.generate_seeds(rng, map.width, map.height);
|
||||
|
||||
let mut voronoi_distance = vec![(0, 0.0f32); self.n_seeds];
|
||||
let mut voronoi_membership: Vec<i32> = vec![0; map.width * map.height];
|
||||
let mut voronoi_membership: Vec<i32> = vec![0; map.width as usize * map.height as usize];
|
||||
for (i, vid) in voronoi_membership.iter_mut().enumerate() {
|
||||
let x = i % map.width;
|
||||
let y = i / map.width;
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
//! Support function for 2D geometry
|
||||
//!
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Position on the map
|
||||
#[derive(Default, PartialEq, Copy, Clone, Debug, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
pub struct Point {
|
||||
pub x: usize,
|
||||
pub y: usize,
|
||||
|
@ -33,7 +29,6 @@ impl Point {
|
|||
|
||||
/// Rectangle region on the map
|
||||
#[derive(Hash, PartialEq, Eq, Copy, Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
pub struct Rect {
|
||||
pub x1: usize,
|
||||
pub x2: usize,
|
||||
|
@ -89,7 +84,7 @@ impl Rect {
|
|||
/// Calculate abs value between 2 usize values
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use here_be_dragons::geometry::usize_abs;
|
||||
/// use mapgen::geometry::usize_abs;
|
||||
///
|
||||
/// assert_eq!(usize_abs(5, 3), 2);
|
||||
/// assert_eq!(usize_abs(3, 5), 2);
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
//!
|
||||
//! Example
|
||||
//! ```
|
||||
//! use here_be_dragons::{MapFilter, MapBuilder, Map, NoData, Tile};
|
||||
//! use here_be_dragons::filter::{
|
||||
//! use mapgen::{MapFilter, MapBuilder, Map, NoData, Tile};
|
||||
//! use mapgen::filter::{
|
||||
//! NoiseGenerator,
|
||||
//! CellularAutomata,
|
||||
//! starting_point::{AreaStartingPosition, XStart, YStart}
|
||||
//! };
|
||||
//! use here_be_dragons::geometry::Point;
|
||||
//! use mapgen::geometry::Point;
|
||||
//!
|
||||
//! let map = MapBuilder::<NoData>::new(80, 50)
|
||||
//! .with(NoiseGenerator::uniform())
|
||||
|
|
54
src/map.rs
54
src/map.rs
|
@ -7,15 +7,10 @@
|
|||
//! specific game.
|
||||
//!
|
||||
|
||||
use super::geometry::{usize_abs, Point, Rect};
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::geometry::{usize_abs, Point, Rect};
|
||||
|
||||
#[derive(PartialEq, Copy, Clone, Debug, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
pub struct Tile {
|
||||
is_blocked: bool,
|
||||
index: usize,
|
||||
|
@ -35,7 +30,6 @@ pub struct NoData;
|
|||
|
||||
/// Map data
|
||||
#[derive(Default, Clone)]
|
||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||
pub struct Map<D: Clone + Default> {
|
||||
pub tiles: Vec<Tile>,
|
||||
pub width: usize,
|
||||
|
@ -118,12 +112,12 @@ impl<D: Clone + Default> Map<D> {
|
|||
}
|
||||
|
||||
/// Get TileType at the given location
|
||||
pub fn at(&self, x: usize, y: usize) -> Option<&Tile> {
|
||||
if x < self.width && y < self.height {
|
||||
let idx = y * self.width + x;
|
||||
self.tiles.get(idx)
|
||||
pub fn at(&self, x: usize, y: usize) -> Tile {
|
||||
if x >= self.width || y >= self.height {
|
||||
Tile::wall()
|
||||
} else {
|
||||
None
|
||||
let idx = (y as usize) * self.width + (x as usize);
|
||||
self.tiles[idx]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,17 +158,13 @@ impl<D: Clone + Default> Map<D> {
|
|||
|
||||
// Check if given tile can be accessed
|
||||
fn is_exit_valid(&self, x: usize, y: usize) -> bool {
|
||||
if let Some(tile) = self.at(x, y) {
|
||||
!tile.is_blocked
|
||||
} else {
|
||||
false
|
||||
}
|
||||
!self.at(x, y).is_blocked
|
||||
}
|
||||
|
||||
/// Modify tile at the given location
|
||||
pub fn set_tile(&mut self, x: usize, y: usize, tile: Tile) {
|
||||
if x < self.width && y < self.height {
|
||||
let idx = self.xy_idx(x, y);
|
||||
let idx = self.xy_idx(x as usize, y as usize);
|
||||
self.tiles[idx] = tile;
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +178,7 @@ impl<D: Clone + Default> Map<D> {
|
|||
pub fn add_room(&mut self, rect: Rect) {
|
||||
for x in rect.x1..rect.x2 {
|
||||
for y in rect.y1..rect.y2 {
|
||||
self.set_tile(x, y, Tile::floor());
|
||||
self.set_tile(x as usize, y as usize, Tile::floor());
|
||||
}
|
||||
}
|
||||
self.rooms.push(rect);
|
||||
|
@ -210,11 +200,9 @@ impl<D: Clone + Default> Map<D> {
|
|||
y -= 1;
|
||||
}
|
||||
|
||||
if let Some(tile) = self.at(x, y) {
|
||||
if tile.is_blocked {
|
||||
corridor.push(Point::new(x, y));
|
||||
self.set_tile(x, y, Tile::floor());
|
||||
}
|
||||
if self.at(x, y).is_blocked {
|
||||
corridor.push(Point::new(x, y));
|
||||
self.set_tile(x, y, Tile::floor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -286,10 +274,10 @@ impl<D: Clone + Default> fmt::Display for Map<D> {
|
|||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
for y in 0..self.height {
|
||||
let bytes: Vec<u8> = (0..self.width)
|
||||
.map(|x| if self.at(x, y).unwrap().is_blocked { '#' } else { ' ' } as u8)
|
||||
.map(|x| if self.at(x, y).is_blocked { '#' } else { ' ' } as u8)
|
||||
.collect();
|
||||
let line = String::from_utf8(bytes).expect("Can't convert map to string");
|
||||
let _ = writeln!(f, "{line}");
|
||||
let _ = writeln!(f, "{}", line);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -307,7 +295,7 @@ mod tests {
|
|||
let map = Map::<NoData>::new(10, 10);
|
||||
for i in 0..10 {
|
||||
for j in 0..10 {
|
||||
assert!(map.at(i, j).unwrap().is_blocked);
|
||||
assert!(map.at(i, j).is_blocked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -324,12 +312,12 @@ mod tests {
|
|||
assert_eq!(map.width, 10);
|
||||
assert_eq!(map.height, 3);
|
||||
for i in 0..10 {
|
||||
assert!(map.at(i, 0).unwrap().is_blocked);
|
||||
assert!(map.at(i, 2).unwrap().is_blocked);
|
||||
assert!(map.at(i, 0).is_blocked);
|
||||
assert!(map.at(i, 2).is_blocked);
|
||||
if i == 0 || i == 9 {
|
||||
assert!(map.at(i, 1).unwrap().is_blocked);
|
||||
assert!(map.at(i, 1).is_blocked);
|
||||
} else {
|
||||
assert!(map.at(i, 1).unwrap().is_walkable());
|
||||
assert!(map.at(i, 1).is_walkable());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -355,9 +343,9 @@ mod tests {
|
|||
for x in 0..map.width {
|
||||
for y in 0..map.height {
|
||||
if x == 0 || y == 0 || x == 4 || y == 4 {
|
||||
assert!(map.at(x, y).unwrap().is_blocked);
|
||||
assert!(map.at(x, y).is_blocked);
|
||||
} else {
|
||||
assert!(map.at(x, y).unwrap().is_walkable());
|
||||
assert!(map.at(x, y).is_walkable());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user