allow loading animations to be contributed from a manifest file

This commit is contained in:
Vincent Foulon 2021-03-17 23:41:28 +01:00
parent 62b945dab1
commit eafa69ee4c
4 changed files with 90 additions and 113 deletions

View File

@ -77,6 +77,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Overhauled the sceptre
- Make the /time command relative to the current day
- Spatial partitioning via a grid for entity versus entity collisions was added which can more than halve the total tick time at higher entity counts (> ~1000)
- The loading screen will now display random animations
### Removed

View File

@ -0,0 +1,37 @@
([
(8.0, [
"voxygen.element.animation.loaders.cauldron1",
"voxygen.element.animation.loaders.cauldron2",
"voxygen.element.animation.loaders.cauldron3",
"voxygen.element.animation.loaders.cauldron4",
"voxygen.element.animation.loaders.cauldron5",
]),
(6.0, [
"voxygen.element.animation.loaders.cheese1",
"voxygen.element.animation.loaders.cheese2",
"voxygen.element.animation.loaders.cheese3",
"voxygen.element.animation.loaders.cheese4",
"voxygen.element.animation.loaders.cheese5",
]),
(6.0, [
"voxygen.element.animation.loaders.coins1",
"voxygen.element.animation.loaders.coins2",
"voxygen.element.animation.loaders.coins3",
"voxygen.element.animation.loaders.coins4",
"voxygen.element.animation.loaders.coins5",
]),
(1.0, [
"voxygen.element.animation.loaders.house1",
"voxygen.element.animation.loaders.house2",
"voxygen.element.animation.loaders.house3",
"voxygen.element.animation.loaders.house4",
"voxygen.element.animation.loaders.house5",
]),
(1.0, [
"voxygen.element.animation.loaders.ship1",
"voxygen.element.animation.loaders.ship2",
"voxygen.element.animation.loaders.ship3",
"voxygen.element.animation.loaders.ship4",
"voxygen.element.animation.loaders.ship5",
]),
])

View File

