#[macro_use] extern crate lazy_static; use fyrox::core::color::Color; use fyrox::graph::SceneGraph; use fyrox::gui::Thickness; use fyrox::{ asset::manager::ResourceManager, core::{ log::Log, pool::Handle, visitor::{Visit, VisitResult, Visitor}, }, engine::GraphicsContext, event::{Event, WindowEvent}, gui::{ brush::Brush, button::ButtonMessage, font::Font, grid::{Column, GridBuilder, Row}, message::{MessageDirection, UiMessage}, text::TextBuilder, widget::WidgetBuilder, widget::WidgetMessage, UiNode, UserInterface, }, keyboard::{KeyCode, PhysicalKey}, plugin::{Plugin, PluginContext}, scene::{graph::Graph, Scene}, }; use std::path::Path; mod enemies; mod map; mod msg; mod player; mod sound; use enemies::archer::{enemy::Archer, spawn::ArcherSpawn}; use enemies::swordsman::{enemy::Swordman, spawn::SwordmanSpawn}; use map::build_map; use msg::ScreenSizeMessage; use player::Player; use sound::Sound; const START_LEVEL: u32 = 1; pub struct GameConstructor; // impl PluginConstructor for GameConstructor { // fn register(&self, context: PluginRegistrationContext) { // // Register your scripts here. // let script_constructors = &context.serialization_context.script_constructors; // script_constructors.add::("Enemy"); // script_constructors.add::("Player"); // script_constructors.add::("Sound"); // } // fn create_instance(&self, scene_path: Option<&str>, context: PluginContext) -> Box { // Box::new(Game::new(scene_path, context)) // } // } #[derive(Visit, Default)] pub struct Game { scene: Handle, new_game: Handle, new_game_with_plot: Handle, next: Handle, new_game_after_plot: Handle, exit: Handle, level_node: Handle, level: u32, need_change_level: bool, need_show_menu: bool, show_menu_time: f32, change_level_time: f32, need_show_end: bool, } impl Game { pub fn default() -> Self { return Game { level: START_LEVEL, ..Default::default() }; } pub fn init_game(&self, ctx: PluginContext) -> Self { ctx.task_pool.spawn_plugin_task( UserInterface::load_from_file("data/menu.ui", ctx.resource_manager.clone()), |result, game: &mut Game, ctx| match result { Ok(menu) => { *ctx.user_interface = menu; (game.new_game, _) = ctx .user_interface .find_by_name_from_root("NewGame") .unwrap(); (game.new_game_with_plot, _) = ctx .user_interface .find_by_name_from_root("NewGameWithPlot") .unwrap(); (game.next, _) = ctx .user_interface .find_by_name_from_root("NextPlotScreen") .unwrap(); (game.new_game_after_plot, _) = ctx .user_interface .find_by_name_from_root("NewGamePlotScreen") .unwrap(); (game.exit, _) = ctx.user_interface.find_by_name_from_root("Exit").unwrap(); } Err(e) => Log::err(format!("Unable to load main menu! Reason: {:?}", e)), // let ui = ctx.user_interface.clone(); // *ui = result.unwrap(); }, ); Self { level_node: Handle::NONE, scene: Handle::NONE, new_game: Handle::NONE, new_game_with_plot: Handle::NONE, new_game_after_plot: Handle::NONE, next: Handle::NONE, exit: Handle::NONE, level: START_LEVEL, need_change_level: false, need_show_menu: false, need_show_end: false, show_menu_time: 0.0, change_level_time: 0.0, } } pub fn next_level(&mut self, change_level_time: f32) { self.need_change_level = true; self.change_level_time = change_level_time; } pub fn show_menu(&mut self, show_menu_time: f32) { self.show_menu_time = show_menu_time; self.need_show_menu = true; } pub fn end_game(&mut self) { self.need_show_end = true; } } impl Plugin for Game { fn register( &self, #[allow(unused_variables)] context: fyrox::plugin::PluginRegistrationContext, ) { let script_constructors = &context.serialization_context.script_constructors; script_constructors.add::("Enemy"); script_constructors.add::("Player"); script_constructors.add::("Sound"); } fn init(&mut self, _scene_path: Option<&str>, context: PluginContext) { self.init_game(context); } fn on_deinit(&mut self, _context: PluginContext) { // Do a cleanup here. } fn update(&mut self, context: &mut PluginContext) { if self.need_change_level && self.change_level_time < context.elapsed_time { self.need_change_level = false; self.level += 1; context.async_scene_loader.request("data/scene.rgs"); } //println!("{} {} ", context.elapsed_time, self.show_menu_time); if self.need_show_menu && self.show_menu_time < context.elapsed_time { self.need_show_menu = false; self.show_menu_time = 0.0; context .user_interface .send_message(WidgetMessage::visibility( context .user_interface .find_handle_by_name_from_root("MenuScreen"), MessageDirection::ToWidget, true, )); } if self.need_show_end { context .user_interface .send_message(WidgetMessage::visibility( context .user_interface .find_handle_by_name_from_root("EndScreen"), MessageDirection::ToWidget, true, )); } } fn on_os_event(&mut self, event: &Event<()>, context: PluginContext) { if let Event::WindowEvent { event, .. } = event { if let WindowEvent::KeyboardInput { event, .. } = event { if let PhysicalKey::Code(keycode) = event.physical_key { if keycode == KeyCode::Escape { context .user_interface .send_message(WidgetMessage::visibility( context .user_interface .find_handle_by_name_from_root("MenuScreen"), MessageDirection::ToWidget, true, )); } } } } if let Event::Resumed {} = event { if let GraphicsContext::Initialized(ref graphics_context) = context.graphics_context { let window_size = graphics_context.window.inner_size(); for script_scene in &context.script_processor.scripted_scenes { script_scene .message_sender .send_global(ScreenSizeMessage::Resize { width: window_size.width, height: window_size.height, }); } } } if let Event::WindowEvent { event, .. } = event { if let WindowEvent::Resized(size) = event { for script_scene in &context.script_processor.scripted_scenes { script_scene .message_sender .send_global(ScreenSizeMessage::Resize { width: size.width, height: size.height, }); } } } } fn on_ui_message(&mut self, ctx: &mut PluginContext, message: &UiMessage) { if let Some(ButtonMessage::Click) = message.data() { if message.destination() == self.new_game || message.destination() == self.new_game_after_plot { ctx.user_interface.send_message(WidgetMessage::visibility( ctx.user_interface .find_handle_by_name_from_root("Start2Screen"), MessageDirection::ToWidget, false, )); ctx.user_interface.send_message(WidgetMessage::visibility( ctx.user_interface .find_handle_by_name_from_root("MenuScreen"), MessageDirection::ToWidget, false, )); ctx.async_scene_loader.request("data/scene.rgs"); } else if message.destination() == self.new_game_with_plot { ctx.user_interface.send_message(WidgetMessage::visibility( ctx.user_interface .find_handle_by_name_from_root("MenuScreen"), MessageDirection::ToWidget, false, )); ctx.user_interface.send_message(WidgetMessage::visibility( ctx.user_interface .find_handle_by_name_from_root("StartScreen"), MessageDirection::ToWidget, true, )); } else if message.destination() == self.next { ctx.user_interface.send_message(WidgetMessage::visibility( ctx.user_interface .find_handle_by_name_from_root("StartScreen"), MessageDirection::ToWidget, false, )); ctx.user_interface.send_message(WidgetMessage::visibility( ctx.user_interface .find_handle_by_name_from_root("Start2Screen"), MessageDirection::ToWidget, true, )); } else if message.destination() == self.exit { if let Some(window_target) = ctx.window_target { window_target.exit(); } } } } fn on_scene_begin_loading(&mut self, _path: &Path, ctx: &mut PluginContext) { if self.scene.is_some() { ctx.scenes.remove(self.scene); } ctx.user_interface.send_message(WidgetMessage::visibility( self.level_node, MessageDirection::ToWidget, false, )); } fn on_scene_loaded( &mut self, _path: &Path, scene: Handle, _data: &[u8], context: &mut PluginContext, ) { context .user_interface .send_message(WidgetMessage::visibility( context .user_interface .find_handle_by_name_from_root("MenuScreen"), MessageDirection::ToWidget, false, )); self.scene = scene; let graph: &mut Graph = &mut context.scenes[self.scene].graph; let resource_manager: &ResourceManager = &context.resource_manager; build_map(graph, resource_manager, self.level); Sound::new(graph); if self.level == 1 { SwordmanSpawn::new().spawn_enemy(graph, resource_manager, -5.0); } if self.level == 2 { ArcherSpawn::new().spawn_enemy(graph, resource_manager, -25.0); } let ui_ctx = &mut context.user_interface.build_ctx(); let font_to_level = resource_manager.request::("data/cd2f1-36d91_sunday.ttf".to_owned()); self.level_node = GridBuilder::new( WidgetBuilder::new() .with_child( TextBuilder::new( WidgetBuilder::new() .with_foreground(Brush::Solid(Color::opaque(192, 34, 9))), ) .with_text(format!("Уровень: {}", self.level)) .with_font_size(20.0) .with_font(font_to_level) .with_shadow_brush(Brush::Solid(Color::RED)) .build(ui_ctx), ) .with_margin(Thickness::top_left(10.0)), ) .add_row(Row::stretch()) .add_column(Column::auto()) .add_column(Column::stretch()) .build(ui_ctx); } }