1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
target/
|
||||||
5618
Cargo.lock
generated
Normal file
5618
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
19
Cargo.toml
Normal file
19
Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[package]
|
||||||
|
name = "pomomon-garden"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = 1
|
||||||
|
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
opt-level = 3
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
codegen-units = 1
|
||||||
|
lto = "thin"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bevy = "0.17.2"
|
||||||
|
bevy_aseprite_ultra = "0.7.0"
|
||||||
|
bevy_dev_tools = "0.17.2"
|
||||||
BIN
assets/pom-idle.aseprite
Normal file
BIN
assets/pom-idle.aseprite
Normal file
Binary file not shown.
BIN
assets/pom-sleep.aseprite
Normal file
BIN
assets/pom-sleep.aseprite
Normal file
Binary file not shown.
BIN
assets/pom.aseprite
Normal file
BIN
assets/pom.aseprite
Normal file
Binary file not shown.
116
flake.lock
generated
Normal file
116
flake.lock
generated
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"crane": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1762538466,
|
||||||
|
"narHash": "sha256-8zrIPl6J+wLm9MH5ksHcW7BUHo7jSNOu0/hA0ohOOaM=",
|
||||||
|
"owner": "ipetkov",
|
||||||
|
"repo": "crane",
|
||||||
|
"rev": "0cea393fffb39575c46b7a0318386467272182fe",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "ipetkov",
|
||||||
|
"repo": "crane",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fenix": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"rust-analyzer-src": "rust-analyzer-src"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1763361733,
|
||||||
|
"narHash": "sha256-ka7dpwH3HIXCyD2wl5F7cPLeRbqZoY2ullALsvxdPt8=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "fenix",
|
||||||
|
"rev": "6c8d48e3b0ae371b19ac1485744687b788e80193",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "fenix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1760524057,
|
||||||
|
"narHash": "sha256-EVAqOteLBFmd7pKkb0+FIUyzTF61VKi7YmvP1tw4nEw=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "544961dfcce86422ba200ed9a0b00dd4b1486ec5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"crane": "crane",
|
||||||
|
"fenix": "fenix",
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-analyzer-src": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1762860488,
|
||||||
|
"narHash": "sha256-rMfWMCOo/pPefM2We0iMBLi2kLBAnYoB9thi4qS7uk4=",
|
||||||
|
"owner": "rust-lang",
|
||||||
|
"repo": "rust-analyzer",
|
||||||
|
"rev": "2efc80078029894eec0699f62ec8d5c1a56af763",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "rust-lang",
|
||||||
|
"ref": "nightly",
|
||||||
|
"repo": "rust-analyzer",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
116
flake.nix
Normal file
116
flake.nix
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
fenix = {
|
||||||
|
url = "github:nix-community/fenix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
crane.url = "github:ipetkov/crane";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = {
|
||||||
|
nixpkgs,
|
||||||
|
fenix,
|
||||||
|
crane,
|
||||||
|
flake-utils,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
flake-utils.lib.eachDefaultSystem (system: let
|
||||||
|
pkgs = import nixpkgs {inherit system;};
|
||||||
|
|
||||||
|
pname = "pomomon-garden";
|
||||||
|
version = "0.1.0";
|
||||||
|
|
||||||
|
rust-toolchain = with fenix.packages.${system};
|
||||||
|
combine [
|
||||||
|
beta.rustc
|
||||||
|
beta.cargo
|
||||||
|
beta.rust-src
|
||||||
|
beta.rust-analyzer
|
||||||
|
];
|
||||||
|
|
||||||
|
bevyDeps = with pkgs; [
|
||||||
|
pkg-config
|
||||||
|
# Audio
|
||||||
|
alsa-lib
|
||||||
|
# Vulkan
|
||||||
|
vulkan-loader
|
||||||
|
vulkan-tools
|
||||||
|
libudev-zero
|
||||||
|
# X11
|
||||||
|
xorg.libX11
|
||||||
|
xorg.libXcursor
|
||||||
|
xorg.libXi
|
||||||
|
xorg.libXrandr
|
||||||
|
# Wayland
|
||||||
|
wayland
|
||||||
|
libxkbcommon
|
||||||
|
# linker
|
||||||
|
lld
|
||||||
|
];
|
||||||
|
runtimeLibs = pkgs.lib.makeLibraryPath bevyDeps;
|
||||||
|
|
||||||
|
craneLib = (crane.mkLib pkgs).overrideToolchain rust-toolchain;
|
||||||
|
|
||||||
|
cargoArtifacts = craneLib.buildDepsOnly {
|
||||||
|
pname = "${pname}-deps";
|
||||||
|
src = craneLib.cleanCargoSource (craneLib.path ./.);
|
||||||
|
nativeBuildInputs = with pkgs; [pkg-config];
|
||||||
|
buildInputs = bevyDeps;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
packages.default = craneLib.buildPackage {
|
||||||
|
inherit pname version;
|
||||||
|
src = craneLib.cleanCargoSource (craneLib.path ./.);
|
||||||
|
inherit cargoArtifacts;
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [
|
||||||
|
pkg-config
|
||||||
|
rust-toolchain
|
||||||
|
lld
|
||||||
|
makeWrapper
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = bevyDeps;
|
||||||
|
|
||||||
|
CARGO_PROFILE_RELEASE_LTO = "thin";
|
||||||
|
CARGO_PROFILE_RELEASE_CODEGEN_UNITS = 1;
|
||||||
|
CARGO_PROFILE_RELEASE_STRIP = true;
|
||||||
|
RUSTFLAGS = "-C link-arg=-fuse-ld=lld";
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
wrapProgram "$out/bin/${pname}" \
|
||||||
|
--prefix LD_LIBRARY_PATH : ${runtimeLibs}
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with pkgs.lib; {
|
||||||
|
description = "A pomodoro garden management game.";
|
||||||
|
license = licenses.mit;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
devShells.default = pkgs.mkShell {
|
||||||
|
nativeBuildInputs = with pkgs; [
|
||||||
|
pkg-config
|
||||||
|
lld
|
||||||
|
];
|
||||||
|
|
||||||
|
packages = with pkgs;
|
||||||
|
[
|
||||||
|
rust-toolchain
|
||||||
|
cargo-watch
|
||||||
|
cargo-edit
|
||||||
|
cargo-tarpaulin
|
||||||
|
]
|
||||||
|
++ bevyDeps;
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
export RUST_SRC_PATH=${fenix.packages.${system}.stable.rust-src}/lib/rustlib/src/rust/library
|
||||||
|
export LD_LIBRARY_PATH=${runtimeLibs}:$LD_LIBRARY_PATH
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
formatter = pkgs.nixpkgs-fmt;
|
||||||
|
});
|
||||||
|
}
|
||||||
21
src/components.rs
Normal file
21
src/components.rs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct GameRootNode;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct GameScreenRoot;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct StartScreenRoot;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct DynamicMenuText {
|
||||||
|
pub text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct StartButtonText;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct FpsText;
|
||||||
3
src/lib.rs
Normal file
3
src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
pub mod components;
|
||||||
|
pub mod plugins;
|
||||||
|
pub mod states;
|
||||||
30
src/main.rs
Normal file
30
src/main.rs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy_aseprite_ultra::prelude::*;
|
||||||
|
use bevy_dev_tools::fps_overlay::*;
|
||||||
|
use pomomon_garden::plugins;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
App::new()
|
||||||
|
.add_plugins((
|
||||||
|
DefaultPlugins.set(ImagePlugin::default_nearest()),
|
||||||
|
AsepriteUltraPlugin,
|
||||||
|
))
|
||||||
|
.add_plugins((FpsOverlayPlugin {
|
||||||
|
config: FpsOverlayConfig {
|
||||||
|
refresh_interval: core::time::Duration::from_millis(100),
|
||||||
|
enabled: true,
|
||||||
|
frame_time_graph_config: FrameTimeGraphConfig {
|
||||||
|
enabled: true,
|
||||||
|
min_fps: 30.0,
|
||||||
|
target_fps: 144.0,
|
||||||
|
},
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
},))
|
||||||
|
.add_plugins((
|
||||||
|
plugins::CorePlugin,
|
||||||
|
plugins::StartScreenPlugin,
|
||||||
|
plugins::GameScreenPlugin,
|
||||||
|
))
|
||||||
|
.run();
|
||||||
|
}
|
||||||
15
src/plugins/core.rs
Normal file
15
src/plugins/core.rs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
use crate::states::*;
|
||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
pub struct CorePlugin;
|
||||||
|
|
||||||
|
impl Plugin for CorePlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
app.add_systems(Startup, setup_camera);
|
||||||
|
app.init_state::<AppState>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_camera(mut commands: Commands) {
|
||||||
|
commands.spawn(Camera2d::default());
|
||||||
|
}
|
||||||
24
src/plugins/game_screen.rs
Normal file
24
src/plugins/game_screen.rs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
use crate::states::*;
|
||||||
|
use bevy::prelude::*;
|
||||||
|
use bevy_aseprite_ultra::prelude::*;
|
||||||
|
|
||||||
|
pub struct GameScreenPlugin;
|
||||||
|
|
||||||
|
impl Plugin for GameScreenPlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
app.add_systems(OnEnter(AppState::GameScreen), setup);
|
||||||
|
app.add_systems(OnExit(AppState::GameScreen), cleanup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
|
commands.spawn((
|
||||||
|
AseAnimation {
|
||||||
|
aseprite: asset_server.load("pom-sleep.aseprite"),
|
||||||
|
animation: Animation::tag("sleep-sit-start").with_repeat(AnimationRepeat::Loop),
|
||||||
|
},
|
||||||
|
Sprite::default(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cleanup() {}
|
||||||
7
src/plugins/mod.rs
Normal file
7
src/plugins/mod.rs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
pub mod core;
|
||||||
|
pub mod game_screen;
|
||||||
|
pub mod start_screen;
|
||||||
|
|
||||||
|
pub use core::CorePlugin;
|
||||||
|
pub use game_screen::GameScreenPlugin;
|
||||||
|
pub use start_screen::StartScreenPlugin;
|
||||||
83
src/plugins/start_screen.rs
Normal file
83
src/plugins/start_screen.rs
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
use crate::states::*;
|
||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
pub struct StartScreenPlugin;
|
||||||
|
|
||||||
|
impl Plugin for StartScreenPlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
app.add_systems(OnEnter(AppState::StartScreen), setup);
|
||||||
|
app.add_systems(OnExit(AppState::StartScreen), cleanup);
|
||||||
|
app.add_systems(Update, menu.run_if(in_state(AppState::StartScreen)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
struct MenuData {
|
||||||
|
button_entity: Entity,
|
||||||
|
}
|
||||||
|
|
||||||
|
const NORMAL_BUTTON: Color = Color::srgb(0.15, 0.15, 0.15);
|
||||||
|
const HOVERED_BUTTON: Color = Color::srgb(0.25, 0.25, 0.25);
|
||||||
|
const PRESSED_BUTTON: Color = Color::srgb(0.35, 0.75, 0.35);
|
||||||
|
|
||||||
|
fn setup(mut commands: Commands) {
|
||||||
|
let button_entity = commands
|
||||||
|
.spawn((
|
||||||
|
Node {
|
||||||
|
width: percent(100),
|
||||||
|
height: percent(100),
|
||||||
|
justify_content: JustifyContent::Center,
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
children![(
|
||||||
|
Button,
|
||||||
|
Node {
|
||||||
|
width: px(150),
|
||||||
|
height: px(65),
|
||||||
|
justify_content: JustifyContent::Center,
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
BackgroundColor(NORMAL_BUTTON),
|
||||||
|
children![(
|
||||||
|
Text::new("Play"),
|
||||||
|
TextFont {
|
||||||
|
font_size: 33.0,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
TextColor(Color::srgb(0.9, 0.9, 0.9))
|
||||||
|
)]
|
||||||
|
)],
|
||||||
|
))
|
||||||
|
.id();
|
||||||
|
|
||||||
|
commands.insert_resource(MenuData { button_entity });
|
||||||
|
}
|
||||||
|
|
||||||
|
fn menu(
|
||||||
|
mut next_state: ResMut<NextState<AppState>>,
|
||||||
|
mut interaction_query: Query<
|
||||||
|
(&Interaction, &mut BackgroundColor),
|
||||||
|
(Changed<Interaction>, With<Button>),
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
for (interaction, mut color) in &mut interaction_query {
|
||||||
|
match *interaction {
|
||||||
|
Interaction::Pressed => {
|
||||||
|
*color = PRESSED_BUTTON.into();
|
||||||
|
next_state.set(AppState::GameScreen);
|
||||||
|
}
|
||||||
|
Interaction::Hovered => {
|
||||||
|
*color = HOVERED_BUTTON.into();
|
||||||
|
}
|
||||||
|
Interaction::None => {
|
||||||
|
*color = NORMAL_BUTTON.into();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cleanup(mut commands: Commands, menu_data: Res<MenuData>) {
|
||||||
|
commands.entity(menu_data.button_entity).despawn();
|
||||||
|
}
|
||||||
8
src/states.rs
Normal file
8
src/states.rs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
#[derive(States, Clone, PartialEq, Eq, Debug, Hash, Default, Reflect)]
|
||||||
|
pub enum AppState {
|
||||||
|
#[default]
|
||||||
|
StartScreen,
|
||||||
|
GameScreen,
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user