/**
* 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 "Foreground.hpp"
#include
#include
Foreground::~Foreground()
{
for(unsigned i = 0; i < _sprites.size(); ++i)
_sprites[i].clear();
_sprites.clear();
_tiles.clear();
_normalSprites.clear();
_normalTiles.clear();
}
const sf::Vector2u Foreground::getSize() const
{
return {_tileCount.x * _tileSize, _tileCount.y * _tileSize};
}
unsigned const Foreground::tileAlpha(unsigned x, unsigned y, unsigned pixelX, unsigned pixelY)
{
return _tiles[y * _tileCount.x + x].first.getPixel(pixelX, pixelY).a;
}
void Foreground::reloadFromTile(int x, int y, bool neighbouring)
{
if(x < 0 or y < 0 or x >= (int)_tileCount.x or y >= (int)_tileCount.y)
return;
if(neighbouring)
{
for(int i = -1; i <= 1; ++i)
{
if(x + i < 0 or x + i >= (int)_tileCount.x)
continue;
for(int j = -1; j <= 1; ++j)
{
if(y + j < 0 or y + j >= (int)_tileCount.y)
continue;
unsigned id = (y + j) * _tileCount.x + (x + i);
_tiles[id].second.loadFromImage(_tiles[id].first);
_normalTiles[id].second.loadFromImage(_normalTiles[id].first);
}
}
}
else
{
unsigned id = y * _tileCount.x + x;
_tiles[id].second.loadFromImage(_tiles[id].first);
_normalTiles[id].second.loadFromImage(_normalTiles[id].first);
}
}
void Foreground::reloadFromPixel(int x, int y, bool neighbouring)
{
reloadFromTile((x / _tileSize), (y / _tileSize), neighbouring);
}
bool Foreground::destroy(unsigned x, unsigned y)
{
if((x / _tileSize) < 0 or (y / _tileSize) < 0 or (x / _tileSize) >= _tileCount.x or (y / _tileSize) >= _tileCount.y)
return true;
unsigned id = ((y / _tileSize) * _tileCount.x) + (x / _tileSize);
x %= _tileSize;
y %= _tileSize;
int a = _tiles[id].first.getPixel(x, y).a;
if(a > 0)
{
_tiles[id].first.setPixel(x, y, sf::Color::Transparent);
_normalTiles[id].first.setPixel(x, y, sf::Color::Transparent);
return true;
}
else
return false;
}
const unsigned Foreground::getTileSize() const
{
return _tileSize;
}
void Foreground::create(sf::Image& foreground, sf::Image& normal, sf::Image& map)
{
_tileSize = 256;
_position.x = 0; _position.y = 0;
_tileCount.x = std::ceil(static_cast(map.getSize().x) / _tileSize);
_tileCount.y = std::ceil(static_cast(map.getSize().y) / _tileSize);
_tiles.clear();
_tiles.resize(_tileCount.x * _tileCount.y);
_sprites.resize(_tileCount.x);
_normalTiles.clear();
_normalTiles.resize(_tileCount.x * _tileCount.y);
_normalSprites.resize(_tileCount.x);
for(unsigned i = 0; i < _tileCount.x; ++i)
{
_sprites[i].resize(_tileCount.y);
_normalSprites[i].resize(_tileCount.y);
}
for(unsigned i = 0; i < _tiles.size(); ++i)
{
// std::get instead of .first and .second because it used to be a tuple
// and I did not rewrite this.
std::get<0>(_tiles[i]).create(_tileSize, _tileSize, sf::Color::Yellow);
std::get<0>(_normalTiles[i]).create(_tileSize, _tileSize, sf::Color::Yellow);
}
for(unsigned i = 0; i < _tileCount.x * _tileSize; ++i)
for(unsigned j = 0; j < _tileCount.y * _tileSize; ++j)
{
sf::Color color = foreground.getPixel(i % foreground.getSize().x, j % foreground.getSize().y);
std::get<0>(_tiles[j / _tileSize * _tileCount.x + i / _tileSize])
.setPixel(i % _tileSize, j % _tileSize, sf::Color(color.r, color.g, color.b, i < map.getSize().x and j < map.getSize().y ? 255 - map.getPixel(i, j).r : 255));
color = normal.getPixel(i % normal.getSize().x, j % normal.getSize().y);
std::get<0>(_normalTiles[j / _tileSize * _tileCount.x + i / _tileSize])
.setPixel(i % _tileSize, j % _tileSize, sf::Color(color.r, color.g, color.b, i < map.getSize().x and j < map.getSize().y ? 255 - map.getPixel(i, j).r : 255));
}
for(unsigned i = 0; i < _tiles.size(); ++i)
{
std::get<1>(_tiles[i]).loadFromImage(std::get<0>(_tiles[i]));
_sprites[i % _tileCount.x][i / _tileCount.x].setTexture(std::get<1>(_tiles[i]));
_sprites[i % _tileCount.x][i / _tileCount.x].setPosition((i % _tileCount.x) * _tileSize, (i / _tileCount.x) * _tileSize);
std::get<1>(_normalTiles[i]).loadFromImage(std::get<0>(_normalTiles[i]));
_normalSprites[i % _tileCount.x][i / _tileCount.x].setTexture(std::get<1>(_normalTiles[i]));
_normalSprites[i % _tileCount.x][i / _tileCount.x].setPosition((i % _tileCount.x) * _tileSize, (i / _tileCount.x) * _tileSize);
}
}
void Foreground::create(std::string foreground, std::string normal, std::string map)
{
sf::Image image1, image2, image3;
image1.loadFromFile(foreground);
image2.loadFromFile(normal);
image3.loadFromFile(map);
create(image1, image2, image3);
}
void Foreground::setResolution(sf::Vector2u resolution)
{
sf::Vector2f temp;
temp.x = static_cast(resolution.x) / static_cast(_tileSize);
temp.y = static_cast(resolution.y) / static_cast(_tileSize);
_renderCount = sf::Vector2u(std::ceil(temp.x) + 1, std::ceil(temp.y) + 1);
}
void Foreground::setPosition(sf::Vector2f position)
{
_position.x = position.x >= 0 ? position.x : 0;
_position.y = position.y >= 0 ? position.y : 0;
}
void Foreground::renderNormals(bool render)
{
_renderNormals = render;
}
void Foreground::move(sf::Vector2f movement)
{
for(unsigned i = 0; i < _renderCount.x; ++i)
for(unsigned j = 0; j < _renderCount.y; ++j)
_sprites[i][j].move(movement);
}
void Foreground::rotate(float rotation)
{
for(unsigned i = 0; i < _renderCount.x; ++i)
for(unsigned j = 0; j < _renderCount.y; ++j)
_sprites[i][j].rotate(rotation);
}
void Foreground::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
unsigned x = _position.x / _tileSize, y = _position.y / _tileSize;
for(unsigned i = 0; i < _renderCount.x; ++i)
for(unsigned j = 0; j < _renderCount.y; ++j)
if(i + x < _tileCount.x and j + y < _tileCount.y)
{
if(!_renderNormals)
target.draw(_sprites[i + x][j + y], states);
else
target.draw(_normalSprites[i + x][j + y], states);
}
}