IngameState.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /**
  2. * Triangles
  3. * Copyright (C) 2016 POSITIVE MENTAL ATTITUDE
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, version 3 of the License.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include <cmath>
  18. #include <thread>
  19. #include <sstream>
  20. #include "IngameState.hpp"
  21. #include "Player.hpp"
  22. IngameState::IngameState(): State(), _player(), _paused(false), _blurSize(0.f), _frameAlpha(0.f), _wormhole() {}
  23. IngameState::~IngameState()
  24. {
  25. Echo::debug("Flushing state");
  26. _lightSystem.removeLight(_light);
  27. _lightSystem.removeLight(_wormhole.light());
  28. }
  29. Rect Player::getBounds()
  30. {
  31. Rect rect;
  32. sf::Vector2f A = _vertices[0].position;
  33. sf::Vector2f B = _vertices[1].position;
  34. sf::Vector2f C = _vertices[2].position;
  35. rect.top = std::min({A.y, B.y, C.y});
  36. rect.bottom = std::max({A.y, B.y, C.y});
  37. rect.left = std::min({A.x, B.x, C.x});
  38. rect.right = std::max({A.x, B.x, C.x});
  39. return rect;
  40. }
  41. void IngameState::init()
  42. {
  43. _background.setTexture(_context->assets->loadTexture("data/background/Background.jpg"));
  44. _context->assets->loadTexture("data/background/Background.jpg").setRepeated(true);
  45. _player.setContext(_context);
  46. _player.setTexture(_context->assets->loadTexture(rand() % 10 == 0 ? "data/triangle/Illuminati.png" : "data/triangle/Texture.png"));
  47. _player.setPosition(556.f, 2200.f);
  48. _foreground.create("data/background/Foreground.jpg", "data/background/Foreground_normal.jpg", "data/background/75pxjitter03.png");
  49. _context->foreground = &_foreground;
  50. _spike.create("data/background/Foreground.jpg", "data/background/Foreground_normal.jpg", "data/background/Spikes16px.png");
  51. _spike.setResolution(sf::Vector2u(0, 0));
  52. _spike.move(sf::Vector2f(1020, 2310));
  53. _spike.rotate(332.f);
  54. _background.setTextureRect(sf::IntRect(0, 0, _foreground.getSize().x, _foreground.getSize().y));
  55. _pauseFrame.setFillColor(sf::Color(0, 0, 0, 155));
  56. _pauseFrame.setPosition(0, 0);
  57. _unshadowShader.loadFromFile("data/light/unshadowShader.frag", sf::Shader::Fragment);
  58. _lightOverShapeShader.loadFromFile("data/light/lightOverShapeShader.frag", sf::Shader::Fragment);
  59. _normalsShader.loadFromFile("data/light/normalsShader.frag", sf::Shader::Fragment);
  60. _penumbraTexture.loadFromFile("data/light/penumbraTexture.png");
  61. _penumbraTexture.setSmooth(true);
  62. _light = std::make_shared<ltbl::LightPointEmission>();
  63. _light->_emissionSprite.setPosition(0.f, 0.f);
  64. _light->_emissionSprite.setTexture(_context->assets->loadTexture("data/background/Light.png"));
  65. _light->_emissionSprite.setOrigin(sf::Vector2f(_context->assets->loadTexture("data/background/Light.png").getSize() / 2u));
  66. _light->_emissionSprite.setColor(sf::Color::White);
  67. _light->_localCastCenter = sf::Vector2f(0.0f, 0.0f); // This is where the shadows emanate from relative to the sprite
  68. _blurV.loadFromFile("data/shaders/old_pi_blur/blur.vert", "data/shaders/old_pi_blur/blur-v.frag");
  69. _blurH.loadFromFile("data/shaders/old_pi_blur/blur.vert", "data/shaders/old_pi_blur/blur-h.frag");
  70. _marioSound.setBuffer(_context->assets->loadSound("data/audio/Mario.ogg"));
  71. _dotaSound.setBuffer(_context->assets->loadSound("data/audio/Victory.ogg"));
  72. _wormhole.load(_context->assets->loadTexture("data/triangle/Wormhole.png"), _context->assets->loadTexture("data/triangle/Wormhole_light.png"));
  73. _wormhole.setPosition(400.f, 400.f);
  74. _statsTime.setFont(_context->assets->loadFont("data/ttf/canonical/Ubuntu-L.ttf"));
  75. _statsHull.setFont(_context->assets->loadFont("data/ttf/canonical/Ubuntu-L.ttf"));
  76. _statsTime.setCharacterSize(30);
  77. _statsHull.setCharacterSize(30);
  78. // Global window is not initialized yet in this method. If you need _context->window->getSize(), go to refresh() instead.
  79. _totalTime.restart();
  80. _status = State::Ongoing;
  81. }
  82. void IngameState::refresh()
  83. {
  84. sf::Vector2u res = _context->window->getSize();
  85. //_background.setTextureRect(sf::IntRect(0, 0, _context->window->getSize().x, _context->window->getSize().y));
  86. _camera.setSize(static_cast<sf::Vector2f>(_context->window->getSize()));
  87. _camera.setTwilightViewport(_context->window->getSize().x / 2.f - 240.f/* * (bool) _czyWOgóleTwilightViewportMaByć*/, _context->window->getSize().y / 2.f - 240.f);
  88. _camera.setCenter(_player.getPosition());
  89. _foreground.setResolution(res);
  90. _pauseFrame.setSize((sf::Vector2f)res);
  91. _wasted.setScale(_context->window->getSize().x / 1920.f, _context->window->getSize().y / 1080.f);
  92. _wasted.setPosition(_context->window->getSize().x / 2.f, _context->window->getSize().y * 1.5f);
  93. _statsTime.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f);
  94. _statsHull.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f);
  95. _backgroundH.create(_context->window->getSize().x, _context->window->getSize().y);
  96. _backgroundV.create(_context->window->getSize().x, _context->window->getSize().y);
  97. _lightSystem.create(sf::FloatRect{{0.f, 0.f}, {0.f, 0.f}}, {_context->window->getSize().x, _context->window->getSize().y}, _penumbraTexture, _unshadowShader, _lightOverShapeShader, _normalsShader);
  98. _lightSystem.normalsEnabled(true);
  99. _lightSystem.addLight(_light);
  100. _lightSystem.addLight(_wormhole.light());
  101. }
  102. void IngameState::coreThink(const sf::Event& event)
  103. {
  104. if(event.type == sf::Event::Closed or (event.type == sf::Event::KeyPressed and event.key.code == sf::Keyboard::Escape))
  105. _status = State::Menu;
  106. if(event.type == sf::Event::KeyPressed and event.key.code == sf::Keyboard::P and !_player.isDead())
  107. _paused = !_paused;
  108. _player.think(event);
  109. }
  110. void IngameState::coreInput()
  111. {
  112. if(_paused)
  113. return;
  114. _player.think();
  115. }
  116. void IngameState::coreUpdate(sf::Time delta)
  117. {
  118. float seconds = delta.asSeconds();
  119. if(_player.isDead())
  120. {
  121. if(_blurSize < 4.f)
  122. _blurSize += delta.asSeconds();
  123. /**
  124. * This will dynamically fade the grey pause foreground from 0 to 100 alpha.
  125. */
  126. if(_frameAlpha < 100.f)
  127. _frameAlpha += (delta.asSeconds() * 25.f);
  128. sf::Color color = _pauseFrame.getFillColor();
  129. color.a = (int)_frameAlpha;
  130. _pauseFrame.setFillColor(color);
  131. _blurH.setParameter("blurSize", _blurSize / _context->window->getSize().x);
  132. _blurV.setParameter("blurSize", _blurSize / _context->window->getSize().y);
  133. if((_wasted.getPosition().y > _context->window->getSize().y / 2.f)
  134. || (_wasted.getPosition().y < -_context->window->getSize().y / 2.f
  135. && _marioSound.getStatus() == sf::Sound::Status::Stopped && !_player.hasWon()))
  136. {
  137. _wasted.move(0.f, -250.f * delta.asSeconds());
  138. if(_player.hasWon())
  139. {
  140. _statsTime.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f);
  141. _statsHull.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f);
  142. }
  143. }
  144. }
  145. if(_paused)
  146. return;
  147. if(sf::Joystick::isConnected(0))
  148. _context->window->lockMouse();
  149. const sf::Vector2f pos = _player.getPosition();
  150. _player.update(delta);
  151. _camera.move(_player.getPosition() - pos);
  152. _light->_emissionSprite.setPosition(_player.getPosition());
  153. _foreground.setPosition(_camera.getCenter() - _camera.getSize() / 2.f);
  154. if(_player.checkCollision(_foreground)) /// True if the target died.
  155. {
  156. _paused = true;
  157. _wasted.setTexture(_context->assets->loadTexture("data/background/Wasted.png"));
  158. _wasted.setOrigin(sf::Vector2f(_context->assets->loadTexture("data/background/Wasted.png").getSize() / 2u));
  159. _marioSound.play();
  160. }
  161. else if(_player.isDead() && _player.hasWon())
  162. {
  163. _paused = true;
  164. _wasted.setTexture(_context->assets->loadTexture("data/background/Victory.png"));
  165. _wasted.setOrigin(sf::Vector2f(_context->assets->loadTexture("data/background/Victory.png").getSize() / 2u));
  166. std::ostringstream oss;
  167. int minutesElapsed = int(_totalTime.getElapsedTime().asSeconds()) / 60;
  168. int secondsElapsed = int(_totalTime.getElapsedTime().asSeconds()) % 60;
  169. oss << "Time: " << minutesElapsed << ":" << (secondsElapsed < 10 ? "0" : "") << secondsElapsed;
  170. _statsTime.setString(oss.str());
  171. oss.str(std::string());
  172. oss.clear();
  173. oss << "Hull: " << int(_player.getHullLeft()) << "%";
  174. _statsHull.setString(oss.str());
  175. _statsTime.setOrigin(_statsTime.getLocalBounds().width / 2.f, _statsTime.getLocalBounds().height / 2.f - 30.f);
  176. _statsHull.setOrigin(_statsTime.getLocalBounds().width / 2.f, _statsTime.getLocalBounds().height + _statsHull.getLocalBounds().height / 2.f);
  177. _dotaSound.play();
  178. }
  179. _wormhole.update(delta);
  180. float gravity = _wormhole.gravity(_player.getPosition());
  181. if(gravity < 1000.f)
  182. {
  183. float k = 1000000.f - gravity * gravity;
  184. if(k > 0.f)
  185. {
  186. sf::Vector2f offset = k * seconds * 0.00025f * _wormhole.direction(_player.getPosition());
  187. _camera.move(offset);
  188. _player.move(offset);
  189. _player.rotate(k * seconds * 0.0001f);
  190. }
  191. if(gravity < 200.f)
  192. _player.setScale(gravity / 200.f, gravity / 200.f);
  193. else
  194. _player.setScale(1.f, 1.f);
  195. }
  196. }
  197. void IngameState::coreRender(const bool shaders)
  198. {
  199. if(_player.isDead())
  200. {
  201. _backgroundH.draw(_background);
  202. _backgroundH.setView(*_camera.getView());
  203. _backgroundH.draw(_foreground);
  204. _backgroundH.draw(_wormhole);
  205. _backgroundH.draw(_player);
  206. sf::Sprite sprite3(_lightSystem.getLightingTexture());
  207. sf::RenderStates lightRenderStates;
  208. lightRenderStates.blendMode = sf::BlendMultiply;
  209. _backgroundH.setView(_context->window->getDefaultView());
  210. _backgroundH.draw(sprite3, lightRenderStates);
  211. sf::Sprite sprite(_backgroundH.getTexture());
  212. sprite.setScale(1.f, -1.f);
  213. sprite.setOrigin(0, _context->window->getSize().y);
  214. sprite.setPosition(0.f, 0.f);
  215. _backgroundV.draw(sprite, &_blurH);
  216. sf::Sprite sprite2(_backgroundV.getTexture());
  217. sprite2.setScale(1.f, -1.f);
  218. sprite2.setOrigin(0, _context->window->getSize().y);
  219. sprite2.setPosition(0.f, 0.f);
  220. _context->window->draw(sprite2, &_blurH);
  221. _context->window->draw(_pauseFrame);
  222. _context->window->draw(_wasted);
  223. _context->window->draw(_statsTime);
  224. _context->window->draw(_statsHull);
  225. }
  226. else
  227. {
  228. _context->window->setView(_camera.getView());
  229. _context->window->draw(_background);
  230. _foreground.renderNormals(true);
  231. _spike.renderNormals(true);
  232. _lightSystem.normalsTargetSetView(*_camera.getView());
  233. _lightSystem.normalsTargetClear();
  234. _lightSystem.normalsTargetDraw(_spike);
  235. _lightSystem.normalsTargetDraw(_foreground);
  236. _lightSystem.normalsTargetDisplay();
  237. _lightSystem.render(*_camera.getView(), _unshadowShader, _lightOverShapeShader, _normalsShader);
  238. _foreground.renderNormals(false);
  239. _spike.renderNormals(false);
  240. _context->window->draw(_spike);
  241. _context->window->draw(_foreground);
  242. _context->window->draw(_wormhole);
  243. _context->window->draw(_player);
  244. _context->window->setView();
  245. sf::Sprite sprite(_lightSystem.getLightingTexture());
  246. sf::RenderStates lightRenderStates;
  247. lightRenderStates.blendMode = sf::BlendMultiply;
  248. _context->window->draw(sprite, lightRenderStates);
  249. if(_paused)
  250. _context->window->draw(_pauseFrame);
  251. }
  252. }