Skip to content

Commit

Permalink
Daynight cycle, shepherd base, auto ignight logic
Browse files Browse the repository at this point in the history
  • Loading branch information
rewin123 committed Dec 9, 2023
1 parent 3835dbc commit 3592e63
Show file tree
Hide file tree
Showing 10 changed files with 330 additions and 36 deletions.
1 change: 1 addition & 0 deletions assets/credits.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Knight - https://aamatniekss.itch.io/fantasy-knight-free-pixelart-animated-character
Binary file added assets/test/Knight.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 0 additions & 5 deletions src/debug_diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ impl Plugin for DiagnosticPlugin {
Update,
(fps_counting, sheep_counter_text, alive_sheep_counter).in_set(GameSet::Playing),
);

#[cfg(feature = "dev")]
{
app.add_plugins(bevy_inspector_egui::quick::WorldInspectorPlugin::default());
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub mod storyteller;
pub mod test_level;
pub mod torch;
pub mod wolf;
pub mod sunday;
pub mod shepherd;

use std::f32::consts::PI;

Expand Down Expand Up @@ -99,6 +101,8 @@ impl Plugin for GamePlugin {
wolf::WolfPlugin,
menu::MenuPlugin,
finish_screen::FinishScreenPlugin,
sunday::SundayPlugin,
shepherd::ShepherdPlugin,
));

//For long term updates
Expand Down
16 changes: 14 additions & 2 deletions src/player.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy::{input::mouse::MouseWheel, prelude::*, window::PrimaryWindow};
use bevy::{input::mouse::MouseWheel, prelude::*, window::PrimaryWindow, pbr::{CascadeShadowConfig, CascadeShadowConfigBuilder}};

