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 - Composer3

Pages: [1] 2
1
Graphics / Re: Collision Detection between circle and triangle?
« on: March 01, 2020, 02:49:50 am »
Never mind, I figured it out. One problem was that I was using getOrigin instead of getPosition. Also, after I changed that I was still getting false positives because it would still sometimes cross one of the lines when just the corners of the bounding rectangles intersected. I fixed that by making sure it only crossed the right line segment when the spaceship was on the left of the circle, and vice-versa. Also, I did have to use the point-radius collision for the top point of the triangle because of this. Here's my changed code for anyone who's interested:

#include "Spaceship.h"
#include <iostream>

Spaceship::Spaceship() {
        _texture.loadFromFile("images\\spaceship.png");
        _texture.setSmooth(true);
        setTexture(_texture);

        setPosition(720 / 2 + getGlobalBounds().width / 2, 680 - getGlobalBounds().height);
}

bool Spaceship::pointRadius(sf::CircleShape &circle, float x1, float y1) {
        float x2 = circle.getPosition().x;
        float y2 = circle.getPosition().y;

        float distance = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

        return distance < circle.getRadius();
}

float Spaceship::getDistanceToCircleOrigin(sf::CircleShape &circle, float x1, float y1, float x2, float y2) {
        float distance = abs((y2 - y1) * (circle.getPosition().x) - (x2 - x1) * (circle.getPosition().y) + x2 * y1 - y2 * x1) / sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
        return distance;
}

bool Spaceship::intersectsCircle(sf::CircleShape &circle) {
        if (getGlobalBounds().intersects(circle.getGlobalBounds())) {

                if (pointRadius(circle, getPosition().x + getGlobalBounds().width / 2, getPosition().y)) {
                        return true;
                }

                float distance = getDistanceToCircleOrigin(
                        circle,
                        getPosition().x + getGlobalBounds().width / 2,
                        getPosition().y,
                        getPosition().x + getGlobalBounds().width,
                        getPosition().y + getGlobalBounds().height
                );

                float distance2 = getDistanceToCircleOrigin(
                        circle, getPosition().x + getGlobalBounds().width / 2,
                        getPosition().y,
                        getPosition().x,
                        getPosition().y + getGlobalBounds().height);

                float radius = circle.getRadius();
                if (distance <= radius && distance2 > radius && getPosition().x < circle.getPosition().x - circle.getGlobalBounds().width / 2) {

                        return true;
                }

                if (distance2 <= radius && distance > radius && getPosition().x + getGlobalBounds().width > circle.getPosition().x + circle.getGlobalBounds().width / 2) {

                        return true;
                }
        }
        return false;
}

 

2
Graphics / Re: Collision Detection between circle and triangle?
« on: March 01, 2020, 12:09:29 am »
I'm back again.  :D

I have implemented the AABB and line segments intersection methods. Obviously, the AABB collision is working, but the line segments method is giving me trouble. Here's my code:

Spaceship.h (the spaceship is the triangle):
#include <SFML\Graphics.hpp>
#include <vector>

class Spaceship : public sf::Sprite {
  public:
    Spaceship();
    float getDistanceToCircleOrigin(sf::CircleShape &circle, float x1, float y1, float x2, float y2);
    bool intersectsCircle(sf::CircleShape &circle);

    int speedX = 0;
    int speedY = 0;
  private:
    sf::Texture _texture;
};
 

Spaceship.cpp:

#include "Spaceship.h"

Spaceship::Spaceship() {
        _texture.loadFromFile("images\\spaceship.png");
        _texture.setSmooth(true);
        setTexture(_texture);

        setPosition(720 / 2 + getGlobalBounds().width / 2,
                                680 - getGlobalBounds().height);
}

float Spaceship::getDistanceToCircleOrigin(sf::CircleShape &circle, float x1, float y1, float x2, float y2) {
        float distance = abs((y2 - y1) * circle.getOrigin().x - (x2 - x1) * circle.getOrigin().y + x2 * y1 - y2 * x1) / sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
        return distance;
}

bool Spaceship::intersectsCircle(sf::CircleShape &circle) {
        if (getGlobalBounds().intersects(circle.getGlobalBounds())) {

                float distance = getDistanceToCircleOrigin(
                        circle, getOrigin().x + getGlobalBounds().width / 2, getOrigin().y,
                        getOrigin().x + getGlobalBounds().width,
                        getOrigin().y + getGlobalBounds().height);

                if (distance <= circle.getRadius())
                        return true;
        }
        return false;
}

 

Asteroid.h (the asteroid is the circle):

#include <SFML\Graphics.hpp>

class Asteroid : public sf::Sprite {
  public:
    Asteroid();
        sf::CircleShape circle;

        void move(float x, float y);

  private:
    sf::Texture _texture;
};

 

Asteroid.cpp:

#include "Asteroid.h"
#include <iostream>

