16 Commits

Author SHA1 Message Date
23e4ef3093 Release v0.7.0
Some checks failed
Basic checks / Basic build-and-test supertask (push) Has been cancelled
check / nightly / doc (push) Has been cancelled
check / ubuntu / stable / features (push) Has been cancelled
check / ubuntu / 1.88.0 (push) Has been cancelled
check / stable / fmt (push) Has been cancelled
2025-12-26 10:35:45 -06:00
235d89ebb3 Automatically fill version info in index.html 2025-12-26 10:34:45 -06:00
12c303d0ab Pull in the check workflow from my Boids repo
Some checks failed
Basic checks / Basic build-and-test supertask (push) Has been cancelled
check / nightly / doc (push) Has been cancelled
check / ubuntu / stable / features (push) Has been cancelled
check / ubuntu / 1.88.0 (push) Has been cancelled
check / stable / fmt (push) Has been cancelled
Which is, in turn, something Jonhoo put together. See the comments in
the file for more.

I mainly want the feature combination checking that this should do.
2025-12-25 23:39:25 -06:00
03b985ee57 Record MSRV in Cargo.toml (currently 1.88) 2025-12-25 23:39:11 -06:00
16b118f37d Update basic.yml workflow for Bevy 0.17
This thing has been broken since a48dfc1d65 (v0.5.0 + 1) when the game
was upgraded to Bevy 0.17. Install the libwayland-dev package to get the
CI runner building correctly again.

I also increased the artifact retention period to 7 days... I'm not sure
I actually want to keep any artifacts, but if I'm going to then I should
keep them long enough for me to go back and look at them.
2025-12-25 23:35:20 -06:00
172b528138 Mark v0.6.2 release: Removed debug noise
Some checks failed
Basic checks / Basic build-and-test supertask (push) Failing after 1m10s
I've removed a bit of the debug stuff from the program -- mainly the
egui-inspector UI, but also some debug prints that were still happening
in the physics module.
2025-12-22 10:41:52 -06:00
70de4bb67d Remove debug prints in physics.rs 2025-12-22 10:39:40 -06:00
ebee953955 Hide egui-inspector window behind feature flag
The World Inspector widget shouldn't be enabled by default. This hides
it behind the "debug_ui" feature flag, along with the bevy_rapier2d
debug drawings.

The bevy_rapier2d debug plugin is now added when in debug mode, which
was not previously the case.
2025-12-21 16:45:52 -06:00
d2cb75c3a1 Apply clippy fixes 2025-12-20 09:38:46 -06:00
099926d368 Hotfix for broken install target in Makefile
Some checks failed
Basic checks / Basic build-and-test supertask (push) Failing after 48s
I didn't check that it also *installs* all of it's components! That's
what I get for not having a list of package contents... although I'd
probably just end up missing something there instead.
2025-12-19 16:11:13 -06:00
76426094d3 Mark v0.6.0 release
Some checks failed
Basic checks / Basic build-and-test supertask (push) Failing after 59s
2025-12-19 13:47:49 -06:00
4b101633e7 Better colors for the "get ready" screen
The card itself is transparent, but it still has a size of 30% of the
viewport because the bar is based on the size of it's container.

The start bar and text can still be green and red, respectively, but the
light blue was completely out of place.
2025-12-19 13:45:22 -06:00
a5a6f32037 Add a sound warning and mute guide
Page visitors may be surprised by the sounds and not know how to turn
them off. The answer is "you don't", but practically the browser tab can
be muted instead.
2025-12-19 13:36:48 -06:00
4d899d3c97 Improved "load game" button, now with elem swap
Some checks failed
Basic checks / Basic build-and-test supertask (push) Failing after 1m3s
The canvas element no longer exists in the page source. Instead, there
is a div styled to look similar and contain a button. The button is
styled to match the ones in the Bevy app. When pressed, the button
creates the canvas element, replaces the fake canvas div, and loads the
WASM to do it's thing.
2025-12-19 13:27:42 -06:00
6d5afc2445 Add a basic "load game" button
This will ensure the user has interacted with the page before the game
starts, thus allowing the sound to play correctly.

It doesn't re-load the game if the user quits. I'd like to figure out
how to do that.

The need to push the button isn't immediately obvious. It should be over
top (or in place of) the canvas to best convey that the user must start
the game.
2025-12-19 11:46:18 -06:00
d34d0a31f2 Fix: Folder deps need to be order-only deps
I did the thing againnnnn. The Makefile thinks the sound assets are
constantly out-of-date because the folder that contains them technically
changes any time a file is added or removed from the folder.

