11 Commits

Author SHA1 Message Date
8fc9e682cc Release v0.5.0
Some checks failed
Basic checks / Basic build-and-test supertask (push) Failing after 28s
2025-11-15 15:18:54 -06:00
be83be1a7b Compress the WASM file for even more space savings 2025-11-15 15:16:37 -06:00
3639122e54 Fix: install "asteroids.html" not "boids.html"
Yay for copying code around!
2025-11-15 15:16:02 -06:00
97e0313c23 Impl a basic scoring system
Games have scores, so I need a score counter... I guess.
2025-11-09 11:14:27 -06:00
de79ca0258 Apply clippy lint fix 2025-11-09 10:57:36 -06:00
1edbd3e78c Name oldest viable dependency versions
Semver compatible resolution means I still get the newest, so I want to
name the oldest that still works to let Cargo do it's thing.
2025-11-08 22:17:05 -06:00
5af59863a1 Release v0.4.0, now includes lockfile
All checks were successful
Basic checks / Basic build-and-test supertask (push) Successful in 6m23s
The only real change was the addition of some CSS. I'm recording the
lockfile so that consumers can more reliably build the same binary each
time.
2025-11-08 12:31:29 -06:00
84d93d496a Remove Linux-specific deps from web build
All checks were successful
Basic checks / Basic build-and-test supertask (push) Successful in 6m24s
The Alsa and Udev system dependencies are only required on Linux. The
WASM/WASI build doesn't use them, so they don't need to exist in the
build container.
2025-11-08 12:10:42 -06:00
4a9d252691 Update Dockerfile, copy everything, use makefile
I have figured out the `.dockerignore` file so I don't have to do manual
context size management like before.

The Dockerfile now uses the Makefile to ensure image builds contain the
same thing non-image builds would.
2025-11-08 12:08:45 -06:00
3c9a9a7d9d Add some CSS 2025-11-08 12:07:30 -06:00
010cbd6d4b Add an install target 2025-11-06 14:18:13 -06:00
8 changed files with 6064 additions and 31 deletions