Asteroid::Asteroid() {
        _texture.loadFromFile("C:\\Users\\_____\\OneDrive\\Documents\\C++\\SFML_Asteroids\\images\\asteroid2.png");
        setTexture(_texture);
        setOrigin(getGlobalBounds().width / 2, getGlobalBounds().height / 2);
        setPosition(720 / 2, 680 / 2);
        circle.setRadius(150 / 2);
        circle.setOrigin(circle.getRadius(), circle.getRadius());
        circle.setPosition(720 / 2, 680 / 2);
}

void Asteroid::move(float x, float y) {
        circle.move(x, y);
        sf::Sprite::move(x, y);
}
 

main.cpp:
#include "main.h"

using namespace std;

void initialize() {
        window.create(sf::VideoMode(WIDTH, HEIGHT, 32), "Asteroids");
        window.setKeyRepeatEnabled(false);
}

void input(sf::Event &event) {
        while (window.pollEvent(event)) {
                switch (event.type) {

                        case sf::Event::Closed: {
                                window.close();
                                break;
                        }

                        default:
                                break;
                }
        }

        upPressed = sf::Keyboard::isKeyPressed(sf::Keyboard::Up);
        downPressed = sf::Keyboard::isKeyPressed(sf::Keyboard::Down);
        leftPressed = sf::Keyboard::isKeyPressed(sf::Keyboard::Left);
        rightPressed = sf::Keyboard::isKeyPressed(sf::Keyboard::Right);

        bounds = spaceship.getGlobalBounds();

        if (upPressed && bounds.top > 0) {
                spaceship.move(0, -5);
        }

        if (downPressed && bounds.top + bounds.height < HEIGHT) {
                spaceship.move(0, 5);
        }

        if (leftPressed && bounds.left > 0) {
                spaceship.move(-5, 0);
        }

        if (rightPressed && bounds.left + bounds.width < WIDTH) {
                spaceship.move(5, 0);
        }
}

void update() {
        asteroid.move(0, 1);
}

bool checkForCollisions() {
        return spaceship.intersectsCircle(asteroid.circle);
}

void render() {
        window.clear();

        sf::RectangleShape srect(sf::Vector2f(spaceship.getGlobalBounds().width, spaceship.getGlobalBounds().height));
        srect.setPosition(spaceship.getPosition());
        window.draw(srect);
        window.draw(spaceship);
        window.draw(asteroid.circle);
        window.draw(asteroid);

        window.display();
}

int main() {
        initialize();

        sf::Event event;
        while (window.isOpen()) {
                input(event);
                update();
                if (checkForCollisions())
                        cout << "intersects!" << endl;
                render();

                sf::sleep(sf::milliseconds(10));
        }

        return 0;
}

 

Note: I have a white rectangle behind the spaceship and have filled in the asteroid's circle with white so I can visualize the collisions.

The problem is, the line segment method doesn't seem to be working at all. I get the same results if I comment out the if (distance <= circle.getRadius()). Any ideas?

3
Graphics / Re: Inherit from sf::Shape (sf::CircleShape)
« on: February 13, 2020, 07:35:57 pm »
Thanks.

Sorry, I know almost nothing about GitHub. I have an account but the only thing I use it for is creating/replying to issues :). How exactly do I create a PR? If it's too complicated to explain on this issue, could you point me to a tutorial on a different site?

4
Graphics / Re: Inherit from sf::Shape (sf::CircleShape)
« on: February 12, 2020, 09:42:45 pm »
Also, I believe beyond a shadow of a doubt that it was not my fault that I was confused by the tutorial. However, I do admit that it may have been my fault that reading the docs did not correct my confusion, or at least point me in the right direction.

5
Graphics / Re: Inherit from sf::Shape (sf::CircleShape)
« on: February 12, 2020, 09:29:19 pm »
Quote
I thought it was the other way around: if I wanted to apply a 400*400 texture to a 300*300 sprite, then I would need a texture rect of 300*300
There's no way you can understand this from that:

Quote from: the API documentation
Set the sub-rectangle of the texture that the shape will display.

The texture rect is useful when you don't want to display the whole texture, but rather a part of it. By default, the texture rect covers the entire texture.

I didn't understand that from the docs, I understood that from the tutorial. The docs didn't help any, because I was just kinda skimming over them, but they were not the source of the confusion.

But anyway, I don't really like to argue like this. You spotted a lack in the tutorials, and it's true that we could easily improve it to avoid such a confusion. If you want to submit a PR for this (only the english part of course, we take care of the french translation), you're more than welcome :)

How do I do this?

6
Graphics / Re: Inherit from sf::Shape (sf::CircleShape)
« on: February 12, 2020, 09:03:16 pm »
Btw, I didn't fully understand what it was supposed to do until G.'s post. I thought it was the other way around: if I wanted to apply a 400*400 texture to a 300*300 sprite, then I would need a texture rect of 300*300. In other words, what the docs didn't explain was whether the intRect was in local or global coordinates and if local, then of the texture or of the sprite.