1. "out/assets" is created, it is up-to-date
2. "out/assets/example.ogg" is created, it is up-to-date
3. Parent folder "out/assets" has it's mtime updated because it's
   contents have changed. It is newer than it was at step 1, and newer
   than the .ogg file in step 2.
4. run `make` again
5. "out/assets" is up-to-date, nothing changes
6. "out/assets/example.ogg" is OLDER than one of it's dependencies
   ("out/assets/"), and is rebuilt.
7. "out/assets" got new contents, so it's mtime was updated again.

The cycle isn't infinite, but it will always try to rebuild the sound
files. The fix is to consider the containing folder to only be an
ordering dependency rather than a substantive dependency. The former
only needs the dependency to be made first, where the latter considers
the dependency to be part of the target file. The containing folder is
not part of the sound files, so "rebuilding" the sound files when the
folder changes is complete nonsense.
2025-12-19 11:26:18 -06:00
11 changed files with 228 additions and 80 deletions

View File

@@ -18,7 +18,12 @@ jobs:
with: with:
components: rustfmt clippy components: rustfmt clippy
- name: Install system dependencies - 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 - name : cargo generate-lockfile
if: hashFiles('Cargo.lock') == '' if: hashFiles('Cargo.lock') == ''
run: cargo generate-lockfile run: cargo generate-lockfile
@@ -41,6 +46,6 @@ jobs:
name: roberts-bad-asteroids-game name: roberts-bad-asteroids-game
path: target/release/asteroids path: target/release/asteroids
if-no-files-found: 'error' if-no-files-found: 'error'
retention-days: 1 retention-days: 7
compression-level: 9 compression-level: 9
overwrite: true overwrite: true

View 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

68
Cargo.lock generated
View File

