very early prototype of a spaceshooter in SFML
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.

main.cpp 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #include <cmath>
  2. #include <iostream>
  3. #include <string>
  4. #include <SFML/Graphics.hpp>
  5. #include <SFML/System.hpp>
  6. #include <SFML/Window.hpp>
  7. #include "main.hpp"
  8. #include "background.hpp"
  9. #include "game.hpp"
  10. #include "mainmenu.hpp"
  11. namespace Proto4 {
  12. // because we want to create the objects in init(), we use the default
  13. // constructor, so nothing can go wrong here
  14. sf::RenderWindow window{};
  15. AppState state = AppState::MainMenu;
  16. MainMenu menu{};
  17. Game game{};
  18. Background background{};
  19. sf::Texture bg0, bg1;
  20. sf::Font font;
  21. static bool isFullscreen = false;
  22. bool openWindow(bool fullscreen) {
  23. // set antialising for shapes
  24. // this doesn't affect textures (requires sf::Texture::setSmooth())
  25. sf::ContextSettings settings;
  26. settings.antialiasingLevel = 4;
  27. if (fullscreen) {
  28. //go fullscreen
  29. sf::VideoMode fsMode = sf::VideoMode::getFullscreenModes()[0];
  30. window.create(fsMode, gameTitle, sf::Style::Fullscreen, settings);
  31. isFullscreen = true;
  32. } else {
  33. window.create(sf::VideoMode(xResolution, yResolution, colorDepth),
  34. gameTitle, sf::Style::Default, settings);
  35. window.setPosition(sf::Vector2i(0, 0));
  36. isFullscreen = false;
  37. }
  38. window.setMouseCursorVisible(false);
  39. if (!window.isOpen()) {
  40. std::cout << "Unable to open window object. Aborting execution.";
  41. return false;
  42. }
  43. return true;
  44. }
  45. bool init() {
  46. if (!font.loadFromFile("Audiowide-Regular.ttf")) {
  47. std::cout << "Unable to load font. Aborting execution.";
  48. return false;
  49. }
  50. if (!bg0.loadFromFile("img/bg_grid_48.png") ||
  51. !bg1.loadFromFile("img/bg_grid_72.png")) {
  52. std::cout
  53. << "Unable to load background images. Aborting execution.";
  54. return false;
  55. }
  56. background.init(bg0, bg1, game.getMainView());
  57. if (!menu.init(font) || !game.init()) {
  58. return false;
  59. }
  60. // set antialising for shapes
  61. // this doesnt affect textures (requires sf::Texture::setSmooth())
  62. sf::ContextSettings settings;
  63. settings.antialiasingLevel = 4;
  64. // open window after everything has loaded to avoid
  65. // 'window not responding' warning
  66. if (!openWindow(isFullscreen)) return false;
  67. return true;
  68. }
  69. void update(sf::Time timestep, sf::Time currentTime) {
  70. // poll for events and pass them to components
  71. sf::Event event;
  72. while (window.pollEvent(event)) {
  73. switch (event.type) {
  74. case sf::Event::LostFocus:
  75. game.pause();
  76. break;
  77. case sf::Event::GainedFocus:
  78. game.resume();
  79. break;
  80. case sf::Event::Resized:
  81. background.resize(event);
  82. menu.resize(event);
  83. game.resize(event);
  84. break;
  85. case sf::Event::KeyPressed:
  86. // toggle fullscreen
  87. if (
  88. event.key.code == sf::Keyboard::F11 ||
  89. (event.key.code == sf::Keyboard::Return && event.key.alt)
  90. ) openWindow(!isFullscreen);
  91. switch (state) {
  92. case AppState::MainMenu:
  93. state = menu.handleKey(event);
  94. break;
  95. case AppState::Game:
  96. state = game.handleKey(event);
  97. break;
  98. default:
  99. break;
  100. }
  101. break;
  102. default:
  103. break;
  104. }
  105. }
  106. // Update everything that gets updated without events...
  107. sf::View &gameView = game.getMainView();
  108. switch (state) {
  109. case AppState::MainMenu:
  110. // move camera for background movement
  111. gameView.setCenter(sf::Vector2f(
  112. gameView.getCenter().x + timestep.asSeconds() * 100 * std::sin(currentTime.asSeconds()),
  113. gameView.getCenter().y + timestep.asSeconds() * 100));
  114. break;
  115. case AppState::Game:
  116. state = game.update(window, timestep);
  117. break;
  118. case AppState::Exit:
  119. window.close();
  120. break;
  121. default:
  122. break;
  123. }
  124. background.update(gameView, window);
  125. }
  126. void draw() {
  127. window.clear(sf::Color::Black);
  128. window.draw(background);
  129. switch (state) {
  130. case AppState::Game:
  131. window.draw(game);
  132. break;
  133. case AppState::MainMenu:
  134. window.draw(menu);
  135. break;
  136. case AppState::Exit:
  137. break;
  138. }
  139. window.display();
  140. }
  141. void mainloop() {
  142. // draw as often as possible and
  143. // update multiple times with a fixed timestep as needed
  144. sf::Clock clock;
  145. sf::Time previousTime = sf::milliseconds(0);
  146. sf::Time lagTime = sf::milliseconds(0);
  147. while (window.isOpen()) {
  148. sf::Time currentTime = clock.getElapsedTime();
  149. sf::Time elapsedTime = currentTime - previousTime;
  150. previousTime = currentTime;
  151. lagTime += elapsedTime;
  152. while (lagTime >= updateTimestep) {
  153. update(updateTimestep, clock.getElapsedTime());
  154. lagTime -= updateTimestep;
  155. }
  156. draw();
  157. }
  158. }
  159. }
  160. int main() {
  161. if (!Proto4::init())
  162. return 1;
  163. Proto4::mainloop();
  164. return 0;
  165. }