@ -3,52 +3,65 @@ use crate::{
i18n::Localization,
ui::{
fonts::IcedFonts as Fonts,
ice::{component::neat_button, style, widget::Image, Element},
ice::{component::neat_button, style, widget::Image, Element, IcedUi as Ui, Id},
Graphic,
},
};
use common::assets::{self, AssetExt};
use iced::{button, Align, Column, Container, Length, Row, Space, Text};
use serde::{Deserialize, Serialize};
const LOADER_CAULDRON_SPEED_FACTOR: f64 = 8.0;
const LOADER_CHEESE_SPEED_FACTOR: f64 = 6.0;
const LOADER_COINS_SPEED_FACTOR: f64 = 6.0;
const LOADER_HOUSE_SPEED_FACTOR: f64 = 1.0;
const LOADER_SHIP_SPEED_FACTOR: f64 = 1.0;
enum LoaderAnimation {
Cauldron,
Cheese,
Coins,
House,
Ship,
struct LoadingAnimation {
speed_factor: f32,
frames: Vec<Id>,
}
impl LoaderAnimation {
fn random() -> LoaderAnimation {
match rand::random::<u8>() % 5 {
0 => LoaderAnimation::Cauldron,
1 => LoaderAnimation::Cheese,
2 => LoaderAnimation::Coins,
3 => LoaderAnimation::House,
_ => LoaderAnimation::Ship,
impl LoadingAnimation {
fn new(raw: &(f32, Vec<String>), ui: &mut Ui) -> Self {
let mut frames = vec![];
for frame_path in raw.1.iter() {
frames.push(ui.add_graphic(Graphic::Image(
assets::Image::load(frame_path).unwrap().read().to_image(),
None,
)));
}
Self {
speed_factor: raw.0,
frames,
}
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
struct LoadingAnimationManifest(Vec<(f32, Vec<String>)>);
impl assets::Asset for LoadingAnimationManifest {
type Loader = assets::RonLoader;
const EXTENSION: &'static str = "ron";
}
/// Connecting screen for the main menu
pub struct Screen {
cancel_button: button::State,
add_button: button::State,
tip_number: u16,
loader_animation: LoaderAnimation,
loading_animation: LoadingAnimation,
}
impl Screen {
pub fn new() -> Self {
pub fn new(ui: &mut Ui) -> Self {
let animations =
LoadingAnimationManifest::load("voxygen.element.animation.loaders.manifest")
.unwrap()
.cloned()
.0;
Self {
cancel_button: Default::default(),
add_button: Default::default(),
tip_number: rand::random(),
loader_animation: LoaderAnimation::random(),
loading_animation: LoadingAnimation::new(
&animations[rand::random::<usize>() % animations.len()],
ui,
),
}
}
@ -63,58 +76,9 @@ impl Screen {
show_tip: bool,
) -> Element<Message> {
// TODO: add built in support for animated images
let gear_anim_image = match self.loader_animation {
LoaderAnimation::Cauldron => {
let gear_anim_time = time * LOADER_CAULDRON_SPEED_FACTOR;
match (gear_anim_time % 5.0).trunc() as u8 {
0 => imgs.loader_cauldron1,
1 => imgs.loader_cauldron2,
2 => imgs.loader_cauldron3,
3 => imgs.loader_cauldron4,
_ => imgs.loader_cauldron5,
}
},
LoaderAnimation::Cheese => {
let gear_anim_time = time * LOADER_CHEESE_SPEED_FACTOR;
match (gear_anim_time % 5.0).trunc() as u8 {
0 => imgs.loader_cheese1,
1 => imgs.loader_cheese2,
2 => imgs.loader_cheese3,
3 => imgs.loader_cheese4,
_ => imgs.loader_cheese5,
}
},
LoaderAnimation::Coins => {
let gear_anim_time = time * LOADER_COINS_SPEED_FACTOR;
match (gear_anim_time % 5.0).trunc() as u8 {
0 => imgs.loader_coins1,
1 => imgs.loader_coins2,
2 => imgs.loader_coins3,
3 => imgs.loader_coins4,
_ => imgs.loader_coins5,
}
},
LoaderAnimation::House => {
let gear_anim_time = time * LOADER_HOUSE_SPEED_FACTOR;
match (gear_anim_time % 5.0).trunc() as u8 {
0 => imgs.loader_house1,
1 => imgs.loader_house2,
2 => imgs.loader_house3,
3 => imgs.loader_house4,
_ => imgs.loader_house5,
}
},
LoaderAnimation::Ship => {
let gear_anim_time = time * LOADER_SHIP_SPEED_FACTOR;
match (gear_anim_time % 5.0).trunc() as u8 {
0 => imgs.loader_ship1,
1 => imgs.loader_ship2,
2 => imgs.loader_ship3,
3 => imgs.loader_ship4,
_ => imgs.loader_ship5,
}
},
};
let frame_index = (time * self.loading_animation.speed_factor as f64)
% self.loading_animation.frames.len() as f64;
let frame_id = self.loading_animation.frames[frame_index as usize];
let children = match connection_state {
ConnectionState::InProgress => {
@ -153,7 +117,7 @@ impl Screen {
.padding(5);
let gear = Container::new(
Image::new(gear_anim_image)
Image::new(frame_id)
.width(Length::Units(64))
.height(Length::Units(64)),
)

View File

@ -51,37 +51,6 @@ image_ids_ice! {
selection: "voxygen.element.frames.selection",
selection_hover: "voxygen.element.frames.selection_hover",
selection_press: "voxygen.element.frames.selection_press",
// Loader Animations
loader_cauldron1: "voxygen.element.animation.loaders.cauldron1",
loader_cauldron2: "voxygen.element.animation.loaders.cauldron2",
loader_cauldron3: "voxygen.element.animation.loaders.cauldron3",
loader_cauldron4: "voxygen.element.animation.loaders.cauldron4",
loader_cauldron5: "voxygen.element.animation.loaders.cauldron5",
loader_cheese1: "voxygen.element.animation.loaders.cheese1",
loader_cheese2: "voxygen.element.animation.loaders.cheese2",
loader_cheese3: "voxygen.element.animation.loaders.cheese3",
loader_cheese4: "voxygen.element.animation.loaders.cheese4",
loader_cheese5: "voxygen.element.animation.loaders.cheese5",
loader_coins1: "voxygen.element.animation.loaders.coins1",
loader_coins2: "voxygen.element.animation.loaders.coins2",
loader_coins3: "voxygen.element.animation.loaders.coins3",
loader_coins4: "voxygen.element.animation.loaders.coins4",
loader_coins5: "voxygen.element.animation.loaders.coins5",
loader_house1: "voxygen.element.animation.loaders.house1",
loader_house2: "voxygen.element.animation.loaders.house2",
loader_house3: "voxygen.element.animation.loaders.house3",
loader_house4: "voxygen.element.animation.loaders.house4",
loader_house5: "voxygen.element.animation.loaders.house5",
loader_ship1: "voxygen.element.animation.loaders.ship1",
loader_ship2: "voxygen.element.animation.loaders.ship2",
loader_ship3: "voxygen.element.animation.loaders.ship3",
loader_ship4: "voxygen.element.animation.loaders.ship4",
loader_ship5: "voxygen.element.animation.loaders.ship5",
}
}
@ -343,7 +312,13 @@ impl Controls {
.into()
}
fn update(&mut self, message: Message, events: &mut Vec<Event>, settings: &Settings) {
fn update(
&mut self,
message: Message,
events: &mut Vec<Event>,
settings: &Settings,
ui: &mut Ui,
) {
let servers = &settings.networking.servers;
let mut language_metadatas = crate::i18n::list_localizations();
@ -367,14 +342,14 @@ impl Controls {
#[cfg(feature = "singleplayer")]
Message::Singleplayer => {
self.screen = Screen::Connecting {
screen: connecting::Screen::new(),
screen: connecting::Screen::new(ui),
connection_state: ConnectionState::InProgress,
};
events.push(Event::StartSingleplayer);
},
Message::Multiplayer => {
self.screen = Screen::Connecting {
screen: connecting::Screen::new(),
screen: connecting::Screen::new(ui),
connection_state: ConnectionState::InProgress,
};
@ -601,7 +576,7 @@ impl<'a> MainMenuUi {
messages.into_iter().for_each(|message| {
self.controls
.update(message, &mut events, &global_state.settings)
.update(message, &mut events, &global_state.settings, &mut self.ui)
});
events