/**
* 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);
}
}