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.

151 lines
3.8 KiB

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