Bladeren bron

:tada: first commit, logo animation

Felix Bytow 2 jaren geleden
commit
49d5430ba0
7 gewijzigde bestanden met toevoegingen van 196 en 0 verwijderingen
  1. 10 0
      .gitignore
  2. 17 0
      Cargo.toml
  3. BIN
      assets/images/logo.jpg
  4. 1 0
      src/assets.rs
  5. 136 0
      src/game_state/logo.rs
  6. 7 0
      src/game_state/mod.rs
  7. 25 0
      src/main.rs

+ 10 - 0
.gitignore

@@ -0,0 +1,10 @@
+# Rust
+/target/
+Cargo.lock
+
+# CLion/IDEA
+*.iml
+.idea/
+
+# MacOS
+.DS_Store

+ 17 - 0
Cargo.toml

@@ -0,0 +1,17 @@
+[package]
+name = "bevy-idle"
+description = "IDLE RPG using the Bevy Engine"
+authors = ["Felix Bytow <drako@drako.guru>"]
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+bevy = { version = "0.7.0", features = ["jpeg"] }
+
+[profile.dev]
+opt-level = 1
+
+[profile.dev.package."*"]
+opt-level = 3

BIN
assets/images/logo.jpg


+ 1 - 0
src/assets.rs

@@ -0,0 +1 @@
+pub const LOGO: &'static str = "images/logo.jpg";

+ 136 - 0
src/game_state/logo.rs

@@ -0,0 +1,136 @@
+use bevy::core::Stopwatch;
+use bevy::prelude::*;
+
+use crate::assets::LOGO;
+use crate::game_state::GameState;
+
+#[derive(Clone, Debug)]
+pub struct LogoFilename(pub String);
+
+#[derive(Component)]
+struct Logo;
+
+#[derive(Component)]
+struct LogoFader {
+    time: Stopwatch,
+}
+
+// Logo should take 10 seconds
+const LOGO_DURATION: f32 = 10.0;
+
+pub struct LogoPlugin;
+
+fn logo_filename(filename: Option<Res<LogoFilename>>) -> String {
+    filename.map_or_else(|| LOGO.to_string(), |res| res.0.clone())
+}
+
+fn setup_logo(
+    mut commands: Commands,
+    filename: Option<Res<LogoFilename>>,
+    assert_server: Res<AssetServer>,
+    windows: Res<Windows>,
+) {
+    let path = logo_filename(filename);
+    let window = windows.primary();
+    let (win_w, win_h) = (window.width(), window.height());
+
+    commands
+        .spawn()
+        .insert(Logo)
+        .insert_bundle(SpriteBundle {
+            texture: assert_server.load(&path),
+            transform: Transform {
+                translation: Vec3::new(0.0, 0.0, 0.0),
+                ..Default::default()
+            },
+            ..Default::default()
+        });
+
+    commands
+        .spawn()
+        .insert(LogoFader { time: Stopwatch::new() })
+        .insert_bundle(SpriteBundle {
+            sprite: Sprite {
+                color: Color::rgba(0.0, 0.0, 0.0, 0.0),
+                custom_size: Some(Vec2::new(win_w, win_h)),
+                ..Default::default()
+            },
+            transform: Transform {
+                translation: Vec3::new(0.0, 0.0, 1.0),
+                ..Default::default()
+            },
+            ..Default::default()
+        });
+}
+
+fn resize_logo(
+    mut query: Query<&mut Transform, With<Logo>>,
+    filename: Option<Res<LogoFilename>>,
+    windows: Res<Windows>,
+    images: Res<Assets<Image>>,
+) {
+    let mut logo_transform = query.single_mut();
+    let window = windows.primary();
+    let (win_w, win_h) = (window.width(), window.height());
+    let win_aspect = win_w / win_h;
+
+    if let Some(logo_image) = images.get(logo_filename(filename)) {
+        let size = logo_image.size();
+        let (logo_w, logo_h) = (size.x, size.y);
+        let logo_aspect = logo_w / logo_h;
+
+        let scale = if win_aspect > logo_aspect {
+            win_h / logo_h
+        } else {
+            win_w / logo_w
+        };
+
+        logo_transform.scale.x = scale;
+        logo_transform.scale.y = scale;
+    }
+}
+
+fn resize_fader(
+    mut query: Query<&mut Sprite, With<LogoFader>>,
+    windows: Res<Windows>,
+) {
+    let mut sprite = query.single_mut();
+    let window = windows.primary();
+    sprite.custom_size = Some(Vec2::new(window.width(), window.height()));
+}
+
+fn animate_logo(
+    mut query: Query<(&mut Sprite, &mut LogoFader)>,
+    mut game_state: ResMut<State<GameState>>,
+    time: Res<Time>,
+) {
+    let (mut sprite, mut fader) = query.single_mut();
+    let timer: &mut Stopwatch = &mut fader.time;
+    timer.tick(time.delta());
+
+    let progress = timer.elapsed_secs();
+
+    if progress < LOGO_DURATION * 0.4 {
+        sprite.color = Color::rgba(0.0, 0.0, 0.0, (progress * std::f32::consts::PI / (LOGO_DURATION * 0.8)).cos());
+    } else if progress >= LOGO_DURATION * 0.4 && progress < LOGO_DURATION * 0.6 {
+        sprite.color = Color::rgba(0.0, 0.0, 0.0, 0.0);
+    } else if progress >= LOGO_DURATION * 0.6 && progress < LOGO_DURATION {
+        sprite.color = Color::rgba(0.0, 0.0, 0.0, ((progress - LOGO_DURATION * 0.2) * std::f32::consts::PI / (LOGO_DURATION * 0.8)).cos().abs());
+    } else {
+        game_state.set(GameState::MainMenu).unwrap();
+        sprite.color = Color::rgba(0.0, 0.0, 0.0, 1.0);
+    }
+}
+
+impl Plugin for LogoPlugin {
+    fn build(&self, app: &mut App) {
+        let state = GameState::Logo;
+        app.add_state(state);
+        app.add_system_set(SystemSet::on_enter(state).with_system(setup_logo));
+        app.add_system_set(SystemSet::on_update(state)
+            .with_system(resize_logo)
+            .with_system(animate_logo)
+            .with_system(resize_fader)
+        );
+    }
+}

+ 7 - 0
src/game_state/mod.rs

@@ -0,0 +1,7 @@
+pub mod logo;
+
+#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
+pub enum GameState {
+    Logo,
+    MainMenu,
+}

+ 25 - 0
src/main.rs

@@ -0,0 +1,25 @@
+use bevy::prelude::*;
+use bevy::window::PresentMode;
+
+pub mod game_state;
+pub mod assets;
+
+fn setup_2d_camera(mut commands: Commands) {
+    commands.spawn_bundle(OrthographicCameraBundle::new_2d());
+}
+
+fn main() {
+    App::new()
+        .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)))
+        .insert_resource(WindowDescriptor {
+            title: "Bevy-Idle".to_string(),
+            width: 1600.0,
+            height: 900.0,
+            present_mode: PresentMode::Immediate,
+            ..WindowDescriptor::default()
+        })
+        .add_plugins(DefaultPlugins)
+        .add_startup_system(setup_2d_camera)
+        .add_plugin(game_state::logo::LogoPlugin)
+        .run();
+}