SFML community forums

Help => Graphics => Topic started by: DatCorno on February 17, 2014, 02:58:21 am

Title: Check if draw over something
Post by: DatCorno on February 17, 2014, 02:58:21 am
Ok, ok. The title isn't that clear. So here's my problem : I'm doing a Tower Defense and as we might expect, I don't want to create a Tower over a Tower already there. But problems is, I think the .contains method for sprite doesn't work... Or I'm just a retard (the later might be true.) Here's my code :


Entity.cpp
#include "Entity.hpp"

using namespace Corno;


Entity::Entity(float _x, float _y)
{
        position = Vector2(_x, _y);
        velocity = Vector2();
        acceleration = Vector2();
}

void Entity::LoadSprite(){
        if (!texture.loadFromFile(filename))
                return;

        sprite.setTexture(texture);
        sprite.setPosition(position.x, position.y);
}

void Entity::Move(){
}

void Entity::Draw(sf::RenderWindow &win){
        win.draw(sprite);
}

sf::FloatRect Entity::BoundingBox(){
        return sprite.getLocalBounds();
}

BasicTower.cpp
#include "BasicTower.hpp"

using namespace sf;

BasicTower::BasicTower(float _x, float _y) : Tower(_x, _y)
{
        filename = "Textures/baseTower.png";
        LoadSprite();
}
 

and finally Game.cpp
#include "Game.hpp"


using namespace std;
using namespace sf;

Game::Game(){
        win.create(VideoMode(800, 600), "Tower Defense");
        towers = vector<Tower*>();
}

int Game::Run(){
        while (win.isOpen())
        {
                Update();
                Draw();
        }

        return 0;
}

void Game::Update(){
        Event event;
        while (win.pollEvent(event))
        {
                if (event.type == Event::Closed)
                        win.close();

                if (Mouse::isButtonPressed(Mouse::Left))
                {
                        AddTower();
                }
        }
}

void Game::Draw(){
        win.clear(Color::White);

        for (int i = 0; i < towers.size(); i++)
                towers[i]->Draw(win);

        win.display();
}

void Game::AddTower(){
        Vector2i mouse = Mouse::getPosition(win);
        for (int i = 0; i < towers.size(); i++){
                if (towers[i]->BoundingBox().contains(mouse.x, mouse.y))
                        return;
        }

        towers.push_back(new BasicTower(mouse.x, mouse.y));
}

I think the problem might be in the AddTower() function. By the way, the tower Class does nothing.


thanks :D
Title: Re: Check if draw over something
Post by: Hapax on February 17, 2014, 03:09:10 am
I don't understand your problem/question. Sprites don't have .contains methods. It compares a rectangle with a point. (http://www.sfml-dev.org/tutorials/2.1/graphics-transform.php#bounding-boxes)
Title: Re: Check if draw over something
Post by: DatCorno on February 17, 2014, 03:12:21 am
That's what I meant sorry! The boundingBox method from Entity returns the Rect and I use it to check if the mouse is inside. But it doesn't work and keeps drwaing a tower over an other tower.
Title: Re: Check if draw over something
Post by: Hapax on February 17, 2014, 03:37:20 am
This is certainly not complete and minimal (http://en.sfml-dev.org/forums/index.php?topic=5559.msg36368#msg36368) code :(

You said that the Tower class does nothing. The towers vector is instances of Tower. You check the bounding box of the towers vector. This means that you are checking the bounding box of nothing.
Title: Re: Check if draw over something
Post by: DatCorno on February 17, 2014, 03:43:32 am
By 'do nothing' I mean it has no methods, it's just here for Polymorphism so I can add new Tower type in the towers vector


Edit :
#include "Tower.hpp"

Tower::Tower(float _x, float _y) : Entity(_x, _y){

}

Title: Re: Check if draw over something
Post by: Hapax on February 17, 2014, 04:05:49 am
I'm sorry but looking at just part of your code is just guesswork. You should (preferably) reduce it down by taking out parts that aren't a part of the problem - a bit at a time - and post a smaller, complete version that still has the same problem, or you could attach the entire code and someone might have a look through it.

Also, I'm curious. Why does this have to be a vector of pointers?
towers = vector<Tower*>();
Title: Re: Check if draw over something
Post by: DatCorno on February 17, 2014, 04:09:27 am
So this is the part that causes problems :

void Game::AddTower(){
        Vector2i mouse = Mouse::getPosition(win);
        for (int i = 0; i < towers.size(); i++){
                if (towers[i]->BoundingBox().contains(mouse.x, mouse.y))
                        return;
        }

        towers.push_back(new BasicTower(mouse.x, mouse.y));
}

The rest of the code I posted was so you could understand the 'behind the screens' but fairly, it's the if statement that doesn't hold.

(And I honestly don't quite know... I just thought, if I were to share the vector accross classes and functions I might want pointers... But it's kind of a no-brain act)
Title: Re: Check if draw over something
Post by: Hapax on February 17, 2014, 04:14:57 am
Well, you should debug the value returned from bounding box and the values of mouse. You need to be able to compare the values manually and see why they aren't the values you think they should be. If you can't set breakpoints etc., at least output the information somewhere ;)
Title: Re: Check if draw over something
Post by: DatCorno on February 17, 2014, 04:18:47 am
Problem is... I did debug my stuff, and the number were perfectly fine! contains() should have returned true
Title: Re: Check if draw over something
Post by: AlejandroCoria on February 17, 2014, 04:27:31 am
You have to use:
sprite.getGlobalBounds();

instead of:
sprite.getLocalBounds();
Title: Re: Check if draw over something
Post by: DatCorno on February 17, 2014, 04:28:29 am
I just figured it out when you were posting Alejandro! But thank you both for your help :D
Title: Re: Check if draw over something
Post by: Hapax on February 17, 2014, 04:54:36 am
You have to use:
sprite.getGlobalBounds();

instead of:
sprite.getLocalBounds();
OMG! I can't believe I missed that  :-[
I think it's because I've been staring at lots of getLocalBounds() in my own stuff  >:(

Problem is... I did debug my stuff, and the number were perfectly fine! contains() should have returned true
It can't have returned the correct values since you were using the wrong boundaries. Looks like you need to debug your debugger!