Skip to content
This repository was archived by the owner on Oct 25, 2021. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@

# IntelliJ folder
.idea

*.iml
Binary file added resources/assets/night_ambient.ogg
Binary file not shown.
30 changes: 15 additions & 15 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,7 @@ extern crate amethyst_derive;

use amethyst;
use amethyst::assets::PrefabLoaderSystem;
use amethyst::{
audio::AudioBundle,
core::frame_limiter::FrameRateLimitStrategy,
core::transform::{Transform, TransformBundle},
core::Named,
ecs::*,
input::InputBundle,
prelude::*,
renderer::*,
ui::{DrawUi, NoCustomUi, UiBundle, UiTransform},
utils::application_root_dir,
};
use amethyst::{audio::AudioBundle, core::frame_limiter::FrameRateLimitStrategy, core::transform::{Transform, TransformBundle}, core::Named, ecs::*, input::InputBundle, prelude::*, renderer::*, ui::{DrawUi, NoCustomUi, UiBundle, UiTransform}, utils::application_root_dir, LoggerConfig};

mod components;
mod resources;
Expand All @@ -28,6 +17,7 @@ use crate::components::creatures::{self, IntelligenceTag, Movement, Wander};
use crate::components::digestion::{Digestion, Fullness, Nutrition};
use crate::resources::audio::Music;
use crate::states::{loading::LoadingState, CustomStateEvent, CustomStateEventReader};
use crate::systems::day_night_cycle::DayNightCycle;

