364 lines
13 KiB
Rust
364 lines
13 KiB
Rust
#[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, UiContainer,
|
|
},
|
|
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::<Swordman>("Enemy");
|
|
// script_constructors.add::<Player>("Player");
|
|
// script_constructors.add::<Sound>("Sound");
|
|
// }
|
|
|
|
// fn create_instance(&self, scene_path: Option<&str>, context: PluginContext) -> Box<dyn Plugin> {
|
|
// Box::new(Game::new(scene_path, context))
|
|
// }
|
|
// }
|
|
|
|
#[derive(Visit, Default)]
|
|
pub struct Game {
|
|
scene: Handle<Scene>,
|
|
|
|
new_game: Handle<UiNode>,
|
|
new_game_with_plot: Handle<UiNode>,
|
|
next: Handle<UiNode>,
|
|
new_game_after_plot: Handle<UiNode>,
|
|
exit: Handle<UiNode>,
|
|
level_node: Handle<UiNode>,
|
|
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) => {
|
|
let mut ui_container = UiContainer::new();
|
|
ui_container.add(menu);
|
|
*ctx.user_interfaces = ui_container;
|
|
(game.new_game, _) = ctx
|
|
.user_interfaces.first()
|
|
.find_by_name_from_root("NewGame")
|
|
.unwrap();
|
|
(game.new_game_with_plot, _) = ctx
|
|
.user_interfaces.first()
|
|
.find_by_name_from_root("NewGameWithPlot")
|
|
.unwrap();
|
|
(game.next, _) = ctx
|
|
.user_interfaces.first()
|
|
.find_by_name_from_root("NextPlotScreen")
|
|
.unwrap();
|
|
(game.new_game_after_plot, _) = ctx
|
|
.user_interfaces.first()
|
|
.find_by_name_from_root("NewGamePlotScreen")
|
|
.unwrap();
|
|
(game.exit, _) = ctx.user_interfaces.first().find_by_name_from_root("Exit").unwrap();
|
|
}
|
|
Err(e) => Log::err(format!("Unable to load main menu! Reason: {:?}", e)),
|
|
// let ui = ctx.user_interfaces.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::<Swordman>("Enemy");
|
|
script_constructors.add::<Player>("Player");
|
|
script_constructors.add::<Sound>("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_interfaces.first()
|
|
.send_message(WidgetMessage::visibility(
|
|
context
|
|
.user_interfaces.first()
|
|
.find_handle_by_name_from_root("MenuScreen"),
|
|
MessageDirection::ToWidget,
|
|
true,
|
|
));
|
|
}
|
|
|
|
if self.need_show_end {
|
|
context
|
|
.user_interfaces.first()
|
|
.send_message(WidgetMessage::visibility(
|
|
context
|
|
.user_interfaces.first()
|
|
.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_interfaces.first()
|
|
.send_message(WidgetMessage::visibility(
|
|
context
|
|
.user_interfaces.first()
|
|
.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_interfaces.first().send_message(WidgetMessage::visibility(
|
|
ctx.user_interfaces.first()
|
|
.find_handle_by_name_from_root("Start2Screen"),
|
|
MessageDirection::ToWidget,
|
|
false,
|
|
));
|
|
ctx.user_interfaces.first().send_message(WidgetMessage::visibility(
|
|
ctx.user_interfaces
|
|
.first().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_interfaces.first().send_message(WidgetMessage::visibility(
|
|
ctx.user_interfaces
|
|
.first().find_handle_by_name_from_root("MenuScreen"),
|
|
MessageDirection::ToWidget,
|
|
false,
|
|
));
|
|
ctx.user_interfaces.first().send_message(WidgetMessage::visibility(
|
|
ctx.user_interfaces
|
|
.first().find_handle_by_name_from_root("StartScreen"),
|
|
MessageDirection::ToWidget,
|
|
true,
|
|
));
|
|
} else if message.destination() == self.next {
|
|
ctx.user_interfaces.first().send_message(WidgetMessage::visibility(
|
|
ctx.user_interfaces
|
|
.first().find_handle_by_name_from_root("StartScreen"),
|
|
MessageDirection::ToWidget,
|
|
false,
|
|
));
|
|
ctx.user_interfaces.first().send_message(WidgetMessage::visibility(
|
|
ctx.user_interfaces
|
|
.first().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_interfaces.first().send_message(WidgetMessage::visibility(
|
|
self.level_node,
|
|
MessageDirection::ToWidget,
|
|
false,
|
|
));
|
|
}
|
|
|
|
fn on_scene_loaded(
|
|
&mut self,
|
|
_path: &Path,
|
|
scene: Handle<Scene>,
|
|
_data: &[u8],
|
|
context: &mut PluginContext,
|
|
) {
|
|
context
|
|
.user_interfaces.first()
|
|
.send_message(WidgetMessage::visibility(
|
|
context
|
|
.user_interfaces.first()
|
|
.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_interfaces.first_mut().build_ctx();
|
|
let font_to_level =
|
|
resource_manager.request::<Font>("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);
|
|
}
|
|
}
|