I am trying to inherit from Transformable and Drawable in SFML to make my objects ... well, transformable and accessible. I make a simple game, but maybe I'm wrong. Here is my code:
#include <SFML/Graphics.hpp> #include <SFML/System.hpp> class Player : public sf::Transformable, public sf::Drawable { public: Player(int x, int y); ~Player() {}; sf::RectangleShape p_rect; void doMovement(const sf::RenderWindow& window); sf::FloatRect getGlobalBounds() const; private: virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const { states.transform *= getTransform(); target.draw(p_rect, states); } }; class Ball : public sf::Transformable, public sf::Drawable { public: Ball(int r, int x, int y); ~Ball() {}; sf::CircleShape b_circle; void doXMovement(); void doYMovement(); bool doXCollisions(const Player& player); bool doYCollisions(const Player& player); sf::FloatRect getGlobalBounds() const; private: virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const { states.transform *= getTransform(); target.draw(b_circle, states); } bool right; bool up; }; Player::Player(int x, int y) { p_rect = sf::RectangleShape(sf::Vector2f(x, y)); } void Player::doMovement(const sf::RenderWindow& window) { setPosition(sf::Mouse::getPosition(window).x, 500); if (getPosition().x < 0) setPosition(0, 500); else if (getPosition().x > 720) setPosition(720, 500); } sf::FloatRect Player::getGlobalBounds() const { return getTransform().transformRect(p_rect.getGlobalBounds()); } Ball::Ball(int r, int x, int y) { b_circle = sf::CircleShape(r); b_circle.setPosition(x, y); right = true; up = false; } void Ball::doXMovement() { if (right) move(1, 0); else move(-1, 0); } void Ball::doYMovement() { if (up) move(0, -1); else move(0, 1); } bool Ball::doXCollisions(const Player& player) { bool coll; if (getGlobalBounds().intersects(player.getGlobalBounds())) { right = !right; coll = true; } else coll = false; if (getPosition().x >= 800 - b_circle.getRadius()) right = false; else if (getPosition().x <= 0) right = true; return coll; } bool Ball::doYCollisions(const Player& player) { bool coll; if (getGlobalBounds().intersects(player.getGlobalBounds())) { up = !up; coll = true; } else coll = false; if (getPosition().x <= 0) up = false; return coll; } sf::FloatRect Ball::getGlobalBounds() const { return getTransform().transformRect(b_circle.getGlobalBounds()); } int main() { sf::RenderWindow window(sf::VideoMode(800, 600), "Breakout"); window.setMouseCursorVisible(false); Player player(80, 10); Ball ball(3, 100, 100); sf::Clock clock; while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); } player.doMovement(window); if (clock.getElapsedTime().asMilliseconds() >= 3) { clock.restart(); if (!ball.doYCollisions(player)) ball.doXCollisions(player); ball.doYMovement(); ball.doXMovement(); } window.clear(sf::Color::Black); window.draw(player); window.draw(ball); window.display(); } return 0; }
Now moving and drawing is (almost) as expected, however the collision is a bit uncomfortable. My conflict problems first:
- Do I need to implement the getGlobalBounds function the way I do? Or is there a better way to do this with things included in Transformable and Drawable?
- Do I have to do the transformations on the shapes directly or do I need to pass the transforms to the draw function, as I am now?
Something strange is also happening with the drawing, which is probably a quick fix. The getPosition method is currently returning invalid values ββfor my ball object. The returned area seems to be shifting down and to the right. Any reason that could be?
Thanks for any help you can give!
EDIT: Any general advice in C ++ is also welcome, I'm still a beginner.
c ++ collision-detection game-physics sfml
mrobinson7627
source share