diff --git a/.cargo/config.toml b/.cargo/config.toml
index 56992b6..0b6db5f 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -1,11 +1,11 @@
-[unstable]
-codegen-backend = true
+# [unstable]
+# codegen-backend = true
-[profile.dev]
-codegen-backend = "cranelift"
+# [profile.dev]
+# codegen-backend = "cranelift"
-[profile.dev.package."*"]
-codegen-backend = "llvm"
+# [profile.dev.package."*"]
+# codegen-backend = "llvm"
# for Linux
[target.x86_64-unknown-linux-gnu]
diff --git a/.gitignore b/.gitignore
index 2a188ef..7e6f013 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,6 @@
# Nix generated files
.direnv/
result/
+
+# Web target
+out/
diff --git a/Cargo.lock b/Cargo.lock
index 25c4393..c8df7c7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -306,7 +306,6 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6a01cd51a5cd310e4e7aa6e1560b1aabf29efc6a095a01e6daa8bf0a19f1fea"
dependencies = [
- "bevy_dylib",
"bevy_internal",
]
@@ -525,15 +524,6 @@ dependencies = [
"sysinfo",
]
-[[package]]
-name = "bevy_dylib"
-version = "0.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2b0c60e568493ac23c001d22f47b99818efe1e992253e2ab3fdb69603b2aa1c"
-dependencies = [
- "bevy_internal",
-]
-
[[package]]
name = "bevy_ecs"
version = "0.15.0"
@@ -1409,9 +1399,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.2.2"
+version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc"
+checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d"
dependencies = [
"jobserver",
"libc",
@@ -1912,15 +1902,15 @@ dependencies = [
[[package]]
name = "fastrand"
-version = "2.2.0"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "fdeflate"
-version = "0.3.6"
+version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07c6f4c64c1d33a3111c4466f7365ebdcc37c5bd1ea0d62aae2e3d722aacbedb"
+checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
dependencies = [
"simd-adler32",
]
@@ -2418,11 +2408,10 @@ dependencies = [
[[package]]
name = "js-sys"
-version = "0.3.74"
+version = "0.3.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705"
+checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
dependencies = [
- "once_cell",
"wasm-bindgen",
]
@@ -2471,9 +2460,9 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.167"
+version = "0.2.168"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc"
+checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d"
[[package]]
name = "libloading"
@@ -2499,7 +2488,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
"bitflags 2.6.0",
"libc",
- "redox_syscall 0.5.7",
+ "redox_syscall 0.5.8",
]
[[package]]
@@ -3096,7 +3085,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
- "redox_syscall 0.5.7",
+ "redox_syscall 0.5.8",
"smallvec",
"windows-targets 0.52.6",
]
@@ -3170,9 +3159,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "png"
-version = "0.17.14"
+version = "0.17.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0"
+checksum = "b67582bd5b65bdff614270e2ea89a1cf15bef71245cc1e5f7ea126977144211d"
dependencies = [
"bitflags 1.3.2",
"crc32fast",
@@ -3349,9 +3338,9 @@ dependencies = [
[[package]]
name = "read-fonts"
-version = "0.22.5"
+version = "0.22.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a04b892cb6f91951f144c33321843790c8574c825aafdb16d815fd7183b5229"
+checksum = "69aacb76b5c29acfb7f90155d39759a29496aebb49395830e928a9703d2eec2f"
dependencies = [
"bytemuck",
"font-types",
@@ -3374,9 +3363,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
-version = "0.5.7"
+version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
+checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
dependencies = [
"bitflags 2.6.0",
]
@@ -3468,15 +3457,15 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
-version = "0.38.41"
+version = "0.38.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6"
+checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85"
dependencies = [
"bitflags 2.6.0",
"errno",
"libc",
"linux-raw-sys",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -3528,9 +3517,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "self_cell"
-version = "1.0.4"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a"
+checksum = "c2fdfc24bc566f839a2da4c4295b82db7d25a24253867d5c64355abb5799bdbe"
[[package]]
name = "send_wrapper"
@@ -3540,18 +3529,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"
[[package]]
name = "serde"
-version = "1.0.215"
+version = "1.0.216"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
+checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.215"
+version = "1.0.216"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
+checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
dependencies = [
"proc-macro2",
"quote",
@@ -3575,6 +3564,7 @@ name = "set"
version = "0.1.0"
dependencies = [
"bevy",
+ "wasm-bindgen",
]
[[package]]
@@ -4026,9 +4016,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
-version = "0.2.97"
+version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c"
+checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
dependencies = [
"cfg-if",
"once_cell",
@@ -4037,9 +4027,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.97"
+version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd"
+checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
dependencies = [
"bumpalo",
"log",
@@ -4052,22 +4042,21 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.47"
+version = "0.4.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d"
+checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b"
dependencies = [
"cfg-if",
"js-sys",
- "once_cell",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.97"
+version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051"
+checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -4075,9 +4064,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.97"
+version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d"
+checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
dependencies = [
"proc-macro2",
"quote",
@@ -4088,15 +4077,15 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.97"
+version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49"
+checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
[[package]]
name = "web-sys"
-version = "0.3.74"
+version = "0.3.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c"
+checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -4697,9 +4686,9 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56"
[[package]]
name = "xml-rs"
-version = "0.8.23"
+version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af310deaae937e48a26602b730250b4949e125f468f11e6990be3e5304ddd96f"
+checksum = "ea8b391c9a790b496184c29f7f93b9ed5b16abb306c05415b68bcc16e4d06432"
[[package]]
name = "yazi"
diff --git a/Cargo.toml b/Cargo.toml
index 31b0587..2646d4c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,7 +4,8 @@ version = "0.1.0"
edition = "2021"
[dependencies]
-bevy = { package = "bevy", version = "0.15"}
+wasm-bindgen = { version = "= 0.2.95" }
+bevy = "0.15"
[profile.dev]
opt-level = 1
@@ -12,5 +13,7 @@ opt-level = 1
[profile.dev.package."*"]
opt-level = 3
-[features]
-default = ["bevy/dynamic_linking"]
+[profile.release]
+lto = true
+codegen-units = 1
+opt-level = 'z' # 's'
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..50c5ecc
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,35 @@
+ifeq ($(PROFILE),release)
+RELEASE = --release
+PROFILE = release
+else
+PROFILE = debug
+endif
+
+target/x86_64-unknown-linux-gnu/$(PROFILE)/set: src/*
+ cargo build --target x86_64-unknown-linux-gnu --features bevy/dynamic_linking $(RELEASE)
+
+target/wasm32-unknown-unknown/$(PROFILE)/set.wasm: src/*
+ cargo build --target wasm32-unknown-unknown $(RELEASE)
+
+out/$(PROFILE)/set.js: target/wasm32-unknown-unknown/$(PROFILE)/set.wasm
+ wasm-bindgen --no-typescript --target web --out-dir "./out/$(PROFILE)" ./target/wasm32-unknown-unknown/$(PROFILE)/set.wasm
+
+out/$(PROFILE)/assets:
+ rm -rf ./out/$(PROFILE)/assets
+ cp -r ./assets ./out/$(PROFILE)/
+
+out/$(PROFILE)/index.html:
+ cp index.html ./out/$(PROFILE)/index.html
+
+native/build: target/x86_64-unknown-linux-gnu/$(PROFILE)/set
+
+native/run: native/build
+ cargo run --target x86_64-unknown-linux-gnu --features bevy/dynamic_linking $(RELEASE)
+
+web/build: out/$(PROFILE)/set.js out/$(PROFILE)/assets out/$(PROFILE)/index.html
+
+web/serve: web/build
+ cd ./out/$(PROFILE)/; simple-http-server
+
+clean:
+ rm ./target/*/*/set*
diff --git a/flake.nix b/flake.nix
index a7c443a..59105ad 100644
--- a/flake.nix
+++ b/flake.nix
@@ -28,10 +28,10 @@
];
nativeBuildInputs = with pkgs; [
libxkbcommon
- (rust-bin.selectLatestNightlyWith
- (toolchain: toolchain.default.override {
- extensions = [ "rust-src" "clippy" "rustc-codegen-cranelift-preview"];
- }))
+ (rust-bin.stable.latest.default.override {
+ extensions = [ "rust-src" "clippy" ];
+ targets = [ "x86_64-unknown-linux-gnu" "wasm32-unknown-unknown" ];
+ })
];
all_deps = with pkgs; [
cargo-flamegraph
@@ -39,6 +39,9 @@
nixpkgs-fmt
cmake
rx
+ wasm-pack
+ wasm-bindgen-cli
+ simple-http-server
] ++ buildInputs ++ nativeBuildInputs;
in
rec {
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..014d16b
--- /dev/null
+++ b/index.html
@@ -0,0 +1,27 @@
+
+
+
+
+ s e t
+
+
+
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
index 307a00d..eece77f 100644
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -1,3 +1,3 @@
[toolchain]
-channel = "nightly"
+channel = "stable"
components = [ "rust-src", "clippy", "rustc-codegen-cranelift-preview"];
diff --git a/src/boot.rs b/src/boot.rs
index ec23e13..b9c1211 100644
--- a/src/boot.rs
+++ b/src/boot.rs
@@ -6,7 +6,7 @@ pub struct BootPlugin;
impl Plugin for BootPlugin {
fn build(&self, app: &mut App) {
- app.add_systems(Startup, (boot::load, boot::start_setup).chain());
+ app.add_systems(Startup, (load, start_setup).chain());
}
}
diff --git a/src/debug.rs b/src/debug.rs
index 6f96a8d..1224639 100644
--- a/src/debug.rs
+++ b/src/debug.rs
@@ -1,4 +1,4 @@
-use bevy::prelude::*;
+use bevy::{color::palettes::css::BLACK, prelude::*, window::WindowResized};
use crate::deck::Card;
@@ -8,6 +8,7 @@ pub struct DebugPlugin;
impl Plugin for DebugPlugin {
fn build(&self, app: &mut App) {
app.add_observer(track_card_info)
+ .add_systems(Update, update_window_info)
.add_systems(Startup, init_ui);
}
}
@@ -15,6 +16,9 @@ impl Plugin for DebugPlugin {
#[derive(Component)]
pub(crate) struct DebugText;
+#[derive(Component)]
+pub(crate) struct WindowInfoText;
+
fn init_ui(mut commands: Commands) {
commands
.spawn((
@@ -32,6 +36,45 @@ fn init_ui(mut commands: Commands) {
PickingBehavior::IGNORE,
));
});
+
+ commands
+ .spawn((
+ Node {
+ position_type: PositionType::Absolute,
+ top: Val::Px(0.0),
+ right: Val::Px(0.0),
+ ..default()
+ },
+ BackgroundColor(BLACK.into()),
+ GlobalZIndex(1),
+ ))
+ .with_children(|parent| {
+ parent
+ .spawn(Button)
+ .with_children(|parent| {
+ parent.spawn((
+ Text("-".into()),
+ TextFont {
+ font_size: 60.0,
+ ..default()
+ },
+ ));
+ })
+ .observe(decrease_scale_ratio);
+ parent
+ .spawn(Button)
+ .with_children(|parent| {
+ parent.spawn((
+ Text("+".into()),
+ TextFont {
+ font_size: 60.0,
+ ..default()
+ },
+ ));
+ })
+ .observe(increase_scale_ratio);
+ parent.spawn((Text("????x????".to_string()), WindowInfoText));
+ });
}
fn track_card_info(
@@ -71,3 +114,42 @@ pub(crate) fn hide_debug_card(
*v = Visibility::Hidden;
});
}
+
+fn update_window_info(
+ mut events: EventReader,
+ windows: Query<&mut Window>,
+ mut infos: Query<&mut Text, With>,
+) {
+ events.read().for_each(|_| {
+ info!("Window resized");
+ let window = windows.single();
+ let width = window.resolution.width();
+ let height = window.resolution.height();
+ let scale_factor = window.resolution.scale_factor();
+
+ let mut info = infos.single_mut();
+ info.0 = format!("{:.0}x{:.0} ({:.03})", width, height, scale_factor,);
+ });
+}
+
+fn increase_scale_ratio(
+ _trigger: Trigger>,
+ // TODO: Move window scale factor out to non-debug system
+ mut windows: Query<&mut Window>,
+) {
+ info!("increase scale ratio");
+ let mut window = windows.single_mut();
+ let current = window.scale_factor();
+ window.resolution.set_scale_factor(current + 0.05);
+}
+
+fn decrease_scale_ratio(
+ _trigger: Trigger>,
+ // TODO: Move window scale factor out to non-debug system
+ mut windows: Query<&mut Window>,
+) {
+ info!("decrease scale ratio");
+ let mut window = windows.single_mut();
+ let current = window.scale_factor();
+ window.resolution.set_scale_factor(current - 0.05);
+}
diff --git a/src/main.rs b/src/main.rs
index 478ca02..4d180df 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,8 +9,20 @@ mod view;
use bevy::prelude::*;
fn main() {
+ let primary_window = Some(Window {
+ // web: fill the window
+ fit_canvas_to_parent: true,
+ ..default()
+ });
App::new()
- .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
+ .add_plugins(
+ DefaultPlugins
+ .set(ImagePlugin::default_nearest())
+ .set(WindowPlugin {
+ primary_window,
+ ..default()
+ }),
+ )
.add_plugins((
view::ViewPlugin,
deck::DeckPlugin,
@@ -18,7 +30,7 @@ fn main() {
setup::SetupPlugin,
play::PlayPlugin,
menu::MenuPlugin,
- debug::DebugPlugin,
+ // debug::DebugPlugin,
))
.init_state::()
.run();
diff --git a/src/menu.rs b/src/menu.rs
index 2d2a977..9d1e4d6 100644
--- a/src/menu.rs
+++ b/src/menu.rs
@@ -1,10 +1,12 @@
use bevy::{
- color::palettes::css::{BLACK, GREEN, INDIGO, ORANGE, PURPLE, RED, TEAL},
+ color::palettes::css::{BLACK, WHITE},
prelude::*,
};
use crate::{
- play::check_for_sets,
+ boot,
+ deck::{Card, Deck, ItemColor, ItemNumber, ItemPattern, ItemShape},
+ play::{check_for_sets, check_set},
view::{button_set_state, ViewState},
};
@@ -18,70 +20,126 @@ impl Plugin for MenuPlugin {
(
setup,
setup_about,
- setup_how_to_play,
+ setup_how_to_play.after(boot::load),
setup_deck,
setup_sets,
+ setup_set_check_button,
),
);
}
}
+fn button_builder(node: Node) -> (Button, BackgroundColor, Node, BorderColor) {
+ (
+ Button,
+ BackgroundColor(BLACK.with_alpha(0.9).into()),
+ Node {
+ padding: UiRect::all(Val::Px(10.)),
+ margin: UiRect::top(Val::Px(25.)),
+ border: UiRect::all(Val::Px(1.0)),
+ ..node
+ },
+ BorderColor(WHITE.into()),
+ )
+}
+
fn setup(mut commands: Commands) {
commands
- .spawn((ViewState::Menu, Node::default()))
+ .spawn((
+ ViewState::Menu,
+ Node {
+ position_type: PositionType::Absolute,
+ justify_content: JustifyContent::Center,
+ align_items: AlignItems::Center,
+ width: Val::Percent(100.0),
+ height: Val::Percent(100.0),
+ ..default()
+ },
+ ))
.with_children(|parent| {
parent
- .spawn((Button, BackgroundColor(TEAL.into())))
- .with_children(|parent| {
- parent.spawn(Text("Play".to_string()));
+ .spawn(Node {
+ flex_direction: FlexDirection::Column,
+ align_items: AlignItems::Center,
+ justify_content: JustifyContent::Center,
+ ..default()
})
- .observe(button_set_state(ViewState::Play));
- parent
- .spawn((Button, BackgroundColor(ORANGE.into())))
.with_children(|parent| {
- parent.spawn(Text("About".to_string()));
- })
- .observe(button_set_state(ViewState::About));
- parent
- .spawn((Button, BackgroundColor(PURPLE.into())))
- .with_children(|parent| {
- parent.spawn(Text("How to Play".to_string()));
- })
- .observe(button_set_state(ViewState::HowToPlay));
- parent
- .spawn((Button, BackgroundColor(RED.into())))
- .with_children(|parent| {
- parent.spawn(Text("Quit".to_string()));
- })
- .observe(quit_button);
+ parent
+ .spawn(button_builder(Node::default()))
+ .with_children(|parent| {
+ parent.spawn(Text("Play".to_string()));
+ })
+ .observe(button_hover_on)
+ .observe(button_hover_off)
+ .observe(button_set_state(ViewState::Play));
+ parent
+ .spawn(button_builder(Node::default()))
+ .with_children(|parent| {
+ parent.spawn(Text("About".to_string()));
+ })
+ .observe(button_hover_on)
+ .observe(button_hover_off)
+ .observe(button_set_state(ViewState::About));
+ parent
+ .spawn(button_builder(Node::default()))
+ .with_children(|parent| {
+ parent.spawn(Text("How to Play".to_string()));
+ })
+ .observe(button_hover_on)
+ .observe(button_hover_off)
+ .observe(button_set_state(ViewState::HowToPlay));
+
+ #[cfg(not(target_arch = "wasm32"))]
+ parent
+ .spawn(button_builder(Node::default()))
+ .with_children(|parent| {
+ parent.spawn(Text("Quit".to_string()));
+ })
+ .observe(button_hover_on)
+ .observe(button_hover_off)
+ .observe(quit_button);
+ });
});
commands
.spawn((ViewState::Play, Node::default()))
.with_children(|parent| {
parent
- .spawn((Button, BackgroundColor(TEAL.into()), GlobalZIndex(1)))
+ .spawn((button_builder(Node::default()), GlobalZIndex(1)))
.with_children(|parent| {
parent.spawn(Text("Menu".to_string()));
})
+ .observe(button_hover_on)
+ .observe(button_hover_off)
.observe(button_set_state(ViewState::Menu));
+ /*
parent
- .spawn((Button, BackgroundColor(INDIGO.into()), GlobalZIndex(1)))
+ .spawn((button_builder(Node::default()), GlobalZIndex(1)))
.with_children(|parent| {
parent.spawn(Text("Deck".to_string()));
})
+ .observe(button_hover_on)
+ .observe(button_hover_off)
.observe(button_set_state(ViewState::Deck));
+ */
+ /*
parent
- .spawn((Button, BackgroundColor(ORANGE.into()), GlobalZIndex(1)))
+ .spawn((button_builder(Node::default()), GlobalZIndex(1)))
.with_children(|parent| {
parent.spawn(Text("Sets".to_string()));
})
+ .observe(button_hover_on)
+ .observe(button_hover_off)
.observe(button_set_state(ViewState::Sets));
+ */
parent
- .spawn((Button, BackgroundColor(GREEN.into()), GlobalZIndex(1)))
+ .spawn((button_builder(Node::default()), GlobalZIndex(1)))
.with_children(|parent| {
parent.spawn(Text("Help!".to_string()));
})
+ .observe(button_hover_on)
+ .observe(button_hover_off)
.observe(check_for_sets);
});
}
@@ -91,32 +149,150 @@ fn setup_about(mut commands: Commands) {
.spawn((ViewState::About, Node::default()))
.with_children(|parent| {
parent
- .spawn((Button, BackgroundColor(TEAL.into())))
+ .spawn(button_builder(Node::default()))
.with_children(|parent| {
parent.spawn(Text("Menu".to_string()));
})
.observe(button_set_state(ViewState::Menu));
- parent.spawn((
- Text("This is the about page".to_string()),
- BackgroundColor(BLACK.into()),
- ));
});
}
-fn setup_how_to_play(mut commands: Commands) {
+fn setup_how_to_play(mut commands: Commands, deck: Res) {
commands
- .spawn((ViewState::HowToPlay, Node::default()))
+ .spawn((
+ ViewState::HowToPlay,
+ Node {
+ position_type: PositionType::Absolute,
+ width: Val::Percent(100.0),
+ height: Val::Percent(100.0),
+ ..default()
+ },
+ ))
.with_children(|parent| {
parent
- .spawn((Button, BackgroundColor(TEAL.into())))
+ .spawn(button_builder(Node {
+ position_type: PositionType::Absolute,
+ top: Val::Px(0.0),
+ left: Val::Px(0.0),
+ ..default()
+ }))
.with_children(|parent| {
parent.spawn(Text("Menu".to_string()));
})
.observe(button_set_state(ViewState::Menu));
- parent.spawn((
- Text("This is the how to play page".to_string()),
- BackgroundColor(BLACK.into()),
- ));
+
+ parent.spawn((Node {
+ align_items: AlignItems::Center,
+ justify_content: JustifyContent::Center,
+ flex_direction: FlexDirection::Column,
+ ..default()
+ },
+ BackgroundColor(BLACK.with_alpha(0.9).into()),
+ )).with_children(|parent| {
+ let most_matching = (
+ Card {
+ color: ItemColor::Red,
+ shape: ItemShape::Squiggle,
+ number: ItemNumber::One,
+ pattern: ItemPattern::Solid,
+ },
+ Card {
+ color: ItemColor::Red,
+ shape: ItemShape::Squiggle,
+ number: ItemNumber::Two,
+ pattern: ItemPattern::Solid,
+ },
+ Card {
+ color: ItemColor::Red,
+ shape: ItemShape::Squiggle,
+ number: ItemNumber::Three,
+ pattern: ItemPattern::Solid,
+ }
+ );
+ let most_not_matching = (
+ Card {
+ color: ItemColor::Green,
+ shape: ItemShape::Oval,
+ number: ItemNumber::Three,
+ pattern: ItemPattern::Solid,
+ },
+ Card {
+ color: ItemColor::Purple,
+ shape: ItemShape::Squiggle,
+ number: ItemNumber::Three,
+ pattern: ItemPattern::Striped,
+ },
+ Card {
+ color: ItemColor::Red,
+ shape: ItemShape::Diamond,
+ number: ItemNumber::Three,
+ pattern: ItemPattern::Open,
+ }
+ );
+ let not_valid = (
+ Card {
+ color: ItemColor::Purple,
+ shape: ItemShape::Oval,
+ number: ItemNumber::Three,
+ pattern: ItemPattern::Striped,
+ },
+ Card {
+ color: ItemColor::Purple,
+ shape: ItemShape::Oval,
+ number: ItemNumber::Two,
+ pattern: ItemPattern::Striped,
+ },
+ Card {
+ color: ItemColor::Purple,
+ shape: ItemShape::Oval,
+ number: ItemNumber::Three,
+ pattern: ItemPattern::Open,
+ }
+ );
+ [
+ ("Find groups of 3 cards", None),
+ ("All cards in a set must match or differ in their traits: Color, Number, Shading, and Shape.", None),
+ ("For example all agree on Color, Shading, and Shape but not Number...", Some(most_matching)),
+ ("...or all agree on Number but not Color, Number, Shading, and Shape...", Some(most_not_matching)),
+ ("...but never partial agreement on a trait...", Some(not_valid)),
+ ("When in doubt, click the 'Help!' button to get an assist", None),
+ ]
+ .iter()
+ .for_each(|(t, example)| {
+ parent.spawn((
+ Node {
+ flex_direction: FlexDirection::Row,
+ align_items: AlignItems::Center,
+ ..default()
+ },
+ )).with_children(|parent| {
+ parent.spawn((
+ Node {
+ margin: UiRect::all(Val::Px(5.0)),
+ padding: UiRect::all(Val::Px(5.0)),
+ ..default()
+ },
+ Text(t.to_string()),
+ ));
+ if let Some((a, b, c)) = example {
+ [a, b, c].iter().for_each(|x| {
+ let sprite = deck.cards.get(*x).unwrap();
+ parent.spawn((
+ Node {
+ height: Val::Px(100.0),
+ ..default()
+ },
+ ImageNode {
+ image: sprite.image.clone(),
+ texture_atlas: sprite.texture_atlas.clone(),
+ ..default()
+ }
+ ));
+ });
+ };
+ });
+ });
+ });
});
}
@@ -125,7 +301,7 @@ fn setup_deck(mut commands: Commands) {
.spawn((ViewState::Deck, Node::default()))
.with_children(|parent| {
parent
- .spawn((Button, BackgroundColor(TEAL.into())))
+ .spawn(button_builder(Node::default()))
.with_children(|parent| {
parent.spawn(Text("Back".to_string()));
})
@@ -138,7 +314,7 @@ fn setup_sets(mut commands: Commands) {
.spawn((ViewState::Sets, Node::default()))
.with_children(|parent| {
parent
- .spawn((Button, BackgroundColor(TEAL.into())))
+ .spawn(button_builder(Node::default()))
.with_children(|parent| {
parent.spawn(Text("Back".to_string()));
})
@@ -146,6 +322,40 @@ fn setup_sets(mut commands: Commands) {
});
}
+pub(crate) fn setup_set_check_button(mut commands: Commands) {
+ commands
+ .spawn((
+ Node {
+ width: Val::Percent(100.0),
+ position_type: PositionType::Absolute,
+ top: Val::Px(0.0),
+ flex_direction: FlexDirection::Column,
+ align_items: AlignItems::Center,
+ ..default()
+ },
+ Visibility::default(),
+ ViewState::Play,
+ ))
+ .with_children(|parent| {
+ parent
+ .spawn(button_builder(Node::default()))
+ .with_children(|parent| {
+ parent.spawn(Text("Set!".to_string()));
+ })
+ .observe(check_set);
+ });
+}
+
fn quit_button(_trigger: Trigger>, mut exit_event: EventWriter) {
exit_event.send(AppExit::Success);
}
+
+fn button_hover_on(trigger: Trigger>, mut query: Query<&mut BackgroundColor>) {
+ let mut background_color = query.get_mut(trigger.entity()).unwrap();
+ background_color.0.set_alpha(1.0);
+}
+
+fn button_hover_off(trigger: Trigger>, mut query: Query<&mut BackgroundColor>) {
+ let mut background_color = query.get_mut(trigger.entity()).unwrap();
+ background_color.0.set_alpha(0.9);
+}
diff --git a/src/play.rs b/src/play.rs
index d3595ef..d099c52 100644
--- a/src/play.rs
+++ b/src/play.rs
@@ -189,11 +189,11 @@ pub(crate) fn place_card(
query.get_mut(trigger.entity()).unwrap();
// Set it's transform based on it's placement
- let CARD_SIZE = [100.0, 160.0];
- let offset = Vec2::new(CARD_SIZE[0] * 4.0, CARD_SIZE[1] * 4.0) / 2.5;
+ let card_size = [100.0, 160.0];
+ let offset = Vec2::new(card_size[0] * 4.0, card_size[1] * 4.0) / 2.5;
transform.translation = Vec3::new(
- ((*x as f32) * CARD_SIZE[0]) - offset.x,
- ((*y as f32) * CARD_SIZE[1]) - offset.y,
+ ((*x as f32) * card_size[0]) - offset.x,
+ ((*y as f32) * card_size[1]) - offset.y,
0.0,
);
diff --git a/src/setup.rs b/src/setup.rs
index 45f1d81..aaa3ffc 100644
--- a/src/setup.rs
+++ b/src/setup.rs
@@ -1,5 +1,5 @@
use crate::{deck::*, *};
-use bevy::{color::palettes::css::TEAL, prelude::*};
+use bevy::prelude::*;
use view::ViewState;
pub struct SetupPlugin;
@@ -8,14 +8,7 @@ impl Plugin for SetupPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
OnEnter(GameState::Setup),
- (
- setup_background,
- setup_cards,
- setup_set_check_button,
- setup_camera,
- start_play,
- )
- .chain(),
+ (setup_background, setup_cards, setup_camera, start_play).chain(),
);
}
}
@@ -75,29 +68,6 @@ pub(crate) fn setup_background(
));
}
-pub(crate) fn setup_set_check_button(mut commands: Commands) {
- commands
- .spawn((
- Node {
- width: Val::Percent(100.0),
- flex_direction: FlexDirection::Column,
- align_items: AlignItems::Center,
- ..default()
- },
- Visibility::default(),
- ViewState::Play,
- BackgroundColor(Color::BLACK.into()),
- ))
- .with_children(|parent| {
- parent
- .spawn((Button, BackgroundColor(TEAL.into())))
- .with_children(|parent| {
- parent.spawn(Text("Set!?".to_string()));
- })
- .observe(play::check_set);
- });
-}
-
/// Finish the setup state by progressing to the play state
pub(crate) fn start_play(
mut game_state: ResMut>,
diff --git a/src/view.rs b/src/view.rs
index 2ba7e0c..ed0a4b1 100644
--- a/src/view.rs
+++ b/src/view.rs
@@ -1,4 +1,4 @@
-use bevy::{prelude::*, state::state::FreelyMutableState};
+use bevy::{prelude::*, state::state::FreelyMutableState, window::WindowResized};
/// Deck and Cards
pub struct ViewPlugin;
@@ -6,6 +6,7 @@ pub struct ViewPlugin;
impl Plugin for ViewPlugin {
fn build(&self, app: &mut App) {
app.init_state::()
+ .add_systems(Update, update_window_info)
.add_systems(Update, state_monitor);
}
}
@@ -47,3 +48,21 @@ fn state_monitor(
});
});
}
+
+fn update_window_info(mut events: EventReader, mut _windows: Query<&mut Window>) {
+ events
+ .read()
+ .for_each(|WindowResized { height, width, .. }| {
+ info!("Window resized {} {}", height, width);
+
+ let new_scale_factor = {
+ let height_ratio = 800.0 / height;
+ let width_ratio = 500.0 / width;
+ height_ratio.min(width_ratio)
+ };
+ // let window = windows.single_mut();
+ // window.resolution.set_scale_factor(new_scale_factor);
+
+ info!("Proposed scale factor: {:?}", new_scale_factor);
+ });
+}
diff --git a/todo.txt b/todo.txt
index 8b9361d..31d5604 100644
--- a/todo.txt
+++ b/todo.txt
@@ -11,3 +11,10 @@ TODO:
* Menu
* About/Credits
* How To Play
+
+Exclude for now:
+* deck
+* sets
+
+Exclude in wasm:
+* quit