I'm back again.
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?