7
Graphics / Re: Inherit from sf::Shape (sf::CircleShape)
« on: February 12, 2020, 08:56:28 pm »
Even the documentation does not explain what each parameter does in the function. It is missing a vital piece of information - it says what it does, and why you might want to do it, but it does not tell you how to do it. How am I to understand how to correctly use a function if even the docs don't explain it? There are no examples, and the tutorial, which is the only place I've seen an actual call to the function, doesn't explain what the parameters are doing.

8
Graphics / Re: Inherit from sf::Shape (sf::CircleShape)
« on: February 12, 2020, 07:24:48 pm »
Just checked the docs again, and you're right, it does say "The texture rect is useful when you don't want to display the whole texture, but rather a part of it. By default, the texture rect covers the entire texture."

I first found out about setTextureRect in the shapes tutorial. Pasted from the section about texturing shapes:
"Shapes can also be textured, just like sprites. To specify a part of the texture to be mapped to the shape, you must use the setTextureRect function. It takes the texture rectangle to map to the bounding rectangle of the shape. This method doesn't offer maximum flexibility, but it is much easier to use than individually setting the texture coordinates of each point of the shape."

This is what had me confused: nowhere in the tutorial did it say that the default is to cover the entire section. Nor does it use a code example that does not use setTextureRect. I suppose if I had read it again I may have noticed that the language does sort of imply that setTextureRect is only necessary if you want to display a portion, but only if I had reason to believe so already. From what it said, I thought that setTextureRect was a mandatory function used to position the texture on the sf::Shape. I am sure that I am not the only one who was confused by this from the tutorial.

9
Graphics / Re: Inherit from sf::Shape (sf::CircleShape)
« on: February 11, 2020, 11:36:44 pm »
Ok, so setTextureRect is unnecessary? This would have saved a lot of headache for me if this had been mentioned in the docs.

10
Graphics / Re: Collision Detection between circle and triangle?
« on: February 11, 2020, 11:34:57 pm »
Ok, I may use AABB collision too, but not all three (AABB, point-radius, and line segments), as you said before, because point-radius collision, while fairly simple and easy to understand, does not come out of the box with sfml, and therefore would need more code than I would consider worth the performance boost.

11
Graphics / Re: Inherit from sf::Shape (sf::CircleShape)
« on: February 11, 2020, 03:03:48 am »
Thank you for the information.

That's most likely because you're incorrectly calling setTextureRect -- you shouldn't.

How else am I supposed to set the rect for a textured sf::Shape? I understand that I shouldn't use one in this case, and I won't, but I may need to in the future.

It's almost always a bad idea to inherit drawable entities, unless you really want to extend them. Because you don't want your Asteroid class to expose low-level functions such as setTexture etc., these details are configured internally by your class and should not be accessible outside.

I think I may do it anyway, if only just this once. I am doing this project purely as a way to learn C++ and SFML better - kind of my own learning by doing project. I will try to avoid public inheritance with SFML in the future.

12
Graphics / Re: Collision Detection between circle and triangle?
« on: February 11, 2020, 02:56:09 am »
Thank you for your reply.

test AABB collision (if not colliding, no need for more tests)

What is AABB collision?

One thing to note, though, is you could do the collision test in stages:

I don't think this would be necessary in my case. This would require much more code, and I don't think it would slow my program down enough to be a problem for my program.

13
Graphics / Re: Inherit from sf::Shape (sf::CircleShape)
« on: February 07, 2020, 04:30:03 pm »
Thank you. I will use a sprite instead.

And avoid public inheritance: your asteroid is not a circle shape, it just uses one to draw itself on screen.

So are you saying I sould always avoid public inheritance in SFML? Or would it be ok to inherit from a sprite?

14
Graphics / Re: Inherit from sf::Shape (sf::CircleShape)
« on: February 06, 2020, 10:39:10 pm »
Because the asteroid is a circle, I thought it would be easier to implement circle-based collisions if I used the circleshape, which has methods like getRaidus(). And I would still like to know what's causing the weird rendering.

15
Graphics / Re: Collision Detection between circle and triangle?
« on: February 06, 2020, 07:20:19 pm »
Thank you for your reply.

How are you representing the triangle if you don't know all three points? The first thing you need to do to check collision with a triangle is know where its points are...

Checking line segments crossing would be the slower way but either way should be fast enough for normal usage.

I am sorry, I misunderstood your suggestion. I thought you meant every point on the perimiter of the triangle, not the triangle's three points.

The method you are mentioning would work most of the time. However, if the circle was intersecting with one of the triangle's line segments, but not a point, this method would not work. My method checks to see if the line segments intersect the circle. This will always work.

But my question still remains: Do I use getGlobalBounds or getLocalBounds, or does it even matter for width and height?

Pages: [1] 2