Compare commits
24 Commits
b1fd2e5f73
...
v0.7.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 23e4ef3093 | |||
| 235d89ebb3 | |||
| 12c303d0ab | |||
| 03b985ee57 | |||
| 16b118f37d | |||
| 172b528138 | |||
| 70de4bb67d | |||
| ebee953955 | |||
| d2cb75c3a1 | |||
| 099926d368 | |||
| 76426094d3 | |||
| 4b101633e7 | |||
| a5a6f32037 | |||
| 4d899d3c97 | |||
| 6d5afc2445 | |||
| d34d0a31f2 | |||
| 72f062ea10 | |||
| eecfbf5d7c | |||
| 1e09e3ce3a | |||
| 19ac032792 | |||
| de75e25ca6 | |||
| d7802bdbed | |||
| ae093d2c9c | |||
| 3963b548b9 |
@@ -18,7 +18,12 @@ jobs:
|
||||
with:
|
||||
components: rustfmt clippy
|
||||
- name: Install system dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends libasound2-dev libudev-dev
|
||||
run: >
|
||||
sudo apt-get update &&
|
||||
sudo apt-get install -y --no-install-recommends
|
||||
libasound2-dev
|
||||
libudev-dev
|
||||
libwayland-dev
|
||||
- name : cargo generate-lockfile
|
||||
if: hashFiles('Cargo.lock') == ''
|
||||
run: cargo generate-lockfile
|
||||
@@ -41,6 +46,6 @@ jobs:
|
||||
name: roberts-bad-asteroids-game
|
||||
path: target/release/asteroids
|
||||
if-no-files-found: 'error'
|
||||
retention-days: 1
|
||||
retention-days: 7
|
||||
compression-level: 9
|
||||
overwrite: true
|
||||
|
||||
94
.gitea/workflows/check.yml
Normal file
94
.gitea/workflows/check.yml
Normal file
@@ -0,0 +1,94 @@
|
||||
# This workflow runs whenever a PR is opened or updated, or a commit is pushed to main. It runs
|
||||
# several checks:
|
||||
# - fmt: checks that the code is formatted according to rustfmt
|
||||
# - clippy: checks that the code does not contain any clippy warnings
|
||||
# - doc: checks that the code can be documented without errors
|
||||
# - hack: check combinations of feature flags
|
||||
# - msrv: check that the msrv specified in the crate is correct
|
||||
permissions:
|
||||
contents: read
|
||||
# This configuration allows maintainers of this repo to create a branch and pull request based on
|
||||
# the new branch. Restricting the push trigger to the main branch ensures that the PR only gets
|
||||
# built once.
|
||||
on:
|
||||
push:
|
||||
branches: [trunk]
|
||||
pull_request:
|
||||
# If new code is pushed to a PR branch, then cancel in progress workflows for that PR. Ensures that
|
||||
# we don't waste CI time, and returns results quicker https://github.com/jonhoo/rust-ci-conf/pull/5
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
name: check
|
||||
jobs:
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
name: stable / fmt
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Install stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt
|
||||
- name: cargo fmt --check
|
||||
run: cargo fmt --check
|
||||
doc:
|
||||
# run docs generation on nightly rather than stable. This enables features like
|
||||
# https://doc.rust-lang.org/beta/unstable-book/language-features/doc-cfg.html which allows an
|
||||
# API be documented as only available in some specific platforms.
|
||||
runs-on: ubuntu-latest
|
||||
name: nightly / doc
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Install Dependencies
|
||||
run: sudo apt-get update; sudo apt-get install -y --no-install-recommends libasound2-dev libudev-dev libwayland-dev
|
||||
- name: Install nightly
|
||||
uses: dtolnay/rust-toolchain@nightly
|
||||
- name: cargo doc
|
||||
run: cargo doc --no-deps --all-features
|
||||
env:
|
||||
RUSTDOCFLAGS: --cfg docsrs
|
||||
hack:
|
||||
# cargo-hack checks combinations of feature flags to ensure that features are all additive
|
||||
# which is required for feature unification
|
||||
runs-on: ubuntu-latest
|
||||
name: ubuntu / stable / features
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Install Dependencies
|
||||
run: sudo apt-get update; sudo apt-get install -y --no-install-recommends libasound2-dev libudev-dev libwayland-dev cmake
|
||||
- name: Install stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
- name: cargo install cargo-hack
|
||||
uses: taiki-e/install-action@cargo-hack
|
||||
# intentionally no target specifier; see https://github.com/jonhoo/rust-ci-conf/pull/4
|
||||
# --feature-powerset runs for every combination of features
|
||||
- name: cargo hack
|
||||
run: cargo hack --feature-powerset check
|
||||
msrv:
|
||||
# check that we can build using the minimal rust version that is specified by this crate
|
||||
runs-on: ubuntu-latest
|
||||
# we use a matrix here just because env can't be used in job names
|
||||
# https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
|
||||
strategy:
|
||||
matrix:
|
||||
msrv: ["1.88.0"]
|
||||
name: ubuntu / ${{ matrix.msrv }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
- name: Install Dependencies
|
||||
run: sudo apt-get update; sudo apt-get install -y --no-install-recommends libasound2-dev libudev-dev libwayland-dev
|
||||
- name: Install ${{ matrix.msrv }}
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: ${{ matrix.msrv }}
|
||||
- name: cargo +${{ matrix.msrv }} check
|
||||
run: cargo check
|
||||
88
Cargo.lock
generated
88
Cargo.lock
generated
@@ -242,7 +242,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "asteroids"
|
||||
version = "0.6.0-dev2"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"bevy",
|
||||
"bevy-inspector-egui",
|
||||
@@ -302,9 +302,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-lock"
|
||||
version = "3.4.1"
|
||||
version = "3.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc"
|
||||
checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"event-listener-strategy",
|
||||
@@ -1848,9 +1848,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.49"
|
||||
version = "1.2.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215"
|
||||
checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"jobserver",
|
||||
@@ -2194,18 +2194,18 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "2.1.0"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618"
|
||||
checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134"
|
||||
dependencies = [
|
||||
"derive_more-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more-impl"
|
||||
version = "2.1.0"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b"
|
||||
checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
@@ -2491,9 +2491,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
|
||||
checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
@@ -2646,7 +2646,7 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8"
|
||||
dependencies = [
|
||||
"rustix 1.1.2",
|
||||
"rustix 1.1.3",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
@@ -3212,9 +3212,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010"
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
@@ -3661,9 +3661,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
|
||||
checksum = "c70f219e21142367c70c0b30c6a9e3a14d55b4d12a204d897fbec83a0363f081"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
@@ -4289,15 +4289,15 @@ dependencies = [
|
||||
"concurrent-queue",
|
||||
"hermit-abi",
|
||||
"pin-project-lite",
|
||||
"rustix 1.1.2",
|
||||
"rustix 1.1.3",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.11.1"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
|
||||
checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic-util"
|
||||
@@ -4470,9 +4470,9 @@ checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde"
|
||||
|
||||
[[package]]
|
||||
name = "rangemap"
|
||||
version = "1.7.0"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acbbbbea733ec66275512d0b9694f34102e7d5406fdbe2ad8d21b28dce92887c"
|
||||
checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68"
|
||||
|
||||
[[package]]
|
||||
name = "rapier2d"
|
||||
@@ -4660,9 +4660,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.1.2"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
|
||||
checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"errno",
|
||||
@@ -4703,12 +4703,6 @@ dependencies = [
|
||||
"twox-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
|
||||
[[package]]
|
||||
name = "safe_arch"
|
||||
version = "0.7.4"
|
||||
@@ -4802,15 +4796,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.145"
|
||||
version = "1.0.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||
checksum = "6af14725505314343e673e9ecb7cd7e8a36aa9791eb936235a3567cc31447ae4"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5167,9 +5161,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.7.4+spec-1.0.0"
|
||||
version = "0.7.5+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe3cea6b2aa3b910092f6abd4053ea464fab5f9c170ba5e9a6aead16ec4af2b6"
|
||||
checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
@@ -5188,18 +5182,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
version = "1.0.5+spec-1.0.0"
|
||||
version = "1.0.6+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c03bee5ce3696f31250db0bbaff18bc43301ce0e8db2ed1f07cbb2acf89984c"
|
||||
checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44"
|
||||
dependencies = [
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.43"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647"
|
||||
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
@@ -5219,9 +5213,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c"
|
||||
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
@@ -5525,7 +5519,7 @@ checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"downcast-rs 1.2.1",
|
||||
"rustix 1.1.2",
|
||||
"rustix 1.1.3",
|
||||
"scoped-tls",
|
||||
"smallvec",
|
||||
"wayland-sys",
|
||||
@@ -5538,7 +5532,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"rustix 1.1.2",
|
||||
"rustix 1.1.3",
|
||||
"wayland-backend",
|
||||
"wayland-scanner",
|
||||
]
|
||||
@@ -5560,7 +5554,7 @@ version = "0.31.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "447ccc440a881271b19e9989f75726d60faa09b95b0200a9b7eb5cc47c3eeb29"
|
||||
dependencies = [
|
||||
"rustix 1.1.2",
|
||||
"rustix 1.1.3",
|
||||
"wayland-client",
|
||||
"xcursor",
|
||||
]
|
||||
@@ -6474,7 +6468,7 @@ dependencies = [
|
||||
"libc",
|
||||
"libloading",
|
||||
"once_cell",
|
||||
"rustix 1.1.2",
|
||||
"rustix 1.1.3",
|
||||
"x11rb-protocol",
|
||||
]
|
||||
|
||||
@@ -6624,6 +6618,12 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0095ecd462946aa3927d9297b63ef82fb9a5316d7a37d134eeb36e58228615a"
|
||||
|
||||
[[package]]
|
||||
name = "zune-core"
|
||||
version = "0.4.12"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
[package]
|
||||
name = "asteroids"
|
||||
version = "0.6.0-dev2"
|
||||
version = "0.7.0"
|
||||
edition = "2024"
|
||||
license = "AGPL-3.0-only"
|
||||
rust-version = "1.88.0"
|
||||
|
||||
[dependencies]
|
||||
bevy = "0.17"
|
||||
|
||||
25
Makefile
25
Makefile
@@ -3,32 +3,40 @@
|
||||
## Do not use it if that isn't your goal!
|
||||
##
|
||||
|
||||
# # # Configuration Variables # # #
|
||||
#
|
||||
# Patch these to select a different build profile or target
|
||||
# The target shouldn't change any time soon. WASM64, I guess. Other targets
|
||||
# aren't aimed at the web, so you shouldn't be using this makefile.
|
||||
CARGO_TARGET := wasm32-unknown-unknown
|
||||
CARGO_PROFILE := tiny
|
||||
|
||||
# # # Automatic Variables # # #
|
||||
SRC_DIR = ./src
|
||||
SRCS := $(wildcard $(SRC_DIR)/**)
|
||||
|
||||
ASSET_SOURCE := $(wildcard assets/**)
|
||||
ASSETS := $(patsubst assets/%.ogg, out/assets/%.ogg, $(ASSET_SOURCE))
|
||||
|
||||
CRATE_VERSION != sed -nre 's/^version = "(.*)"/\1/p' Cargo.toml
|
||||
|
||||
.PHONY: clean full-clean tarball tarball-standalone web web-standalone
|
||||
|
||||
# "Standalone" version. It includes an index.html to serve as-is
|
||||
web-standalone: out/asteroids.js out/asteroids_bg.wasm.gz out/index.html
|
||||
web-standalone: out/asteroids.js out/asteroids_bg.wasm.gz out/index.html $(ASSETS)
|
||||
|
||||
# "Bundle-able" version. It has a page, but no index.html. Consumers are
|
||||
# expected to provide their own index.html and link to this page.
|
||||
web: out/asteroids.js out/asteroids_bg.wasm.gz out/asteroids.html
|
||||
web: out/asteroids.js out/asteroids_bg.wasm.gz out/asteroids.html $(ASSETS)
|
||||
|
||||
tarball: asteroids_web_root.tar
|
||||
|
||||
tarball_standalone: asteroids_web_root_standalone.tar
|
||||
|
||||
asteroids_web_root.tar: out/asteroids.js out/asteroids_bg.wasm.gz out/asteroids.html
|
||||
asteroids_web_root.tar: out/asteroids.js out/asteroids_bg.wasm.gz out/asteroids.html $(ASSETS)
|
||||
tar -caf $@ $^
|
||||
|
||||
asteroids_web_root_standalone.tar: out/asteroids.js out/asteroids_bg.wasm.gz out/index.html
|
||||
asteroids_web_root_standalone.tar: out/asteroids.js out/asteroids_bg.wasm.gz out/index.html $(ASSETS)
|
||||
tar -caf $@ $^
|
||||
|
||||
target/$(CARGO_TARGET)/$(CARGO_PROFILE)/asteroids.wasm: $(SRCS) Cargo.lock Cargo.toml
|
||||
@@ -37,6 +45,12 @@ target/$(CARGO_TARGET)/$(CARGO_PROFILE)/asteroids.wasm: $(SRCS) Cargo.lock Cargo
|
||||
out:
|
||||
mkdir $@
|
||||
|
||||
out/assets: | out
|
||||
mkdir $@
|
||||
|
||||
out/assets/%.ogg: assets/%.ogg | out/assets
|
||||
cp -ar assets/$*.ogg $@
|
||||
|
||||
# Both the JS and WASM files are generated by the wasm-bindgen call, so both
|
||||
# get to be on the target half of this recipe.
|
||||
out/asteroids.js out/asteroids_bg.wasm.gz &: target/$(CARGO_TARGET)/$(CARGO_PROFILE)/asteroids.wasm | out
|
||||
@@ -47,6 +61,7 @@ out/asteroids.js out/asteroids_bg.wasm.gz &: target/$(CARGO_TARGET)/$(CARGO_PROF
|
||||
out/index.html: www/index.html
|
||||
cp -a $< $@
|
||||
rm -f out/asteroids.html
|
||||
sed -i -e "s/#CRATE_VERSION_PLACEHOLDER#/$(CRATE_VERSION)/" $@
|
||||
|
||||
# Like `out/index.html`, but renames the page for use in a larger site.
|
||||
out/asteroids.html: www/index.html
|
||||
@@ -67,6 +82,8 @@ full-clean: clean
|
||||
# output into the web root. Only supports the "bundle-able" mode.
|
||||
install: web
|
||||
install -dm0755 $(DESTDIR)
|
||||
install -dm0755 $(DESTDIR)/assets
|
||||
install -m0644 out/asteroids.js $(DESTDIR)/
|
||||
install -m0644 out/asteroids_bg.wasm.gz $(DESTDIR)/
|
||||
install -m0644 out/asteroids.html $(DESTDIR)/
|
||||
install -m0644 $(ASSETS) $(DESTDIR)/assets/
|
||||
|
||||
BIN
assets/explosionCrunch_000.ogg
Normal file
BIN
assets/explosionCrunch_000.ogg
Normal file
Binary file not shown.
BIN
assets/laserSmall_001.ogg
Normal file
BIN
assets/laserSmall_001.ogg
Normal file
Binary file not shown.
BIN
assets/thrusterFire_004.ogg
Normal file
BIN
assets/thrusterFire_004.ogg
Normal file
Binary file not shown.
@@ -9,19 +9,21 @@ pub const UI_BUTTON_NORMAL: Color = Color::srgb(0.15, 0.15, 0.15); // Button col
|
||||
pub const UI_BUTTON_HOVERED: Color = Color::srgb(0.25, 0.25, 0.25); // ... when it's hovered
|
||||
pub const UI_BUTTON_PRESSED: Color = Color::srgb(0.55, 0.55, 0.55); // ... when it's pressed
|
||||
|
||||
pub(crate) const BACKGROUND_COLOR: Color = Color::srgb(0.3, 0.3, 0.3);
|
||||
pub(crate) const BACKGROUND_COLOR: Color = Color::srgb(0.1, 0.1, 0.1);
|
||||
pub(crate) const PLAYER_SHIP_COLOR: Color = Color::srgb(1.0, 1.0, 1.0);
|
||||
pub(crate) const SHIP_THRUSTER_COLOR_ACTIVE: Color = Color::srgb(1.0, 0.2, 0.2);
|
||||
pub(crate) const SHIP_THRUSTER_COLOR_INACTIVE: Color = Color::srgb(0.5, 0.5, 0.5);
|
||||
pub(crate) const SHIP_FIRE_RATE: f32 = 3.0; // in bullets-per-second
|
||||
pub(crate) const ASTEROID_SMALL_COLOR: Color = Color::srgb(1.0, 0., 0.);
|
||||
pub(crate) const BULLET_COLOR: Color = Color::srgb(0.0, 0.1, 0.9);
|
||||
pub(crate) const ASTEROID_SMALL_COLOR: Color = Color::srgb(0.9, 0.9, 0.9);
|
||||
pub(crate) const ASTEROID_MEDIUM_COLOR: Color = Color::srgb(0.8, 0.8, 0.8);
|
||||
pub(crate) const ASTEROID_LARGE_COLOR: Color = Color::srgb(0.6, 0.6, 0.6);
|
||||
pub(crate) const BULLET_COLOR: Color = Color::srgb(0.9, 0.9, 0.9);
|
||||
// TODO: asteroid medium & large
|
||||
|
||||
pub(crate) const SHIP_THRUST: f32 = 1.0;
|
||||
pub(crate) const SHIP_THRUST: f32 = 4.0;
|
||||
pub(crate) const SHIP_ROTATION: f32 = 4.0; // +/- rotation speed in... radians per frame
|
||||
|
||||
pub(crate) const BULLET_SPEED: f32 = 150.0;
|
||||
pub(crate) const BULLET_SPEED: f32 = 500.0;
|
||||
pub(crate) const BULLET_LIFETIME: f32 = 2.0;
|
||||
|
||||
pub(crate) const ASTEROID_LIFETIME: f32 = 40.0;
|
||||
|
||||
34
src/lib.rs
34
src/lib.rs
@@ -11,9 +11,9 @@ mod resources;
|
||||
mod widgets;
|
||||
|
||||
use crate::config::{
|
||||
ASTEROID_SMALL_COLOR, BACKGROUND_COLOR, BULLET_COLOR, BULLET_LIFETIME, BULLET_SPEED,
|
||||
PLAYER_SHIP_COLOR, SHIP_ROTATION, SHIP_THRUST, SHIP_THRUSTER_COLOR_ACTIVE,
|
||||
SHIP_THRUSTER_COLOR_INACTIVE,
|
||||
ASTEROID_LARGE_COLOR, ASTEROID_MEDIUM_COLOR, ASTEROID_SMALL_COLOR, BACKGROUND_COLOR,
|
||||
BULLET_COLOR, BULLET_LIFETIME, BULLET_SPEED, PLAYER_SHIP_COLOR, SHIP_ROTATION, SHIP_THRUST,
|
||||
SHIP_THRUSTER_COLOR_ACTIVE, SHIP_THRUSTER_COLOR_INACTIVE,
|
||||
};
|
||||
use crate::machinery::AsteroidSpawner;
|
||||
use crate::objects::{Bullet, Ship, Weapon};
|
||||
@@ -111,14 +111,28 @@ fn spawn_camera(mut commands: Commands) {
|
||||
/// Checks if "W" is pressed and increases velocity accordingly.
|
||||
fn input_ship_thruster(
|
||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||
mut query: Query<(&mut physics::Velocity, &Transform, &mut Children), With<Ship>>,
|
||||
mut query: Query<
|
||||
(
|
||||
&mut physics::Velocity,
|
||||
&Transform,
|
||||
Option<&mut AudioSink>,
|
||||
&mut Children,
|
||||
),
|
||||
With<Ship>,
|
||||
>,
|
||||
mut commands: Commands,
|
||||
game_assets: Res<GameAssets>,
|
||||
) {
|
||||
// TODO: Maybe change for a Single<Ship>> so this only runs for the one ship
|
||||
// buuut... that would silently do nothing if there are 0 or >1 ships, and
|
||||
// I might want to crash on purpose in that case.
|
||||
let Ok((mut velocity, transform, children)) = query.single_mut() else {
|
||||
//
|
||||
// The AudioSink component doesn't exist for just one frame, forcing it to
|
||||
// be an optional system parameter. I'm not sure if I want to guard it with
|
||||
// a check like it does now, or finally switch to using a Single<...> query
|
||||
// parameter. I would lose ship control if the sound sink didn't spawn, but
|
||||
// that should be fine -- any time that fails, more has likely also failed.
|
||||
let Ok((mut velocity, transform, audio, children)) = query.single_mut() else {
|
||||
let count = query.iter().count();
|
||||
panic!("There should be exactly one player ship! Instead, there seems to be {count}.");
|
||||
};
|
||||
@@ -132,10 +146,16 @@ fn input_ship_thruster(
|
||||
commands
|
||||
.entity(*thrusters)
|
||||
.insert(MeshMaterial2d(game_assets.thruster_mat_active()));
|
||||
if let Some(audio) = audio {
|
||||
audio.play();
|
||||
}
|
||||
} else {
|
||||
commands
|
||||
.entity(*thrusters)
|
||||
.insert(MeshMaterial2d(game_assets.thruster_mat_inactive()));
|
||||
if let Some(audio) = audio {
|
||||
audio.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,8 +217,10 @@ fn input_ship_shoot(
|
||||
physics::Velocity(bullet_vel),
|
||||
Mesh2d(game_assets.bullet().0),
|
||||
MeshMaterial2d(game_assets.bullet().1),
|
||||
ship_pos.clone(), // clone ship transform
|
||||
*ship_pos, // clone ship transform
|
||||
Lifetime(Timer::from_seconds(BULLET_LIFETIME, TimerMode::Once)),
|
||||
AudioPlayer::new(game_assets.laser_sound()),
|
||||
PlaybackSettings::ONCE, // `Lifetime` already despawns the entity, so this doesn't need to
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
30
src/main.rs
30
src/main.rs
@@ -1,20 +1,28 @@
|
||||
use bevy::{prelude::*, window::WindowResolution};
|
||||
|
||||
use asteroids::{AsteroidPlugin, config::WINDOW_SIZE};
|
||||
|
||||
#[cfg(feature = "debug_ui")]
|
||||
use bevy_inspector_egui::{bevy_egui::EguiPlugin, quick::WorldInspectorPlugin};
|
||||
#[cfg(feature = "debug_ui")]
|
||||
use bevy_rapier2d::render::RapierDebugRenderPlugin;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||
primary_window: Some(Window {
|
||||
canvas: Some("#game-canvas".to_owned()),
|
||||
resolution: WindowResolution::new(WINDOW_SIZE.0, WINDOW_SIZE.1),
|
||||
..default()
|
||||
}),
|
||||
let mut app = App::new();
|
||||
app.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||
primary_window: Some(Window {
|
||||
canvas: Some("#game-canvas".to_owned()),
|
||||
resolution: WindowResolution::new(WINDOW_SIZE.0, WINDOW_SIZE.1),
|
||||
..default()
|
||||
}))
|
||||
.add_plugins(AsteroidPlugin)
|
||||
.add_plugins(EguiPlugin::default())
|
||||
}),
|
||||
..default()
|
||||
}))
|
||||
.add_plugins(AsteroidPlugin);
|
||||
|
||||
#[cfg(feature = "debug_ui")]
|
||||
app.add_plugins(EguiPlugin::default())
|
||||
.add_plugins(WorldInspectorPlugin::new())
|
||||
.run();
|
||||
.add_plugins(RapierDebugRenderPlugin::default());
|
||||
|
||||
app.run();
|
||||
}
|
||||
|
||||
@@ -83,9 +83,9 @@ pub fn spawn_asteroid(
|
||||
};
|
||||
|
||||
let collider_radius = match spawn.size {
|
||||
AsteroidSize::Small => 10.0,
|
||||
AsteroidSize::Medium => 20.0,
|
||||
AsteroidSize::Large => 40.0,
|
||||
AsteroidSize::Small => 5.0,
|
||||
AsteroidSize::Medium => 10.0,
|
||||
AsteroidSize::Large => 20.0,
|
||||
};
|
||||
|
||||
commands.spawn((
|
||||
@@ -115,6 +115,7 @@ pub fn split_asteroids(
|
||||
mut respawn_events: MessageWriter<SpawnAsteroid>,
|
||||
mut commands: Commands,
|
||||
query: Query<(&Transform, &Asteroid, &Velocity)>,
|
||||
game_assets: Res<GameAssets>,
|
||||
) {
|
||||
for event in destroy_events.read() {
|
||||
if let Ok((transform, rock, velocity)) = query.get(event.0) {
|
||||
@@ -137,6 +138,12 @@ pub fn split_asteroids(
|
||||
// Always despawn the asteroid. New ones (may) be spawned in it's
|
||||
// place, but this one is gone.
|
||||
commands.entity(event.0).despawn();
|
||||
|
||||
// Play a sound for the asteroid exploding
|
||||
commands.spawn((
|
||||
AudioPlayer::new(game_assets.asteroid_crack_sound()),
|
||||
PlaybackSettings::DESPAWN,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,6 +168,12 @@ pub fn spawn_player(mut commands: Commands, game_assets: Res<GameAssets>) {
|
||||
Mesh2d(game_assets.ship().0),
|
||||
MeshMaterial2d(game_assets.ship().1),
|
||||
Transform::default().with_scale(Vec3::new(20.0, 20.0, 20.0)),
|
||||
AudioPlayer::new(game_assets.ship_thruster_sound()),
|
||||
PlaybackSettings {
|
||||
mode: bevy::audio::PlaybackMode::Loop,
|
||||
paused: true,
|
||||
..Default::default()
|
||||
},
|
||||
))
|
||||
.with_child((
|
||||
Mesh2d(game_assets.thruster_mesh()),
|
||||
@@ -225,7 +238,7 @@ pub fn ship_impact_listener(
|
||||
Sparkler::at_interval(0.15),
|
||||
Mesh2d(game_assets.thruster_mesh()), // borrow the thruster mesh for now
|
||||
MeshMaterial2d(game_assets.thruster_mat_active()), // ... and the active thruster material
|
||||
player.0.clone(), // clone the player transform
|
||||
*player.0, // clone the player transform
|
||||
Velocity(vel),
|
||||
));
|
||||
}
|
||||
@@ -237,7 +250,7 @@ pub fn ship_impact_listener(
|
||||
// STEP 5: Play crash sound
|
||||
commands.spawn((
|
||||
AudioPlayer::new(game_assets.wreck_sound()),
|
||||
PlaybackSettings::ONCE,
|
||||
PlaybackSettings::DESPAWN, // despawn this entity when playback ends.
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,29 +111,21 @@ pub fn collision_listener(
|
||||
if *one == *player {
|
||||
if rocks.contains(*two) {
|
||||
// player-asteroid collision
|
||||
dbg!("Writing ShipDestroy event");
|
||||
ship_writer.write(messages::ShipDestroy);
|
||||
} // else, we don't care
|
||||
} else if *two == *player {
|
||||
if rocks.contains(*one) {
|
||||
dbg!("Writing ShipDestroy event");
|
||||
ship_writer.write(messages::ShipDestroy);
|
||||
}
|
||||
} else if *two == *player && rocks.contains(*one) {
|
||||
ship_writer.write(messages::ShipDestroy);
|
||||
}
|
||||
|
||||
// Option 2: Bullet & Asteroid
|
||||
if bullets.contains(*one) {
|
||||
if rocks.contains(*two) {
|
||||
dbg!("Writing AsteroidDestroy & BulletDestroy events");
|
||||
asteroid_writer.write(messages::AsteroidDestroy(*two));
|
||||
bullet_writer.write(messages::BulletDestroy(*one));
|
||||
}
|
||||
} else if rocks.contains(*one) {
|
||||
if bullets.contains(*two) {
|
||||
dbg!("Writing AsteroidDestroy & BulletDestroy events");
|
||||
asteroid_writer.write(messages::AsteroidDestroy(*one));
|
||||
bullet_writer.write(messages::BulletDestroy(*two));
|
||||
}
|
||||
} else if rocks.contains(*one) && bullets.contains(*two) {
|
||||
asteroid_writer.write(messages::AsteroidDestroy(*one));
|
||||
bullet_writer.write(messages::BulletDestroy(*two));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use bevy::{
|
||||
},
|
||||
math::{
|
||||
Vec2,
|
||||
primitives::{Circle, Triangle2d},
|
||||
primitives::{Polyline2d, Segment2d, Triangle2d},
|
||||
},
|
||||
mesh::Mesh,
|
||||
prelude::{Deref, DerefMut, Reflect, ReflectResource},
|
||||
@@ -19,8 +19,9 @@ use bevy_inspector_egui::InspectorOptions;
|
||||
use bevy_inspector_egui::inspector_options::ReflectInspectorOptions;
|
||||
|
||||
use crate::{
|
||||
ASTEROID_SMALL_COLOR, BULLET_COLOR, PLAYER_SHIP_COLOR, SHIP_THRUSTER_COLOR_ACTIVE,
|
||||
SHIP_THRUSTER_COLOR_INACTIVE, config::WINDOW_SIZE,
|
||||
ASTEROID_LARGE_COLOR, ASTEROID_MEDIUM_COLOR, ASTEROID_SMALL_COLOR, BULLET_COLOR,
|
||||
PLAYER_SHIP_COLOR, SHIP_THRUSTER_COLOR_ACTIVE, SHIP_THRUSTER_COLOR_INACTIVE,
|
||||
config::WINDOW_SIZE,
|
||||
};
|
||||
|
||||
#[derive(InspectorOptions, Reflect, Resource, Debug, Deref, Clone, Copy)]
|
||||
@@ -58,7 +59,7 @@ impl Default for WorldSize {
|
||||
pub struct GameAssets {
|
||||
meshes: [Handle<Mesh>; 5],
|
||||
materials: [Handle<ColorMaterial>; 7],
|
||||
sounds: [Handle<AudioSource>; 1],
|
||||
sounds: [Handle<AudioSource>; 4],
|
||||
}
|
||||
|
||||
impl GameAssets {
|
||||
@@ -83,15 +84,15 @@ impl GameAssets {
|
||||
}
|
||||
|
||||
pub fn asteroid_small(&self) -> (Handle<Mesh>, Handle<ColorMaterial>) {
|
||||
(self.meshes[1].clone(), self.materials[1].clone())
|
||||
(self.meshes[1].clone(), self.materials[3].clone())
|
||||
}
|
||||
|
||||
pub fn asteroid_medium(&self) -> (Handle<Mesh>, Handle<ColorMaterial>) {
|
||||
(self.meshes[2].clone(), self.materials[2].clone())
|
||||
(self.meshes[2].clone(), self.materials[4].clone())
|
||||
}
|
||||
|
||||
pub fn asteroid_large(&self) -> (Handle<Mesh>, Handle<ColorMaterial>) {
|
||||
(self.meshes[3].clone(), self.materials[3].clone())
|
||||
(self.meshes[3].clone(), self.materials[5].clone())
|
||||
}
|
||||
|
||||
pub fn bullet(&self) -> (Handle<Mesh>, Handle<ColorMaterial>) {
|
||||
@@ -101,6 +102,18 @@ impl GameAssets {
|
||||
pub fn wreck_sound(&self) -> Handle<AudioSource> {
|
||||
self.sounds[0].clone()
|
||||
}
|
||||
|
||||
pub fn laser_sound(&self) -> Handle<AudioSource> {
|
||||
self.sounds[1].clone()
|
||||
}
|
||||
|
||||
pub fn asteroid_crack_sound(&self) -> Handle<AudioSource> {
|
||||
self.sounds[2].clone()
|
||||
}
|
||||
|
||||
pub fn ship_thruster_sound(&self) -> Handle<AudioSource> {
|
||||
self.sounds[3].clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWorld for GameAssets {
|
||||
@@ -112,10 +125,63 @@ impl FromWorld for GameAssets {
|
||||
Vec2::new(-0.5, 0.45),
|
||||
Vec2::new(-0.5, -0.45),
|
||||
)),
|
||||
world_meshes.add(Circle::new(10.0)),
|
||||
world_meshes.add(Circle::new(20.0)),
|
||||
world_meshes.add(Circle::new(40.0)),
|
||||
world_meshes.add(Circle::new(0.2)),
|
||||
world_meshes.add(Polyline2d::new(
|
||||
[
|
||||
Vec2::new(0.1, 0.0),
|
||||
Vec2::new(0.8, 0.2),
|
||||
Vec2::new(0.8, 0.3),
|
||||
Vec2::new(0.1, 1.0),
|
||||
Vec2::new(-0.5, 1.0),
|
||||
Vec2::new(-0.3, 0.3),
|
||||
Vec2::new(-1.0, 0.3),
|
||||
Vec2::new(-1.0, -0.2),
|
||||
Vec2::new(-0.5, -1.0),
|
||||
Vec2::new(0.1, -0.8),
|
||||
Vec2::new(0.5, -0.9),
|
||||
Vec2::new(1.0, -0.4),
|
||||
Vec2::new(0.1, 0.0),
|
||||
]
|
||||
.into_iter()
|
||||
.map(|vert| vert * 5.0),
|
||||
)),
|
||||
world_meshes.add(Polyline2d::new(
|
||||
[
|
||||
Vec2::new(0.6, 0.3),
|
||||
Vec2::new(1.0, 0.6),
|
||||
Vec2::new(0.6, 1.0),
|
||||
Vec2::new(0.1, 0.8),
|
||||
Vec2::new(-0.4, 1.0),
|
||||
Vec2::new(-1.0, 0.6),
|
||||
Vec2::new(-0.8, -0.1),
|
||||
Vec2::new(-1.0, -0.5),
|
||||
Vec2::new(-0.4, -1.0),
|
||||
Vec2::new(-0.3, -0.7),
|
||||
Vec2::new(0.6, -1.0),
|
||||
Vec2::new(1.0, -0.3),
|
||||
Vec2::new(0.6, 0.3),
|
||||
]
|
||||
.into_iter()
|
||||
.map(|vert| vert * 10.0),
|
||||
)),
|
||||
world_meshes.add(Polyline2d::new(
|
||||
[
|
||||
Vec2::new(1.0, -0.1),
|
||||
Vec2::new(1.0, 0.3),
|
||||
Vec2::new(0.4, 1.0),
|
||||
Vec2::new(-0.2, 1.0),
|
||||
Vec2::new(-0.9, 0.3),
|
||||
Vec2::new(-0.5, 0.1),
|
||||
Vec2::new(-0.9, -0.1),
|
||||
Vec2::new(-0.5, -1.0),
|
||||
Vec2::new(0.0, 0.0),
|
||||
Vec2::new(0.0, -1.0),
|
||||
Vec2::new(0.5, -1.0),
|
||||
Vec2::new(1.0, -0.1),
|
||||
]
|
||||
.into_iter()
|
||||
.map(|vert| vert * 20.0),
|
||||
)),
|
||||
world_meshes.add(Segment2d::new(Vec2::new(-0.1, 0.0), Vec2::new(0.1, 0.0))),
|
||||
];
|
||||
let mut world_materials = world.resource_mut::<Assets<ColorMaterial>>();
|
||||
let materials = [
|
||||
@@ -124,12 +190,17 @@ impl FromWorld for GameAssets {
|
||||
world_materials.add(SHIP_THRUSTER_COLOR_ACTIVE),
|
||||
world_materials.add(ASTEROID_SMALL_COLOR),
|
||||
// TODO: asteroid medium and large colors
|
||||
world_materials.add(ASTEROID_SMALL_COLOR),
|
||||
world_materials.add(ASTEROID_SMALL_COLOR),
|
||||
world_materials.add(ASTEROID_MEDIUM_COLOR),
|
||||
world_materials.add(ASTEROID_LARGE_COLOR),
|
||||
world_materials.add(BULLET_COLOR),
|
||||
];
|
||||
let loader = world.resource_mut::<AssetServer>();
|
||||
let sounds = [loader.load("explosionCrunch_004.ogg")];
|
||||
let sounds = [
|
||||
loader.load("explosionCrunch_004.ogg"),
|
||||
loader.load("laserSmall_001.ogg"),
|
||||
loader.load("explosionCrunch_000.ogg"),
|
||||
loader.load("thrusterFire_004.ogg"),
|
||||
];
|
||||
GameAssets {
|
||||
meshes,
|
||||
materials,
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::{
|
||||
};
|
||||
|
||||
use bevy::{
|
||||
color::palettes::css::{BLACK, DARK_GRAY, GREEN, LIGHT_BLUE, RED, WHITE},
|
||||
color::palettes::css::{BLACK, DARK_GRAY, GREEN, RED, WHITE},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
@@ -180,9 +180,9 @@ fn spawn_get_ready(mut commands: Commands, mut timer: ResMut<ReadySetGoTimer>) {
|
||||
height: Val::Percent(30.),
|
||||
..default()
|
||||
},
|
||||
BackgroundColor(LIGHT_BLUE.into()),
|
||||
BackgroundColor(Color::NONE),
|
||||
children![
|
||||
(Text::new("Get Ready!"), TextColor(BLACK.into())),
|
||||
(Text::new("Get Ready!"), TextColor(WHITE.into())),
|
||||
(
|
||||
CountdownBar,
|
||||
Node {
|
||||
@@ -263,6 +263,7 @@ fn animate_get_ready_widget(
|
||||
/// on the HUD, this system would quit the game. The same will happen for
|
||||
/// returning to the title screen. This should be useful for making a pause
|
||||
/// menu, too.
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn operate_buttons(
|
||||
mut interactions: Query<
|
||||
(
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
margin: auto;
|
||||
padding: 0.5em;
|
||||
}
|
||||
#prestart-controls,
|
||||
canvas {
|
||||
margin-top: 1em;
|
||||
margin-left: auto;
|
||||
@@ -22,6 +23,26 @@
|
||||
border-radius: 8px;
|
||||
background-color: rgb(40%, 40%, 40%);
|
||||
}
|
||||
#prestart-controls {
|
||||
width: 800px;
|
||||
height: 600px;
|
||||
text-align: center;
|
||||
align-content: center;
|
||||
}
|
||||
button {
|
||||
font-size: 20px;
|
||||
text-shadow: 0.2em 0.2em 0px rgba(0, 0, 0, 75%);
|
||||
padding: 1em;
|
||||
border-radius: 2em;
|
||||
border-style: solid;
|
||||
border-color: black;
|
||||
color: rgb(90%, 90%, 90%);
|
||||
background-color: rgb(15%, 15%, 15%);
|
||||
}
|
||||
button:hover {
|
||||
background-color: rgb(25%, 25%, 25%);
|
||||
border-color: rgb(90%, 90%, 90%);
|
||||
}
|
||||
main {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
@@ -41,13 +62,21 @@
|
||||
<h1>
|
||||
Robert's Bad Asteroids Game
|
||||
</h1>
|
||||
<canvas id="game-canvas" width="1280" height="720"></canvas>
|
||||
<!-- <canvas id="game-canvas" width="800" height="600"></canvas> -->
|
||||
<div id="prestart-controls">
|
||||
<button id="gameload-button">Load Game</button>
|
||||
</div>
|
||||
<main>
|
||||
<article>
|
||||
<h2>Description</h2>
|
||||
<p>
|
||||
A (work in progress) version of the Asteroids arcade game.
|
||||
</p>
|
||||
<p>
|
||||
<em>Sound Warning!</em> The game now has sound effects, but there are no controls on the page for changing the
|
||||
volume (including to mute them). You can mute the browser tab by pressing <code>ctrl</code> + <code>m</code>.
|
||||
Proper volume controls are coming soon.
|
||||
</p>
|
||||
</article>
|
||||
<article>
|
||||
<h3>Controls</h3>
|
||||
@@ -89,24 +118,34 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Program Version</td>
|
||||
<!-- This version text is completely unchecked. I'll need to do something about that. -->
|
||||
<td><code>v0.5.0</code></td>
|
||||
<td><code>#CRATE_VERSION_PLACEHOLDER#</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
</article>
|
||||
</main>
|
||||
<script type="module">
|
||||
import init from './asteroids.js'
|
||||
|
||||
let button = document.getElementById("gameload-button");
|
||||
button.onclick = async function loadGame() {
|
||||
console.log("Game Load button was pressed!");
|
||||
let canvas = document.createElement("canvas");
|
||||
// <canvas id="game-canvas" width="800" height="600"></canvas>
|
||||
canvas.setAttribute("id", "game-canvas");
|
||||
canvas.setAttribute("width", "800");
|
||||
canvas.setAttribute("height", "600");
|
||||
button.parentElement.replaceWith(canvas);
|
||||
|
||||
let compressed = await fetch("./asteroids_bg.wasm.gz")
|
||||
let wasm_stream = compressed.body.pipeThrough(new DecompressionStream("gzip"))
|
||||
let blob = await new Response(wasm_stream).blob();
|
||||
|
||||
init(await blob.arrayBuffer()).catch((error) => {
|
||||
if (!error.message.startsWith("Using exceptions for control flow, don't mind me. This isn't actually an error!")) {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
let compressed = await fetch("./asteroids_bg.wasm.gz")
|
||||
let wasm_stream = compressed.body.pipeThrough(new DecompressionStream("gzip"))
|
||||
let blob = await new Response(wasm_stream).blob();
|
||||
|
||||
init(await blob.arrayBuffer()).catch((error) => {
|
||||
if (!error.message.startsWith("Using exceptions for control flow, don't mind me. This isn't actually an error!")) {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user