You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
3.6 KiB

  1. use log::{error, info};
  2. use space_crush_app::{App, Error};
  3. use space_crush_common::{
  4. misc::{init_logger, Vfs},
  5. Dispatcher,
  6. };
  7. use specs::{World, WorldExt};
  8. fn main() -> Result<(), Error> {
  9. let vfs = Vfs::new(&["space-crush-app"])?;
  10. init_logger(&vfs, "log4rs.yml");
  11. vfs.log_info();
  12. info!("Application started");
  13. if let Err(err) = run(vfs) {
  14. error!("Error while executing application: {}", err);
  15. return Err(err);
  16. }
  17. info!("Application exited");
  18. Ok(())
  19. }
  20. fn run(vfs: Vfs) -> Result<(), Error> {
  21. let mut world = World::new();
  22. world.insert(vfs);
  23. let mut common = Dispatcher::new(&mut world);
  24. let mut app = App::new(&mut world)?;
  25. if !load_world(&mut world, WORLD_FILEPATH)? {
  26. create_world(&mut world);
  27. }
  28. while app.is_running() {
  29. world.maintain();
  30. common.process(&world);
  31. app.process(&world)?;
  32. }
  33. save_world(&mut world, WORLD_FILEPATH)?;
  34. Ok(())
  35. }
  36. fn create_world(world: &mut World) {
  37. use glc::vector::{Vector2f, Vector4f};
  38. use space_crush_app::{components::PlayerVisual, misc::PersistWorld};
  39. use space_crush_common::{
  40. components::{Owned, Planet, Player, Position, Ship, ShipType, Velocity},
  41. misc::Persistence,
  42. };
  43. use specs::{saveload::MarkedBuilder, Builder};
  44. let player1 = world
  45. .create_entity()
  46. .with(Player {})
  47. .with(PlayerVisual {
  48. color: Vector4f::new(0.0, 0.5, 1.0, 0.1),
  49. })
  50. .build();
  51. world
  52. .create_entity()
  53. .marked::<<PersistWorld as Persistence>::Marker>()
  54. .with(Owned { owner: player1 })
  55. .with(Position {
  56. pos: Vector2f::default(),
  57. size: 500.0,
  58. })
  59. .with(Planet {})
  60. .build();
  61. for i in 0..3 {
  62. let x = if i & 1 == 0 { 1.0 } else { -1.0 };
  63. let y = if i & 2 == 0 { 1.0 } else { -1.0 };
  64. world
  65. .create_entity()
  66. .marked::<<PersistWorld as Persistence>::Marker>()
  67. .with(Owned { owner: player1 })
  68. .with(Position {
  69. pos: Vector2f::new(250.0 * x, 250.0 * y),
  70. size: 30.0,
  71. })
  72. .with(Velocity {
  73. dir: Vector2f::new(i as f32 - 1.0, 1.0).normalize(),
  74. speed: 0.0,
  75. })
  76. .with(Ship {
  77. type_: match i {
  78. 0 => ShipType::Fighter,
  79. 1 => ShipType::Bomber,
  80. 2 => ShipType::Transporter,
  81. _ => unreachable!(),
  82. },
  83. })
  84. .build();
  85. }
  86. }
  87. fn load_world(world: &mut World, path: &str) -> Result<bool, Error> {
  88. use serde_json::de::{Deserializer, IoRead};
  89. use space_crush_app::misc::PersistWorld;
  90. use space_crush_common::misc::{Persistence, WorldHelper};
  91. PersistWorld::setup(world);
  92. let vfs = world.resource::<Vfs>()?;
  93. let path = vfs.join(path)?;
  94. if !path.exists() {
  95. return Ok(false);
  96. }
  97. let mut file = path.open_file()?;
  98. let mut read = IoRead::new(&mut file);
  99. let mut deserializer = Deserializer::new(&mut read);
  100. world.deserialize(PersistWorld, &mut deserializer)?;
  101. Ok(true)
  102. }
  103. fn save_world(world: &mut World, path: &str) -> Result<(), Error> {
  104. use serde_json::Serializer;
  105. use space_crush_app::misc::PersistWorld;
  106. use space_crush_common::misc::WorldHelper;
  107. let vfs = world.resource::<Vfs>()?;
  108. let mut file = vfs.join(path)?.create_file()?;
  109. let mut serializer = Serializer::new(&mut file);
  110. world.serialize(PersistWorld, &mut serializer)?;
  111. Ok(())
  112. }
  113. const WORLD_FILEPATH: &str = "resources/world.json";