/** * Triangles * Copyright (C) 2016 POSITIVE MENTAL ATTITUDE * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include "IngameState.hpp" #include "Player.hpp" IngameState::IngameState(): State(), _player(), _paused(false), _blurSize(0.f), _frameAlpha(0.f), _wormhole() {} IngameState::~IngameState() { Echo::debug("Flushing state"); _lightSystem.removeLight(_light); _lightSystem.removeLight(_wormhole.light()); } Rect Player::getBounds() { Rect rect; sf::Vector2f A = _vertices[0].position; sf::Vector2f B = _vertices[1].position; sf::Vector2f C = _vertices[2].position; rect.top = std::min({A.y, B.y, C.y}); rect.bottom = std::max({A.y, B.y, C.y}); rect.left = std::min({A.x, B.x, C.x}); rect.right = std::max({A.x, B.x, C.x}); return rect; } void IngameState::init() { _background.setTexture(_context->assets->loadTexture("data/background/Background.jpg")); _context->assets->loadTexture("data/background/Background.jpg").setRepeated(true); _player.setContext(_context); _player.setTexture(_context->assets->loadTexture(rand() % 10 == 0 ? "data/triangle/Illuminati.png" : "data/triangle/Texture.png")); _player.setPosition(556.f, 2200.f); _foreground.create("data/background/Foreground.jpg", "data/background/Foreground_normal.jpg", "data/background/75pxjitter03.png"); _context->foreground = &_foreground; _spike.create("data/background/Foreground.jpg", "data/background/Foreground_normal.jpg", "data/background/Spikes16px.png"); _spike.setResolution(sf::Vector2u(0, 0)); _spike.move(sf::Vector2f(1020, 2310)); _spike.rotate(332.f); _background.setTextureRect(sf::IntRect(0, 0, _foreground.getSize().x, _foreground.getSize().y)); _pauseFrame.setFillColor(sf::Color(0, 0, 0, 155)); _pauseFrame.setPosition(0, 0); _unshadowShader.loadFromFile("data/light/unshadowShader.frag", sf::Shader::Fragment); _lightOverShapeShader.loadFromFile("data/light/lightOverShapeShader.frag", sf::Shader::Fragment); _normalsShader.loadFromFile("data/light/normalsShader.frag", sf::Shader::Fragment); _penumbraTexture.loadFromFile("data/light/penumbraTexture.png"); _penumbraTexture.setSmooth(true); _light = std::make_shared(); _light->_emissionSprite.setPosition(0.f, 0.f); _light->_emissionSprite.setTexture(_context->assets->loadTexture("data/background/Light.png")); _light->_emissionSprite.setOrigin(sf::Vector2f(_context->assets->loadTexture("data/background/Light.png").getSize() / 2u)); _light->_emissionSprite.setColor(sf::Color::White); _light->_localCastCenter = sf::Vector2f(0.0f, 0.0f); // This is where the shadows emanate from relative to the sprite _blurV.loadFromFile("data/shaders/old_pi_blur/blur.vert", "data/shaders/old_pi_blur/blur-v.frag"); _blurH.loadFromFile("data/shaders/old_pi_blur/blur.vert", "data/shaders/old_pi_blur/blur-h.frag"); _marioSound.setBuffer(_context->assets->loadSound("data/audio/Mario.ogg")); _dotaSound.setBuffer(_context->assets->loadSound("data/audio/Victory.ogg")); _wormhole.load(_context->assets->loadTexture("data/triangle/Wormhole.png"), _context->assets->loadTexture("data/triangle/Wormhole_light.png")); _wormhole.setPosition(400.f, 400.f); _statsTime.setFont(_context->assets->loadFont("data/ttf/canonical/Ubuntu-L.ttf")); _statsHull.setFont(_context->assets->loadFont("data/ttf/canonical/Ubuntu-L.ttf")); _statsTime.setCharacterSize(30); _statsHull.setCharacterSize(30); // Global window is not initialized yet in this method. If you need _context->window->getSize(), go to refresh() instead. _totalTime.restart(); _status = State::Ongoing; } void IngameState::refresh() { sf::Vector2u res = _context->window->getSize(); //_background.setTextureRect(sf::IntRect(0, 0, _context->window->getSize().x, _context->window->getSize().y)); _camera.setSize(static_cast(_context->window->getSize())); _camera.setTwilightViewport(_context->window->getSize().x / 2.f - 240.f/* * (bool) _czyWOgóleTwilightViewportMaByć*/, _context->window->getSize().y / 2.f - 240.f); _camera.setCenter(_player.getPosition()); _foreground.setResolution(res); _pauseFrame.setSize((sf::Vector2f)res); _wasted.setScale(_context->window->getSize().x / 1920.f, _context->window->getSize().y / 1080.f); _wasted.setPosition(_context->window->getSize().x / 2.f, _context->window->getSize().y * 1.5f); _statsTime.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f); _statsHull.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f); _backgroundH.create(_context->window->getSize().x, _context->window->getSize().y); _backgroundV.create(_context->window->getSize().x, _context->window->getSize().y); _lightSystem.create(sf::FloatRect{{0.f, 0.f}, {0.f, 0.f}}, {_context->window->getSize().x, _context->window->getSize().y}, _penumbraTexture, _unshadowShader, _lightOverShapeShader, _normalsShader); _lightSystem.normalsEnabled(true); _lightSystem.addLight(_light); _lightSystem.addLight(_wormhole.light()); } void IngameState::coreThink(const sf::Event& event) { if(event.type == sf::Event::Closed or (event.type == sf::Event::KeyPressed and event.key.code == sf::Keyboard::Escape)) _status = State::Menu; if(event.type == sf::Event::KeyPressed and event.key.code == sf::Keyboard::P and !_player.isDead()) _paused = !_paused; _player.think(event); } void IngameState::coreInput() { if(_paused) return; _player.think(); } void IngameState::coreUpdate(sf::Time delta) { float seconds = delta.asSeconds(); if(_player.isDead()) { if(_blurSize < 4.f) _blurSize += delta.asSeconds(); /** * This will dynamically fade the grey pause foreground from 0 to 100 alpha. */ if(_frameAlpha < 100.f) _frameAlpha += (delta.asSeconds() * 25.f); sf::Color color = _pauseFrame.getFillColor(); color.a = (int)_frameAlpha; _pauseFrame.setFillColor(color); _blurH.setParameter("blurSize", _blurSize / _context->window->getSize().x); _blurV.setParameter("blurSize", _blurSize / _context->window->getSize().y); if((_wasted.getPosition().y > _context->window->getSize().y / 2.f) || (_wasted.getPosition().y < -_context->window->getSize().y / 2.f && _marioSound.getStatus() == sf::Sound::Status::Stopped && !_player.hasWon())) { _wasted.move(0.f, -250.f * delta.asSeconds()); if(_player.hasWon()) { _statsTime.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f); _statsHull.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f); } } } if(_paused) return; if(sf::Joystick::isConnected(0)) _context->window->lockMouse(); const sf::Vector2f pos = _player.getPosition(); _player.update(delta); _camera.move(_player.getPosition() - pos); _light->_emissionSprite.setPosition(_player.getPosition()); _foreground.setPosition(_camera.getCenter() - _camera.getSize() / 2.f); if(_player.checkCollision(_foreground)) /// True if the target died. { _paused = true; _wasted.setTexture(_context->assets->loadTexture("data/background/Wasted.png")); _wasted.setOrigin(sf::Vector2f(_context->assets->loadTexture("data/background/Wasted.png").getSize() / 2u)); _marioSound.play(); } else if(_player.isDead() && _player.hasWon()) { _paused = true; _wasted.setTexture(_context->assets->loadTexture("data/background/Victory.png")); _wasted.setOrigin(sf::Vector2f(_context->assets->loadTexture("data/background/Victory.png").getSize() / 2u)); std::ostringstream oss; int minutesElapsed = int(_totalTime.getElapsedTime().asSeconds()) / 60; int secondsElapsed = int(_totalTime.getElapsedTime().asSeconds()) % 60; oss << "Time: " << minutesElapsed << ":" << (secondsElapsed < 10 ? "0" : "") << secondsElapsed; _statsTime.setString(oss.str()); oss.str(std::string()); oss.clear(); oss << "Hull: " << int(_player.getHullLeft()) << "%"; _statsHull.setString(oss.str()); _statsTime.setOrigin(_statsTime.getLocalBounds().width / 2.f, _statsTime.getLocalBounds().height / 2.f - 30.f); _statsHull.setOrigin(_statsTime.getLocalBounds().width / 2.f, _statsTime.getLocalBounds().height + _statsHull.getLocalBounds().height / 2.f); _dotaSound.play(); } _wormhole.update(delta); float gravity = _wormhole.gravity(_player.getPosition()); if(gravity < 1000.f) { float k = 1000000.f - gravity * gravity; if(k > 0.f) { sf::Vector2f offset = k * seconds * 0.00025f * _wormhole.direction(_player.getPosition()); _camera.move(offset); _player.move(offset); _player.rotate(k * seconds * 0.0001f); } if(gravity < 200.f) _player.setScale(gravity / 200.f, gravity / 200.f); else _player.setScale(1.f, 1.f); } } void IngameState::coreRender(const bool shaders) { if(_player.isDead()) { _backgroundH.draw(_background); _backgroundH.setView(*_camera.getView()); _backgroundH.draw(_foreground); _backgroundH.draw(_wormhole); _backgroundH.draw(_player); sf::Sprite sprite3(_lightSystem.getLightingTexture()); sf::RenderStates lightRenderStates; lightRenderStates.blendMode = sf::BlendMultiply; _backgroundH.setView(_context->window->getDefaultView()); _backgroundH.draw(sprite3, lightRenderStates); sf::Sprite sprite(_backgroundH.getTexture()); sprite.setScale(1.f, -1.f); sprite.setOrigin(0, _context->window->getSize().y); sprite.setPosition(0.f, 0.f); _backgroundV.draw(sprite, &_blurH); sf::Sprite sprite2(_backgroundV.getTexture()); sprite2.setScale(1.f, -1.f); sprite2.setOrigin(0, _context->window->getSize().y); sprite2.setPosition(0.f, 0.f); _context->window->draw(sprite2, &_blurH); _context->window->draw(_pauseFrame); _context->window->draw(_wasted); _context->window->draw(_statsTime); _context->window->draw(_statsHull); } else { _context->window->setView(_camera.getView()); _context->window->draw(_background); _foreground.renderNormals(true); _spike.renderNormals(true); _lightSystem.normalsTargetSetView(*_camera.getView()); _lightSystem.normalsTargetClear(); _lightSystem.normalsTargetDraw(_spike); _lightSystem.normalsTargetDraw(_foreground); _lightSystem.normalsTargetDisplay(); _lightSystem.render(*_camera.getView(), _unshadowShader, _lightOverShapeShader, _normalsShader); _foreground.renderNormals(false); _spike.renderNormals(false); _context->window->draw(_spike); _context->window->draw(_foreground); _context->window->draw(_wormhole); _context->window->draw(_player); _context->window->setView(); sf::Sprite sprite(_lightSystem.getLightingTexture()); sf::RenderStates lightRenderStates; lightRenderStates.blendMode = sf::BlendMultiply; _context->window->draw(sprite, lightRenderStates); if(_paused) _context->window->draw(_pauseFrame); } }