6008
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,14 @@
[package] [package]
name = "asteroids" name = "asteroids"
version = "0.3.0" version = "0.5.0"
edition = "2024" edition = "2024"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
[dependencies] [dependencies]
bevy = "0.16" bevy = "0.16"
bevy-inspector-egui = "0.32.0" bevy-inspector-egui = "0.32"
bevy_rapier2d = "0.31.0" bevy_rapier2d = "0.31"
rand = "0.9.2" rand = "0.9"
[features] [features]
default = ["dynamic_linking"] default = ["dynamic_linking"]
@@ -16,7 +16,7 @@ dynamic_linking = ["bevy/dynamic_linking"]
debug_ui = ["bevy_rapier2d/debug-render-2d"] debug_ui = ["bevy_rapier2d/debug-render-2d"]
[target.'cfg(target_arch = "wasm32")'.dependencies] [target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0.3.3", features = ["wasm_js"] } getrandom = { version = "0.3", features = ["wasm_js"] }
[profile.speedy] [profile.speedy]
inherits = "release" inherits = "release"

View File

@@ -1,22 +1,11 @@
FROM rust:1.89 AS builder FROM rust:1.89 AS builder
RUN apt-get update
RUN apt-get install -y --no-install-recommends libasound2-dev libudev-dev
RUN rustup target add wasm32-unknown-unknown RUN rustup target add wasm32-unknown-unknown
RUN cargo install --locked wasm-bindgen-cli RUN cargo install --locked wasm-bindgen-cli
# Copy in only the parts we care about. This is to prevent Docker from re- COPY . .
# running some steps because unimportant files changed (e.g.: the .git/ folder)
COPY src/ ./src
COPY Cargo.toml ./Cargo.toml
# WARN: The lockfile doesn't exist in the repo. You will have to create it
# before building the Docker image (i.e.: run `cargo update` first)
COPY Cargo.lock ./Cargo.lock
COPY www/ ./www
COPY Makefile ./Makefile
# Oops. There's no text output in the Docker build command line (it still works, though) RUN make -j
RUN make
FROM busybox:musl FROM busybox:musl
RUN mkdir -p /var/www RUN mkdir -p /var/www

View File

@@ -15,20 +15,20 @@ SRCS := $(wildcard $(SRC_DIR)/**)
.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
web-standalone: out/asteroids.js out/asteroids_bg.wasm out/index.html web-standalone: out/asteroids.js out/asteroids_bg.wasm.gz out/index.html
# "Bundle-able" version. It has a page, but no index.html. Consumers are # "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. # expected to provide their own index.html and link to this page.
web: out/asteroids.js out/asteroids_bg.wasm out/asteroids.html web: out/asteroids.js out/asteroids_bg.wasm.gz out/asteroids.html
tarball: asteroids_web_root.tar tarball: asteroids_web_root.tar
tarball_standalone: asteroids_web_root_standalone.tar tarball_standalone: asteroids_web_root_standalone.tar
asteroids_web_root.tar: out/asteroids.js out/asteroids_bg.wasm out/asteroids.html asteroids_web_root.tar: out/asteroids.js out/asteroids_bg.wasm.gz out/asteroids.html
tar -caf $@ $^ tar -caf $@ $^
asteroids_web_root_standalone.tar: out/asteroids.js out/asteroids_bg.wasm out/index.html asteroids_web_root_standalone.tar: out/asteroids.js out/asteroids_bg.wasm.gz out/index.html
tar -caf $@ $^ tar -caf $@ $^
target/$(CARGO_TARGET)/$(CARGO_PROFILE)/asteroids.wasm: $(SRCS) Cargo.lock Cargo.toml target/$(CARGO_TARGET)/$(CARGO_PROFILE)/asteroids.wasm: $(SRCS) Cargo.lock Cargo.toml
@@ -39,13 +39,14 @@ out:
# 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
# get to be on the target half of this recipe. # get to be on the target half of this recipe.
out/asteroids.js out/asteroids_bg.wasm &: target/$(CARGO_TARGET)/$(CARGO_PROFILE)/asteroids.wasm | out out/asteroids.js out/asteroids_bg.wasm.gz &: target/$(CARGO_TARGET)/$(CARGO_PROFILE)/asteroids.wasm | out
wasm-bindgen --no-typescript --target web --out-dir ./out/ --out-name asteroids target/$(CARGO_TARGET)/$(CARGO_PROFILE)/asteroids.wasm wasm-bindgen --no-typescript --target web --out-dir ./out/ --out-name asteroids target/$(CARGO_TARGET)/$(CARGO_PROFILE)/asteroids.wasm
gzip -9 -f out/asteroids_bg.wasm
# Copies the index page to the output dir. # Copies the index page to the output dir.
out/index.html: www/index.html out/index.html: www/index.html
cp -a $< $@ cp -a $< $@
rm -f out/boids.html rm -f out/asteroids.html
# 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
@@ -61,3 +62,11 @@ clean:
# this, I guess. # this, I guess.
full-clean: clean full-clean: clean
cargo clean cargo clean
# Installation goal. It's meant to be a helper utility for moving the built
# output into the web root. Only supports the "bundle-able" mode.
install: web
install -dm0755 $(DESTDIR)
install -m0644 out/asteroids.js $(DESTDIR)/
install -m0644 out/asteroids_bg.wasm.gz $(DESTDIR)/
install -m0644 out/asteroids.html $(DESTDIR)/

View File

@@ -65,6 +65,7 @@ impl Plugin for AsteroidPlugin {
objects::ship_impact_listener, objects::ship_impact_listener,
physics::collision_listener, physics::collision_listener,
machinery::tick_lifetimes, machinery::tick_lifetimes,
machinery::update_scoreboard,
) )
.run_if(in_state(GameState::Playing)), .run_if(in_state(GameState::Playing)),
) )

View File

@@ -8,7 +8,7 @@ use std::time::Duration;
use bevy::prelude::*; use bevy::prelude::*;
use crate::{WorldSize, events::SpawnAsteroid, objects::AsteroidSize}; use crate::{WorldSize, events::{AsteroidDestroy, SpawnAsteroid}, objects::AsteroidSize, resources::Score};
/// Asteroid spawning parameters and state. /// Asteroid spawning parameters and state.
/// ///
@@ -135,3 +135,15 @@ pub fn operate_sparklers(sparklers: Query<(&mut Visibility, &mut Sparkler)>, tim
} }
} }
} }
/// Event listener for adding score after an asteroid was destroyed
///
/// Refreshing the HUD element is done by [crate::widgets::operate_ui] (a private function)
pub fn update_scoreboard(
mut destroy_events: EventReader<AsteroidDestroy>,
mut scoreboard: ResMut<Score>,
) {
for _event in destroy_events.read() {
scoreboard.0 += 100;
}
}

View File

@@ -4,7 +4,6 @@
use bevy::{ use bevy::{
ecs::{ ecs::{
bundle::Bundle,
component::Component, component::Component,
entity::Entity, entity::Entity,
event::{EventReader, EventWriter}, event::{EventReader, EventWriter},

View File

@@ -2,15 +2,25 @@
<html lang="en"> <html lang="en">
<head> <head>
<style> <style>
body {
background-color: hsl(200, 3%, 65%);
}
h1 { h1 {
color: hsl(200, 3%, 90%);
background-color: hsl(195, 5%, 17%);
text-align: center; text-align: center;
margin: auto;
padding: 0.5em;
} }
canvas { canvas {
padding-left: 0; margin-top: 1em;
padding-right: 0;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
display: block; display: block;
outline-color: hsl(200, 7%, 50%);
outline-style: outset;
border-radius: 8px;
background-color: rgb(40%, 40%, 40%);
} }
main { main {
margin-left: auto; margin-left: auto;
@@ -18,11 +28,12 @@
width: 70%; width: 70%;
} }
table { table {
margin-bottom: 10px;
border-collapse: collapse; border-collapse: collapse;
} }
th, td { th, td {
border: 1px solid; border: 1px solid;
padding: 2px 4px; padding: 0.1em 0.3em;
} }
</style> </style>
</head> </head>
@@ -79,7 +90,7 @@
<tr> <tr>
<td>Program Version</td> <td>Program Version</td>
<!-- This version text is completely unchecked. I'll need to do something about that. --> <!-- This version text is completely unchecked. I'll need to do something about that. -->
<td><code>v0.3.0</code></td> <td><code>v0.5.0</code></td>
</tr> </tr>
</table> </table>
</article> </article>
@@ -87,7 +98,11 @@
<script type="module"> <script type="module">
import init from './asteroids.js' import init from './asteroids.js'
init().catch((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!")) { if (!error.message.startsWith("Using exceptions for control flow, don't mind me. This isn't actually an error!")) {
throw error; throw error;
} }