@@ -242,7 +242,7 @@ dependencies = [
[[package]] [[package]]
name = "asteroids" name = "asteroids"
version = "0.6.0-dev3" version = "0.7.0"
dependencies = [ dependencies = [
"bevy", "bevy",
"bevy-inspector-egui", "bevy-inspector-egui",
@@ -302,9 +302,9 @@ dependencies = [
[[package]] [[package]]
name = "async-lock" name = "async-lock"
version = "3.4.1" version = "3.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
dependencies = [ dependencies = [
"event-listener", "event-listener",
"event-listener-strategy", "event-listener-strategy",
@@ -1848,9 +1848,9 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.50" version = "1.2.51"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203"
dependencies = [ dependencies = [
"find-msvc-tools", "find-msvc-tools",
"jobserver", "jobserver",
@@ -2194,18 +2194,18 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
[[package]] [[package]]
name = "derive_more" name = "derive_more"
version = "2.1.0" version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618" checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134"
dependencies = [ dependencies = [
"derive_more-impl", "derive_more-impl",
] ]
[[package]] [[package]]
name = "derive_more-impl" name = "derive_more-impl"
version = "2.1.0" version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b" checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
dependencies = [ dependencies = [
"convert_case", "convert_case",
"proc-macro2", "proc-macro2",
@@ -2491,9 +2491,9 @@ dependencies = [
[[package]] [[package]]
name = "find-msvc-tools" name = "find-msvc-tools"
version = "0.1.5" version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff"
[[package]] [[package]]
name = "fixedbitset" name = "fixedbitset"
@@ -2646,7 +2646,7 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8"
dependencies = [ dependencies = [
"rustix 1.1.2", "rustix 1.1.3",
"windows-link 0.2.1", "windows-link 0.2.1",
] ]
@@ -3212,9 +3212,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010"
[[package]] [[package]]
name = "jni" name = "jni"
@@ -3661,9 +3661,9 @@ dependencies = [
[[package]] [[package]]
name = "ntapi" name = "ntapi"
version = "0.4.1" version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" checksum = "c70f219e21142367c70c0b30c6a9e3a14d55b4d12a204d897fbec83a0363f081"
dependencies = [ dependencies = [
"winapi", "winapi",
] ]
@@ -4289,15 +4289,15 @@ dependencies = [
"concurrent-queue", "concurrent-queue",
"hermit-abi", "hermit-abi",
"pin-project-lite", "pin-project-lite",
"rustix 1.1.2", "rustix 1.1.3",
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
name = "portable-atomic" name = "portable-atomic"
version = "1.11.1" version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd"
[[package]] [[package]]
name = "portable-atomic-util" name = "portable-atomic-util"
@@ -4660,9 +4660,9 @@ dependencies = [
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "1.1.2" version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34"
dependencies = [ dependencies = [
"bitflags 2.10.0", "bitflags 2.10.0",
"errno", "errno",
@@ -4703,12 +4703,6 @@ dependencies = [
"twox-hash", "twox-hash",
] ]
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]] [[package]]
name = "safe_arch" name = "safe_arch"
version = "0.7.4" version = "0.7.4"
@@ -4802,15 +4796,15 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.145" version = "1.0.147"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" checksum = "6af14725505314343e673e9ecb7cd7e8a36aa9791eb936235a3567cc31447ae4"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr", "memchr",
"ryu",
"serde", "serde",
"serde_core", "serde_core",
"zmij",
] ]
[[package]] [[package]]
@@ -5525,7 +5519,7 @@ checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35"
dependencies = [ dependencies = [
"cc", "cc",
"downcast-rs 1.2.1", "downcast-rs 1.2.1",
"rustix 1.1.2", "rustix 1.1.3",
"scoped-tls", "scoped-tls",
"smallvec", "smallvec",
"wayland-sys", "wayland-sys",
@@ -5538,7 +5532,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d"
dependencies = [ dependencies = [
"bitflags 2.10.0", "bitflags 2.10.0",
"rustix 1.1.2", "rustix 1.1.3",
"wayland-backend", "wayland-backend",
"wayland-scanner", "wayland-scanner",
] ]
@@ -5560,7 +5554,7 @@ version = "0.31.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447ccc440a881271b19e9989f75726d60faa09b95b0200a9b7eb5cc47c3eeb29" checksum = "447ccc440a881271b19e9989f75726d60faa09b95b0200a9b7eb5cc47c3eeb29"
dependencies = [ dependencies = [
"rustix 1.1.2", "rustix 1.1.3",
"wayland-client", "wayland-client",
"xcursor", "xcursor",
] ]
@@ -6474,7 +6468,7 @@ dependencies = [
"libc", "libc",
"libloading", "libloading",
"once_cell", "once_cell",
"rustix 1.1.2", "rustix 1.1.3",
"x11rb-protocol", "x11rb-protocol",
] ]
@@ -6624,6 +6618,12 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "zmij"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0095ecd462946aa3927d9297b63ef82fb9a5316d7a37d134eeb36e58228615a"
[[package]] [[package]]
name = "zune-core" name = "zune-core"
version = "0.4.12" version = "0.4.12"

View File

@@ -1,8 +1,9 @@
[package] [package]
name = "asteroids" name = "asteroids"
version = "0.6.0-dev3" version = "0.7.0"
edition = "2024" edition = "2024"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
rust-version = "1.88.0"
[dependencies] [dependencies]
bevy = "0.17" bevy = "0.17"

View File

@@ -3,18 +3,23 @@
## Do not use it if that isn't your goal! ## Do not use it if that isn't your goal!
## ##
# # # Configuration Variables # # #
#
# Patch these to select a different build profile or target # Patch these to select a different build profile or target
# The target shouldn't change any time soon. WASM64, I guess. Other targets # 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. # aren't aimed at the web, so you shouldn't be using this makefile.
CARGO_TARGET := wasm32-unknown-unknown CARGO_TARGET := wasm32-unknown-unknown
CARGO_PROFILE := tiny CARGO_PROFILE := tiny
# # # Automatic Variables # # #
SRC_DIR = ./src SRC_DIR = ./src
SRCS := $(wildcard $(SRC_DIR)/**) SRCS := $(wildcard $(SRC_DIR)/**)
ASSET_SOURCE := $(wildcard assets/**) ASSET_SOURCE := $(wildcard assets/**)
ASSETS := $(patsubst assets/%.ogg, out/assets/%.ogg, $(ASSET_SOURCE)) 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 .PHONY: clean full-clean tarball tarball-standalone web web-standalone
# "Standalone" version. It includes an index.html to serve as-is # "Standalone" version. It includes an index.html to serve as-is
@@ -40,10 +45,10 @@ target/$(CARGO_TARGET)/$(CARGO_PROFILE)/asteroids.wasm: $(SRCS) Cargo.lock Cargo
out: out:
mkdir $@ mkdir $@
out/assets: out out/assets: | out
mkdir $@ mkdir $@
out/assets/%.ogg: out/assets assets/%.ogg out/assets/%.ogg: assets/%.ogg | out/assets
cp -ar assets/$*.ogg $@ cp -ar assets/$*.ogg $@
# Both the JS and WASM files are generated by the wasm-bindgen call, so both # Both the JS and WASM files are generated by the wasm-bindgen call, so both
@@ -56,6 +61,7 @@ out/asteroids.js out/asteroids_bg.wasm.gz &: target/$(CARGO_TARGET)/$(CARGO_PROF
out/index.html: www/index.html out/index.html: www/index.html
cp -a $< $@ cp -a $< $@
rm -f out/asteroids.html 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. # Like `out/index.html`, but renames the page for use in a larger site.
out/asteroids.html: www/index.html out/asteroids.html: www/index.html
@@ -76,6 +82,8 @@ full-clean: clean
# output into the web root. Only supports the "bundle-able" mode. # output into the web root. Only supports the "bundle-able" mode.
install: web install: web
install -dm0755 $(DESTDIR) install -dm0755 $(DESTDIR)
install -dm0755 $(DESTDIR)/assets
install -m0644 out/asteroids.js $(DESTDIR)/ install -m0644 out/asteroids.js $(DESTDIR)/
install -m0644 out/asteroids_bg.wasm.gz $(DESTDIR)/ install -m0644 out/asteroids_bg.wasm.gz $(DESTDIR)/
install -m0644 out/asteroids.html $(DESTDIR)/ install -m0644 out/asteroids.html $(DESTDIR)/
install -m0644 $(ASSETS) $(DESTDIR)/assets/

View File

@@ -217,7 +217,7 @@ fn input_ship_shoot(
physics::Velocity(bullet_vel), physics::Velocity(bullet_vel),
Mesh2d(game_assets.bullet().0), Mesh2d(game_assets.bullet().0),
MeshMaterial2d(game_assets.bullet().1), MeshMaterial2d(game_assets.bullet().1),
ship_pos.clone(), // clone ship transform *ship_pos, // clone ship transform
Lifetime(Timer::from_seconds(BULLET_LIFETIME, TimerMode::Once)), Lifetime(Timer::from_seconds(BULLET_LIFETIME, TimerMode::Once)),
AudioPlayer::new(game_assets.laser_sound()), AudioPlayer::new(game_assets.laser_sound()),
PlaybackSettings::ONCE, // `Lifetime` already despawns the entity, so this doesn't need to PlaybackSettings::ONCE, // `Lifetime` already despawns the entity, so this doesn't need to

View File

@@ -1,20 +1,28 @@
use bevy::{prelude::*, window::WindowResolution}; use bevy::{prelude::*, window::WindowResolution};
use asteroids::{AsteroidPlugin, config::WINDOW_SIZE}; use asteroids::{AsteroidPlugin, config::WINDOW_SIZE};
#[cfg(feature = "debug_ui")]
use bevy_inspector_egui::{bevy_egui::EguiPlugin, quick::WorldInspectorPlugin}; use bevy_inspector_egui::{bevy_egui::EguiPlugin, quick::WorldInspectorPlugin};
#[cfg(feature = "debug_ui")]
use bevy_rapier2d::render::RapierDebugRenderPlugin;
fn main() { fn main() {
App::new() let mut app = App::new();
.add_plugins(DefaultPlugins.set(WindowPlugin { app.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
canvas: Some("#game-canvas".to_owned()), canvas: Some("#game-canvas".to_owned()),
resolution: WindowResolution::new(WINDOW_SIZE.0, WINDOW_SIZE.1), resolution: WindowResolution::new(WINDOW_SIZE.0, WINDOW_SIZE.1),
..default()
}),
..default() ..default()
})) }),
.add_plugins(AsteroidPlugin) ..default()
.add_plugins(EguiPlugin::default()) }))
.add_plugins(AsteroidPlugin);
#[cfg(feature = "debug_ui")]
app.add_plugins(EguiPlugin::default())
.add_plugins(WorldInspectorPlugin::new()) .add_plugins(WorldInspectorPlugin::new())
.run(); .add_plugins(RapierDebugRenderPlugin::default());
app.run();
} }

View File

@@ -238,7 +238,7 @@ pub fn ship_impact_listener(
Sparkler::at_interval(0.15), Sparkler::at_interval(0.15),
Mesh2d(game_assets.thruster_mesh()), // borrow the thruster mesh for now Mesh2d(game_assets.thruster_mesh()), // borrow the thruster mesh for now
MeshMaterial2d(game_assets.thruster_mat_active()), // ... and the active thruster material 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), Velocity(vel),
)); ));
} }

View File

@@ -111,29 +111,21 @@ pub fn collision_listener(
if *one == *player { if *one == *player {
if rocks.contains(*two) { if rocks.contains(*two) {
// player-asteroid collision // player-asteroid collision
dbg!("Writing ShipDestroy event");
ship_writer.write(messages::ShipDestroy); ship_writer.write(messages::ShipDestroy);
} // else, we don't care } // else, we don't care
} else if *two == *player { } else if *two == *player && rocks.contains(*one) {
if rocks.contains(*one) { ship_writer.write(messages::ShipDestroy);
dbg!("Writing ShipDestroy event");
ship_writer.write(messages::ShipDestroy);
}
} }
// Option 2: Bullet & Asteroid // Option 2: Bullet & Asteroid
if bullets.contains(*one) { if bullets.contains(*one) {
if rocks.contains(*two) { if rocks.contains(*two) {
dbg!("Writing AsteroidDestroy & BulletDestroy events");
asteroid_writer.write(messages::AsteroidDestroy(*two)); asteroid_writer.write(messages::AsteroidDestroy(*two));
bullet_writer.write(messages::BulletDestroy(*one)); bullet_writer.write(messages::BulletDestroy(*one));
} }
} else if rocks.contains(*one) { } else if rocks.contains(*one) && bullets.contains(*two) {
if bullets.contains(*two) { asteroid_writer.write(messages::AsteroidDestroy(*one));
dbg!("Writing AsteroidDestroy & BulletDestroy events"); bullet_writer.write(messages::BulletDestroy(*two));
asteroid_writer.write(messages::AsteroidDestroy(*one));
bullet_writer.write(messages::BulletDestroy(*two));
}
} }
} }
} }

View File

@@ -8,7 +8,7 @@ use crate::{
}; };
use bevy::{ use bevy::{
color::palettes::css::{BLACK, DARK_GRAY, GREEN, LIGHT_BLUE, RED, WHITE}, color::palettes::css::{BLACK, DARK_GRAY, GREEN, RED, WHITE},
prelude::*, prelude::*,
}; };
@@ -180,9 +180,9 @@ fn spawn_get_ready(mut commands: Commands, mut timer: ResMut<ReadySetGoTimer>) {
height: Val::Percent(30.), height: Val::Percent(30.),
..default() ..default()
}, },
BackgroundColor(LIGHT_BLUE.into()), BackgroundColor(Color::NONE),
children![ children![
(Text::new("Get Ready!"), TextColor(BLACK.into())), (Text::new("Get Ready!"), TextColor(WHITE.into())),
( (
CountdownBar, CountdownBar,
Node { Node {
@@ -263,6 +263,7 @@ fn animate_get_ready_widget(
/// on the HUD, this system would quit the game. The same will happen for /// 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 /// returning to the title screen. This should be useful for making a pause
/// menu, too. /// menu, too.
#[allow(clippy::type_complexity)]
fn operate_buttons( fn operate_buttons(
mut interactions: Query< mut interactions: Query<
( (

View File

@@ -12,6 +12,7 @@
margin: auto; margin: auto;
padding: 0.5em; padding: 0.5em;
} }
#prestart-controls,
canvas { canvas {
margin-top: 1em; margin-top: 1em;
margin-left: auto; margin-left: auto;
@@ -22,6 +23,26 @@
border-radius: 8px; border-radius: 8px;
background-color: rgb(40%, 40%, 40%); 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 { main {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
@@ -41,13 +62,21 @@
<h1> <h1>
Robert's Bad Asteroids Game Robert's Bad Asteroids Game
</h1> </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> <main>
<article> <article>
<h2>Description</h2> <h2>Description</h2>
<p> <p>
A (work in progress) version of the Asteroids arcade game. A (work in progress) version of the Asteroids arcade game.
</p> </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>
<article> <article>
<h3>Controls</h3> <h3>Controls</h3>
@@ -89,24 +118,34 @@
</tr> </tr>
<tr> <tr>
<td>Program Version</td> <td>Program Version</td>
<!-- This version text is completely unchecked. I'll need to do something about that. --> <td><code>#CRATE_VERSION_PLACEHOLDER#</code></td>
<td><code>v0.5.0</code></td>
</tr> </tr>
</table> </table>
</article> </article>
</main> </main>
<script type="module"> <script type="module">
import init from './asteroids.js' 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 compressed = await fetch("./asteroids_bg.wasm.gz")
let wasm_stream = compressed.body.pipeThrough(new DecompressionStream("gzip")) let wasm_stream = compressed.body.pipeThrough(new DecompressionStream("gzip"))
let blob = await new Response(wasm_stream).blob(); let blob = await new Response(wasm_stream).blob();
init(await blob.arrayBuffer()).catch((error) => { 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!")) { if (!error.message.startsWith("Using exceptions for control flow, don't mind me. This isn't actually an error!")) {
throw error; throw error;
} }
}); });
}
</script> </script>
</body> </body>