Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - 20lbpizza

Pages: [1]
1
Ah sorry! Looks like I also missed the interaction with RenderTarget::getViewport() ...
Maybe I should close this topic since the x/y size of the render target needs to be combined with the view's viewport settings.

Because of that both options, static member function or as public member of sf::View don't make sense!

2
In the current implementation of mapPixelToCoords it requires a RenderTarget to call.
I have a function handleEvent(sf::event e) which will have information about the relevant view for the object that calls it but not the RenderTarget so I can't call mapPixelToCoords even though I'd like to check for a specific position within a vertex array.

Based on the current implementation it doesn't appear that any member of RenderTarget is needed to perform the calculation:
FloatRect viewport --> Defined from view parameter
normalized --> Defined from parameter point & parameter view
Calculation calls member functions of the view.

Based on this would it make sense to allow for views to directly call this helper function without a RenderTarget object either as a member of view or static call to RenderTarget? If not the context would probably benefit my personal thought process  :).

Vector2f RenderTarget::mapPixelToCoords(const Vector2i& point, const View& view) const
{
    // First, convert from viewport coordinates to homogeneous coordinates
    Vector2f normalized;
    FloatRect viewport = FloatRect(getViewport(view));
    normalized.x = -1.f + 2.f * (static_cast<float>(point.x) - viewport.left) / viewport.width;
    normalized.y =  1.f - 2.f * (static_cast<float>(point.y) - viewport.top)  / viewport.height;

    // Then transform by the inverse of the view matrix
    return view.getInverseTransform().transformPoint(normalized);
}

3
System / Re: Nested transforms for sf::sprite and mouse event collision
« on: August 30, 2021, 04:42:57 am »
I eventually figured this out after a few days away from this part of the project.

In the original problem we didn't apply the transform like we did by with draw:
mSprite.getGlobalBounds().contains(x,y); // only works if we change the sprites position directly
// defeats the point of using a wrapper class
 


It would be somewhat awkward to pass "sf::RenderStates" as a extra parameter to a simple contains() function so we didn't want to necessarily copy how draw works but keep the same premise. First make a bounding box with the sprites global bounds like we originally expected. Then simply apply the transform of the wrapper class to the bounding box and check for this modified box.

bool Button::contains(int x, int y)
{
    sf::FloatRect boundingBox = mSprite.getGlobalBounds();
    boundingBox = getTransform().transformRect(boundingBox);
    return boundingBox.contains(x,y);
}
 

The end result is I can now use the default setPosition function from sf::Transform on this Button class and it accurately handles collision and drawing without direct manipulation of the sprite the Button contains.

To my understanding the tutorial doesn't really help for this particular situation so it may be useful to add?

4
System / Nested transforms for sf::sprite and mouse event collision
« on: August 23, 2021, 09:17:13 pm »
Context: In following the "SFML game development book" (Moreira, Hansson, Haller)  chapter 4 and 6 cover input handling and game menu's respectively. The menu's in the example code are all keyboard based while I'd like to apply mouse based input for a project I am currently working on. A button class is used to pair a sf::Sprite and sf::Text and ultimately inherits from sf::transformable so you only need to make one call of setPosition on the wrapper class in order to move/align both the text and button sprite.

Problem: I am unsure on the proper way of checking collision with the mouse for the buttons. My current work around based on previous forum post is as follow:

In MenuState.cpp - replace the calls of setPosition of the wrapper class with a function that directly passes the coordinates to the sprite and text object.
        // A subset of the constructor of the MenuState
        auto playButton = std::make_shared<GUI::Button>(context);
        float offsetX = playButton->getSize().width / 2 ;
        playButton->setPos(winX/2 - offsetX, winY/3); // Replace a call of setPosition here ***
        playButton->setText("Play");
        playButton->setCallback([this] ()
        {
                requestStackPop();
                requestStackPush(States::Game);
        });
 

In Button.cpp a method is added to directly apply the position to the sprite and text.
// Add a function to pass the position to the underlying objects (sprite and text) instead of the button itself
void Button::setPos(float x, float y)
{
    this->mSprite.setPosition(x,y);
    this->mText.setPosition(x + this->getSize().width /2 ,y + this->getSize().height /2);
}
 

The reason this work around was applied was because in a method which handles the Mouse event, I could not check collision with the sprite since the Button class was moved but the globalPosition of the sprite and text was still set to 0,0 (moving mouse to top left corner would select last piece of menu). For the draw menu the transforms are passed down so this is not an issue when drawing. The final menu has a container for the buttons that are iterated over and the position of the sprite it checked using .contains against the mouse event coordinates.

Final question: What would be the best way to pass a wrapper objects transform to an underlying sprite to check if the sprite (or wrapper object) contain the position of the mouse click?

Hope this question is not too verbose or vague this is my first post and welcome to feedback.

Pages: [1]
anything