diff --git a/difficult_prepare/difficult_plot.py b/difficult_prepare/difficult_plot.py new file mode 100644 index 0000000..0fa2362 --- /dev/null +++ b/difficult_prepare/difficult_plot.py @@ -0,0 +1,25 @@ +import numpy as np +import matplotlib.pyplot as plt + +level_time = 4 * 60 + +l = 20 +s_d = 45.0 * 1000.0 / 3600.0 +s_s = s_d * 0.5 * 0.2 + +print("Sheep time:", l / s_s) +print("Dog max travel time:", 2 * np.pi * l / s_d) + +hardness = np.linspace(0.05, 1.0, 100) +k_h = 1.5 + +param_curve = l / s_s - 2 * np.pi * l / s_d - 1 / k_h / hardness + +delta_t = 10 +c = 10 + +n = (param_curve + delta_t) / np.sqrt(c) + +plt.plot(hardness, n) +plt.grid() +plt.show() \ No newline at end of file diff --git a/src/level_ui.rs b/src/level_ui.rs new file mode 100644 index 0000000..3c40e71 --- /dev/null +++ b/src/level_ui.rs @@ -0,0 +1,59 @@ +use bevy::prelude::*; + +use crate::storyteller::LevelTimer; + +pub struct LevelUiPlugin; + +impl Plugin for LevelUiPlugin { + fn build(&self, app: &mut App) { + app.add_event::() + .add_systems(Update, create_level_ui_system); + } +} + +#[derive(Event)] +pub struct CreateLevelUi; + +#[derive(Component)] +pub struct LevelUi; + +fn create_level_ui_system( + mut commands: Commands, + asset_server: Res, + mut ev_create_level_ui: EventReader, +) { + if ev_create_level_ui.is_empty() { + return; + } + + let mut text_style = TextStyle::default(); + text_style.font_size = 24.0; + + //Spawn top info bar + commands.spawn((NodeBundle { + style: Style { + width: Val::Percent(100.0), + height: Val::Px(50.0), + flex_direction: FlexDirection::Row, + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, + + align_self: AlignSelf::Stretch, + ..default() + }, + ..default() + }, + LevelUi + )).with_children(|parent| { + parent.spawn(( + TextBundle::from_section( + "", + text_style.clone() + ), + LevelUi, + LevelTimer + )); + }); + + ev_create_level_ui.clear(); +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index ef4cd00..43e1731 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,8 @@ pub mod sheep; pub mod sprite_material; pub mod test_level; pub mod torch; +pub mod storyteller; +pub mod level_ui; use std::f32::consts::PI; @@ -53,6 +55,8 @@ impl Plugin for GamePlugin { safe_area::SafeAreaPlugin, sprite_material::SpriteMaterialPlugin, sheep::SheepPlugin, + storyteller::StorytellerPlugin, + level_ui::LevelUiPlugin, )); //For long term updates diff --git a/src/sheep.rs b/src/sheep.rs index 8bb6779..11aa070 100644 --- a/src/sheep.rs +++ b/src/sheep.rs @@ -21,12 +21,12 @@ use bevy_spatial::{ const SHEEP_PATH: &str = "test/sheep.png"; -const SHEEP_SPEED: f32 = DOG_SPEED * 0.5; +pub const SHEEP_SPEED: f32 = DOG_SPEED * 0.5; const SHEEP_ACCELERATION: f32 = SHEEP_SPEED * 3.0; const RANDOM_WALK_RANGE: f32 = 5.0; const RANDOM_WALK_ACCEPT_RADIUS: f32 = 0.5; -const RANDOM_WALK_SPEED_MULTIPLIER: f32 = 0.2; +pub const RANDOM_WALK_SPEED_MULTIPLIER: f32 = 0.2; //IDLE FEEDING must be large enough so that player can see sheep and react for escapes const IDLE_FEEDING_TIME: f32 = 5.0; @@ -49,7 +49,9 @@ impl Plugin for SheepPlugin { //random walk app.add_event::() - .add_systems(Update, (init_random_walk, goto_system)); + .add_systems(Update, (init_random_walk, )); + + app.add_systems(Update, (goto_system,)); //idle feeding app.add_systems(Update, idle_feeding_system); @@ -117,8 +119,6 @@ impl Default for StateChance { next_state: vec![ (1.0, Decision::Feed), //zero values for unimplemented things (0.5, Decision::RandomWalk), - (0.5, Decision::MoveToSafeArea), - (0.5, Decision::Escape), ], }; res.normalize(); @@ -521,7 +521,7 @@ fn collect_field( let around_mean_vel = sum / (count as f32); let dv = around_mean_vel - vel.0; walk.target_velocity = - vel.0 + 0.5 * dv + 0.9 * distance_force + Vec3::new(0.0, 0.0, sum_dz); + vel.0 + 0.9 * distance_force + Vec3::new(0.0, 0.0, sum_dz); } else { walk.target_velocity = vel.0; } diff --git a/src/storyteller.rs b/src/storyteller.rs new file mode 100644 index 0000000..3ee62f2 --- /dev/null +++ b/src/storyteller.rs @@ -0,0 +1,133 @@ +//This global AI is responsible for creating problems for player +//This module will be determine where and how sheep will be try to escape from safe zone + +use std::{f32::consts::{PI, E}, time::Duration}; + +use bevy::prelude::*; +use rand::Rng; + +use crate::{sheep::{Sheep, SHEEP_SPEED, RANDOM_WALK_SPEED_MULTIPLIER, GoTo}, test_level::LevelSize, player::DOG_SPEED}; + +pub struct StorytellerPlugin; + +impl Plugin for StorytellerPlugin { + fn build(&self, app: &mut App) { + app + .insert_resource(Storyteller { + level_start_time : 0.0, + level_duration : 4.0 * 60.0, + next_wave : None + }) + .add_systems(Update, ( + storyteller_system, + level_timer + )) + .add_systems(PostStartup, setup_start_time); + } +} + +#[derive(Debug, Clone)] +pub struct SheepWave { + pub count : usize, + pub beams : usize, + pub time : f32 +} + +#[derive(Resource)] +pub struct Storyteller { + pub level_start_time : f32, + pub level_duration : f32, + pub next_wave : Option +} + +fn setup_start_time( + mut teller : ResMut, + time : Res