use crate::{
get_sprite_rotation,
Expand Down Expand Up @@ -168,7 +168,7 @@ pub fn bark(
return;
};

if input.just_pressed(KeyCode::Space) {
if input.pressed(KeyCode::Space) {
event_writer.send(Bark {
radius: 10.,
position: bark.translation,
Expand Down Expand Up @@ -224,6 +224,7 @@ fn camera_movement(
player_query: Query<&Transform, (With<Player>, Without<Camera>)>,
time: Res<Time>,
mut scroll_evr: EventReader<MouseWheel>,
mut sun : Query<&mut CascadeShadowConfig>
) {
let Ok((mut camera, mut distance)) = camera_query.get_single_mut() else {
return;
Expand All @@ -232,6 +233,11 @@ fn camera_movement(
return;
};


let Ok(mut sun) = sun.get_single_mut() else {
return;
};

for ev in scroll_evr.read() {
let delta = ev.y;
if delta < 0.0 {
Expand All @@ -241,6 +247,11 @@ fn camera_movement(
}

distance.0 = distance.0.clamp(10.0, 150.0);


let mut cascade = CascadeShadowConfigBuilder::default();
cascade.maximum_distance = distance.0 * 2.0;
*sun = cascade.build();
}

let cam_frw = camera.forward();
Expand All @@ -256,6 +267,7 @@ fn set_cam_distance(
mut commands: Commands,
camera_without_dist: Query<(Entity, &Transform), (With<Camera>, Without<CameraDistance>)>,
player_query: Query<&Transform, With<Player>>,
mut sun : Query<&mut CascadeShadowConfig>
) {
let Ok(player) = player_query.get_single() else {
return;
Expand Down
113 changes: 113 additions & 0 deletions src/shepherd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
use bevy::{prelude::*, reflect::EnumInfo};

use crate::{player::{DOG_SPEED, DOG_ACCELERATION}, common_storage::CommonStorage, get_sprite_rotation, physics::{Velocity, WalkController}, GameSet, torch::{TorchBase, IgniteTorch}, sunday::DayState};

const SHEPHERD_PATH: &str = "test/Knight.png";

const SHEPHERD_SPEED: f32 = DOG_SPEED;
const SHEPHERD_ACCEL: f32 = DOG_ACCELERATION;

const IGNITE_RADIUS: f32 = 5.0;

pub struct ShepherdPlugin;

impl Plugin for ShepherdPlugin {
fn build(&self, app: &mut App) {
app
.add_event::<SpawnShepherd>()
.add_systems(Update, (
spawn_shepherd_system,
ignite_all_torhes,
).in_set(GameSet::Playing)
)
.add_systems(OnEnter(DayState::Evening), start_ignite_torches);
}
}

#[derive(Event)]
pub struct SpawnShepherd {
pub pos: Vec3,
}

#[derive(Component, Default)]
pub struct Shepherd;

#[derive(Component)]
pub struct IgniteAllTorhes;

fn start_ignite_torches(
mut commands: Commands,
query : Query<Entity, With<Shepherd>>
) {
if let Ok(entity) = query.get_single() {
commands.entity(entity).insert(IgniteAllTorhes);
}
}

fn ignite_all_torhes(
mut commands: Commands,
mut query : Query<(Entity, &mut WalkController, &Transform), With<IgniteAllTorhes>>,
torches : Query<(&Transform, &TorchBase)>,
mut ignite : EventWriter<IgniteTorch>
) {
let Ok((herd_entity, mut walk_controller, transform)) = query.get_single_mut() else {
return;
};

//find nearest torch
let mut nearest_torch : Option<Vec3> = None;
let mut nearest_torch_data : Option<&TorchBase> = None;
let mut dist = f32::MAX;
for (torch_transform, torch) in torches.iter() {
let dist_to_torch = (torch_transform.translation - transform.translation).length();
if dist_to_torch < dist && !torch.lit {
nearest_torch = Some(torch_transform.translation);
nearest_torch_data = Some(torch);
dist = dist_to_torch;
}
}

if let Some(nearest_torch) = nearest_torch {
if dist < IGNITE_RADIUS {
ignite.send(IgniteTorch {
position: transform.translation,
radius: IGNITE_RADIUS
});
} else {
walk_controller.target_velocity = (nearest_torch - transform.translation).normalize() * SHEPHERD_SPEED;
}
} else {
commands.entity(herd_entity).remove::<IgniteAllTorhes>();
walk_controller.target_velocity = Vec3::ZERO;
}
}

fn spawn_shepherd_system(
mut commands: Commands,
mut events: EventReader<SpawnShepherd>,
asset_server: Res<AssetServer>,
common_storage : Res<CommonStorage>,
mut materials : ResMut<Assets<StandardMaterial>>,
) {
for event in events.read() {
commands.spawn((
Shepherd::default(),
PbrBundle {
transform: Transform::from_translation(event.pos).with_rotation(get_sprite_rotation()).with_scale(Vec3::new(1.0, 1.0, 2.0)),
material: materials.add(StandardMaterial {
base_color_texture: Some(asset_server.load(SHEPHERD_PATH)),
..default()
}),
mesh: common_storage.plane.clone(),
..default()
},
Velocity::default(),
WalkController {
max_speed: SHEPHERD_SPEED,
acceleration: SHEPHERD_ACCEL,
target_velocity: Vec3::ZERO,
}
));
}
events.clear();
}
10 changes: 10 additions & 0 deletions src/storyteller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ pub struct Storyteller {
pub next_wave: Option<SheepWave>,
}

impl Storyteller {
pub fn get_level_time(&self, time : &Time) -> f32 {
time.elapsed_seconds() - self.level_start_time
}

pub fn get_level_unfirom_time(&self, time : &Time) -> f32 {
self.get_level_time(time) / self.level_duration
}
}

#[derive(Resource, Default)]
pub struct Score(pub f32);

Expand Down
119 changes: 119 additions & 0 deletions src/sunday.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
use std::f32::consts::PI;

use bevy::prelude::*;

use crate::{storyteller::Storyteller, GameSet};

pub struct SundayPlugin;

pub const DAY_SUN_COLOR: &str = "f2ecbe";
pub const EVENING_SUN_COLOR: &str = "cfaf56";
pub const DUSK_SUN_COLOR: &str = "f2ecbe";
pub const NIGHT_SUN_COLOR: &str = "506886";

pub const SUN_BASE_ILLUMINANCE: f32 = 50000.0;
pub const AMBIENT_BASE_ILLUMINANCE: f32 = 1.0;

pub const SUN_EVENING_ILLUMINANCE: f32 = 10000.0;
pub const SUN_DUSK_ILLUMINANCE: f32 = 10000.0;
pub const SUN_NIGHT_ILLUMINANCE: f32 = 10000.0;

pub const AMBIENT_DAY_COLOR: &str = "2ba4a9";
pub const AMBIENT_NIGHT_COLOR: &str = "643a69";

pub const AMBIENT_DAY_ILLUMINANCE: f32 = 1.0;
pub const AMBIENT_NIGHT_ILLUMINANCE: f32 = 0.1;

const DAY_TIME: f32 = 0.3;
const EVENING_TIME: f32 = 0.6;
const NIGHT_TIME: f32 = 0.7;

impl Plugin for SundayPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, sunday_system.in_set(GameSet::Playing));
app.add_systems(Update, set_day_state.in_set(GameSet::Playing));
app.add_state::<DayState>();
}
}

#[derive(States, Debug, Clone, Copy, Eq, PartialEq, Hash, Default)]
pub enum DayState {
#[default]
Day,
Evening,
Night,
}

fn set_day_state(
mut state : ResMut<NextState<DayState>>,
current_state : Res<State<DayState>>,
teller : Res<Storyteller>,
time : Res<Time>
) {
let uniform_time = teller.get_level_unfirom_time(&time);
if uniform_time < DAY_TIME {
if *current_state != DayState::Day {
state.set(DayState::Day);
}
} else if uniform_time < EVENING_TIME {
if *current_state != DayState::Evening {
state.set(DayState::Evening);
}
} else if uniform_time < NIGHT_TIME {
if *current_state != DayState::Night {
state.set(DayState::Night);
}
}
}

fn sunday_system(
time: Res<Time>,
teller : Res<Storyteller>,
mut sun : Query<(&mut Transform, &mut DirectionalLight)>,
mut ambient_light: ResMut<AmbientLight>
) {
let Ok((mut transform, mut light)) = sun.get_single_mut() else {
warn!("Could not get directional light");
return;
};

let uniform_time = teller.get_level_unfirom_time(&time);

if uniform_time < DAY_TIME {
let sun_falloff = 1.0;
ambient_light.color = Color::hex(AMBIENT_DAY_COLOR).unwrap();
let sun_angle = sun_falloff * std::f32::consts::PI / 4.0;
let pos = transform.translation.clone();
transform.look_at(pos + Vec3::new(-(PI / 4.0).cos(), -sun_angle.sin(), -sun_angle.cos()), Vec3::Y);

} else if uniform_time < EVENING_TIME {
let sun_falloff = 1.0 - (uniform_time - DAY_TIME) / (EVENING_TIME - DAY_TIME);
let color =
Color::hex(DAY_SUN_COLOR).unwrap() * sun_falloff
+ Color::hex(EVENING_SUN_COLOR).unwrap() * (1.0 - sun_falloff);
let sun_angle = sun_falloff * std::f32::consts::PI / 4.0;
let illuminance = SUN_BASE_ILLUMINANCE * sun_falloff + SUN_EVENING_ILLUMINANCE * (1.0 - sun_falloff);

let pos = transform.translation.clone();
transform.look_at(pos + Vec3::new(-(PI / 4.0).cos(), -sun_angle.sin(), -sun_angle.cos()), Vec3::Y);
light.color = color;
light.illuminance = illuminance;

ambient_light.color = Color::hex(AMBIENT_DAY_COLOR).unwrap();
} else if uniform_time < NIGHT_TIME {
let sun_falloff = 1.0 - (uniform_time - EVENING_TIME) / (NIGHT_TIME - EVENING_TIME);
let color = Color::hex(NIGHT_SUN_COLOR).unwrap();
let sun_angle = (1.0 - sun_falloff) * std::f32::consts::PI / 4.0;
let illuminance = SUN_NIGHT_ILLUMINANCE;
let pos = transform.translation.clone();
transform.look_at(pos + Vec3::new(-(PI / 4.0).cos(), -sun_angle.sin(), -sun_angle.cos()), Vec3::Y);
light.color = color;
light.illuminance = illuminance;

ambient_light.color =
Color::hex(AMBIENT_NIGHT_COLOR).unwrap() * (1.0 - sun_falloff) + Color::hex(AMBIENT_DAY_COLOR).unwrap() * sun_falloff;
ambient_light.brightness = AMBIENT_NIGHT_ILLUMINANCE * (1.0 - sun_falloff) + sun_falloff * AMBIENT_DAY_ILLUMINANCE;
} else {

}
}
Loading

0 comments on commit 3592e63

Please sign in to comment.