amethyst_inspector::inspector![
Named,
Expand All @@ -49,7 +39,12 @@ amethyst_inspector::inspector![
];

fn main() -> amethyst::Result<()> {
amethyst::start_logger(Default::default());
amethyst::start_logger(LoggerConfig {
stdout: amethyst::StdoutLog::Colored,
level_filter: amethyst::LogLevelFilter::Off,
log_file: None,
allow_env_override: true,
});

let resources = application_root_dir().clone() + "/resources";
let display_config_path = resources.clone() + "/display_config.ron";
Expand Down Expand Up @@ -90,7 +85,7 @@ fn main() -> amethyst::Result<()> {
&[],
)
.with_bundle(TransformBundle::new())?
.with_bundle(AudioBundle::new(|music: &mut Music| music.music.next()))?
.with_bundle(AudioBundle::new(|music: &mut Music| music.get_current()))?
.with(
amethyst_inspector::InspectorHierarchy::default(),
"inspector_hierarchy",
Expand All @@ -104,7 +99,12 @@ fn main() -> amethyst::Result<()> {
&["imgui_begin"],
)
.with_bundle(RenderBundle::new(pipe, Some(display_config)))?
.with_bundle(UiBundle::<String, String, NoCustomUi>::new())?;
.with_bundle(UiBundle::<String, String, NoCustomUi>::new())?
.with(
DayNightCycle::new(),
"day_night_cycle",
&[]
);

// Set up the core application with a custom state event that allows us to access input events
// in the game states. The `CustomStateEventReader` is automatically derived based on `CustomStateEvent`.
Expand Down
36 changes: 27 additions & 9 deletions src/resources/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,30 @@ use amethyst::{

use std::iter::Cycle;
use std::vec::IntoIter;
use std::collections::HashMap;

const BACKGROUND_MUSIC: &'static [&'static str] = &["assets/ambient.ogg"];
const DAY_BACKGROUND_MUSIC: &'static str = "assets/day_ambient.ogg";
const NIGHT_BACKGROUND_MUSIC: &'static str = "assets/night_ambient.ogg";

#[derive(Default)]
pub struct Music {
pub music: Cycle<IntoIter<SourceHandle>>,

pub musics: HashMap<String, SourceHandle>,
pub current_music: Option<String>,
}

impl Music {
pub fn get_current(& self) -> Option<SourceHandle>{
match &self.current_music {
None => {None},
Some(cur) => {self.musics.get(cur).cloned()},
}

}

pub fn set_current(&mut self, new_music_name: Option<String>){
self.current_music = new_music_name;
}
}

fn load_audio_track(loader: &Loader, world: &World, file: &str) -> SourceHandle {
Expand All @@ -25,14 +44,13 @@ pub fn initialise_audio(world: &mut World) {
let mut sink = world.write_resource::<AudioSink>();
sink.set_volume(0.25);

let music = BACKGROUND_MUSIC
.iter()
.map(|file| load_audio_track(&loader, &world, &file))
.collect::<Vec<_>>()
.into_iter()
.cycle();

Music { music }

let mut musics = HashMap::new();
musics.insert("day".into(), load_audio_track(&loader, &world, DAY_BACKGROUND_MUSIC));
musics.insert("night".into(), load_audio_track(&loader, &world, NIGHT_BACKGROUND_MUSIC));

Music { musics: musics, current_music: Some("day".into()), }
};

// Add sounds to the world
Expand Down
64 changes: 64 additions & 0 deletions src/systems/day_night_cycle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use amethyst::{
core::{Time},
ecs::*,
audio::{SourceHandle},
};

use crate::Music;

pub struct DayNightCycle{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If data is stored in a system, it can only be read or changed by the system or by re-registering the system in the dispatcher. If we add a UI displaying the elapsed cycle time, or if we want to add debug utilities to change the cycle time, we have to change the implementation.

So imo we should not store data in systems, to begin with. Two possible solutions are to store the data in one or multiple components and attach them to an entity. The system would only store the entity so that it can access the components. The second solution would be to store the data as a Resource.

Personally, I dislike storing data in resources because they are less flexible than components.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is more flexible about entities/component compared to resources?
The way I understood it is that Resources are for "singletons" while entities are for things that have multiple instances.

pub cycle_time: f32,
pub elapsed_cycle_time: f32,
pub current_cycle: CycleState,
pub cycle_data: CycleData,
}

impl DayNightCycle {
pub fn new() -> Self {
DayNightCycle{
cycle_time: 6.0, // FIXME 1 second for testing
current_cycle : CycleState::Day,
elapsed_cycle_time: 0.0,
cycle_data: CycleData {
day_music_name: "day".into(),
night_music_name: "night".into(),
}
}
}
}

#[derive(Copy,Clone,Debug)]
pub enum CycleState{
Day,
Night,
}

pub struct CycleData{
pub day_music_name: String,
pub night_music_name: String,
}

impl<'s> System<'s> for DayNightCycle{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might make sense to split this up into two systems. One that determines if it is day or night and one that switches the music based on that.
The system switching the music could be event driven. The system determining if it is day or night would dispatch an event with the CycleState as the payload.
The advantage of splitting that is that you'd be able to enable/disable individual systems for faster prototyping. In addition, other effects of the day/night cycle don't need to modify existing systems but can be built on top.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thanks! I'll look into events :)

type SystemData = ( Read<'s, Time>, Write<'s, Music> );


fn run(&mut self, (time, mut music): Self::SystemData) {
self.elapsed_cycle_time += time.delta_real_seconds();
if self.elapsed_cycle_time >= self.cycle_time {
dbg!(&self.current_cycle);
match self.current_cycle {
CycleState::Day => {
self.current_cycle = CycleState::Night;
music.set_current(Some(self.cycle_data.night_music_name.clone()));

},
CycleState::Night => {
self.current_cycle = CycleState::Day;
music.set_current(Some(self.cycle_data.day_music_name.clone()));
},
}
self.elapsed_cycle_time = 0.0;
}
}

}
1 change: 1 addition & 0 deletions src/systems/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod behaviors;
pub mod camera_movement;
pub mod collision;
pub mod combat;
pub mod day_night_cycle;
pub mod debug;
pub mod digestion;
pub mod health;
Expand Down