Hi Folks,
I am trying to setup a hexGrid type game and I am currently playing with different ways to do it.
Right now I got a simple class which has a sf::CircleShape that has 6 points to make it a Hexagon. I also have a vector of the sf::CircleShape for the grid.
Now I got the grid drawing fine and I am now trying to detect the hex that the mouse is in. I've written a simple method that is called each time the mouse is moved. It basically checks the globalBounds of each sf::Circleshape to see if the mouse position is contained within that circleShape. If yes then it changes the fillColour of the sf::Circleshape.
Now this is working ok, except when the mouse is hovering near the edge of some grids, then both get highlighted white, i.e. the mouse is within both circleshapes.
Is this because there is a bounding box around the sf::CircleShape which is larger that the displayed shape? Is there a way to resolve this?
I have put down a full working example that should be able to be compile and run on it's own.
hexGrid.h
#ifndef HEXGRID_HPP
#define HEXGRID_HPP
#include <iostream>
#include <vector>
#include <SFML/Graphics.hpp>
using namespace std;
class hexgrid : public sf::Drawable
{
public:
hexgrid(sf::RenderWindow& window);
~hexgrid();
void draw(sf::RenderTarget& target, sf::RenderStates states) const;
bool chkHexGridWithMousePos(sf::Vector2f passed_mousePos);
bool isMouseContainsHexagaon(sf::CircleShape *hexPtr, sf::Vector2f passed_mousePos);
enum hexStyle
{
translucent,
colorful,
green,
cyan
};
private:
sf::CircleShape hexagon;
std::vector<sf::CircleShape> hexaGrid;
};
#endif // HEXGRID_HPP
hexGrid.cpp
#include "hexgrid.h"
hexgrid::hexgrid(sf::RenderWindow& window)
{
//set up background elements
hexagon.setRadius(window.getSize().x / 16.f);
hexagon.setPointCount(6);
hexagon.setFillColor(sf::Color(150, 50, 250));
hexagon.setOutlineThickness(2);
hexagon.setOutlineColor(sf::Color(250, 150, 100));
hexagon.setOrigin(hexagon.getGlobalBounds().width / 2.f, hexagon.getGlobalBounds().height / 2.f);
std::vector<sf::ConvexShape>::iterator hexit;
float xpos = 0, ypos = 0;
for (int y = 0; y < 12; y++)
{
if (y == 0)
{
ypos = y * hexagon.getGlobalBounds().height;
}
else
{
ypos = ypos + (hexagon.getGlobalBounds().height - (hexagon.getGlobalBounds().height * 0.25f));
}
for (int x = 0; x < 12; x++)
{
if (y % 2 == 0)
{
xpos = x * hexagon.getGlobalBounds().width;
}
else
{
xpos = (x * hexagon.getGlobalBounds().width) + (hexagon.getGlobalBounds().width * 0.5f);
}
hexagon.setPosition(xpos, ypos);
hexaGrid.push_back(hexagon);
}
}
}
hexgrid::~hexgrid()
{
}
void hexgrid::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
std::vector<sf::CircleShape>::const_iterator hexit;
for (hexit = hexaGrid.begin(); hexit != hexaGrid.end(); ++hexit)
{
target.draw(*hexit, states);
}
}
bool hexgrid::chkHexGridWithMousePos(sf::Vector2f passed_mousePos)
{
bool returnVal = false;
for (int i = 0; i < hexaGrid.size(); i++)
{
if (isMouseContainsHexagaon(&hexaGrid[i], passed_mousePos))
{
returnVal = true;
}
}
return returnVal;
}
bool hexgrid::isMouseContainsHexagaon(sf::CircleShape *hexPtr, sf::Vector2f passed_mousePos)
{
if (hexPtr->getGlobalBounds().contains(passed_mousePos))
{
hexPtr->setFillColor(sf::Color(255, 255, 255));
return true;
}
else
{
hexPtr->setFillColor(sf::Color(150, 50, 250));
return false;
}
}
main
#include <iostream>
#include <SFML/Graphics.hpp>
#include "hexgrid.h"
int main()
{
sf::ContextSettings settings;
settings.antialiasingLevel = 8;
sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Hexgrid Example", sf::Style::Default, settings);
hexgrid grid(window);
sf::Event e;
bool running = true;
while (running)
{
while (window.pollEvent(e))
{
if (e.type == sf::Event::Closed)
{
window.close();
return 0;
}
if (e.type == sf::Event::MouseMoved)
{
grid.chkHexGridWithMousePos(sf::Vector2f(e.mouseMove.x, e.mouseMove.y));
}
}
window.clear();
window.draw(grid);
window.display();
}
return 0;
}