#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
#include <stdio.h> /* NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#define APP_WIDTH 512
#define APP_HEIGHT 320
int random(int min, int max);
sf::Vector2f randomPosition(sf::Vector2f& tileSize);
sf::Vector2f randomPosition(float tileWidth, float tileHeight);
template <typename T>
void addBlock(std::vector<T>& vector, sf::Vector2f& tileSize);
int main()
{
sf::RenderWindow window(sf::VideoMode(APP_WIDTH, APP_HEIGHT), "Proto", sf::Style::Close);
/* initialize random seed: */
srand(time(NULL));
sf::Vector2f tileSize(16, 16);
std::vector<sf::RectangleShape> blocks;
std::vector<sf::RectangleShape>::pointer selected = NULL;
sf::Vector2i mouse = sf::Mouse::getPosition(window);
bool isMousePressed = false;
sf::Vector2f oldPosition;
addBlock(blocks, tileSize);
addBlock(blocks, tileSize);
addBlock(blocks, tileSize);
addBlock(blocks, tileSize);
addBlock(blocks, tileSize);
addBlock(blocks, tileSize);
addBlock(blocks, tileSize);
addBlock(blocks, tileSize);
addBlock(blocks, tileSize);
addBlock(blocks, tileSize);
addBlock(blocks, tileSize);
addBlock(blocks, tileSize);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::MouseButtonPressed:
mouse = sf::Mouse::getPosition(window);
// Check to see which block has been clicked
for (std::vector<sf::RectangleShape>::iterator itr = blocks.begin(), end = blocks.end(); itr < end; ++itr)
{
if (mouse.x > itr->getPosition().x &&
mouse.y > itr->getPosition().y &&
mouse.x < itr->getPosition().x + itr->getGlobalBounds().width &&
mouse.y < itr->getPosition().y + itr->getGlobalBounds().height)
{
isMousePressed = true;
selected = &(*itr);
selected->setOutlineThickness(-2);
// Save old position
oldPosition = selected->getPosition();
/* Swap selected block with last position in vector
* so that it get's renderd last and overlaps all
* other blocks
*/
std::iter_swap(blocks.begin() + blocks.size() - 1, selected);
}
}
break;
case sf::Event::MouseButtonReleased:
{
isMousePressed = false;
if (selected != NULL)
{
sf::Vector2f newPosition;
newPosition.x = std::floor((selected->getPosition().x + tileSize.x / 2) / tileSize.x) * tileSize.x;
newPosition.y = std::floor((selected->getPosition().y + tileSize.y / 2) / tileSize.y) * tileSize.y;
selected->setOutlineThickness(-1);
// Is block on top of another block?
bool occupied = false;
for (std::vector<sf::RectangleShape>::iterator itr = blocks.begin(), end = blocks.end(); itr < end; ++itr)
{
if (newPosition == itr->getPosition())
{
occupied = true;
break;
}
}
if (!occupied)
selected->setPosition(newPosition);
else
selected->setPosition(oldPosition);
}
selected = NULL;
break;
}
default:
break;
};
}
if (isMousePressed)
{
mouse = sf::Mouse::getPosition(window);
selected->setPosition(mouse.x - tileSize.x / 2, mouse.y - tileSize.y / 2);
}
window.clear();
for (std::vector<sf::RectangleShape>::iterator itr = blocks.begin(), end = blocks.end(); itr < end; ++itr)
{
window.draw(*itr);
}
window.display();
}
return 0;
}
int random(int min, int max)
{
int random = min + (rand() % max - min);
return random;
}
sf::Vector2f randomPosition(sf::Vector2f& tileSize)
{
int randX = random(0, APP_WIDTH);
int randY = random(0, APP_HEIGHT);
randX = std::floor(randX / tileSize.x);
randY = std::floor(randY / tileSize.y);
return sf::Vector2f(randX * tileSize.x, randY * tileSize.y);
}
sf::Vector2f randomPosition(float tileWidth, float tileHeight)
{
int randX = random(0, 512);
int randY = random(0, 320);
randX = std::floor(randX / tileWidth);
randY = std::floor(randY / tileHeight);
return sf::Vector2f(randX * tileWidth, randY * tileHeight);
}
template <typename T>
void addBlock(std::vector<T>& vector, sf::Vector2f& tileSize)
{
sf::RectangleShape block;
block.setSize(tileSize);
block.setFillColor(sf::Color::Red);
block.setOutlineColor(sf::Color::White);
block.setOutlineThickness(-1);
block.setPosition(randomPosition(tileSize));
vector.push_back(block);
}